Im Februar hatte ich mir mal einen BlueSky-Account angelegt und bis neulich gab es immerhin ganze drei Posts. Aber wenn ich schon Mastodon mit meinen Blogposts zuschütte, könnte ich das auch mit dem Bluesky-Account machen.
Ich habe es mir einfach gemacht und benutze dieses BlueSky SDK und das Einbinden war auch denkbar einfach. Allerdings habe ich mich gewundert, warum meine Tags in den Posts über die API nicht verlinkt werden. Tags sind ebensowenig unkomfortabel zu handhaben wie Links. Auch für Tags müssen Facets zur Richtextaufbereitung benutzt werden.
Ein Post für den Text #tags @ € £ #multibyte #test sieht dann in etwa so aus:
{
"text": "#tags @ € £ #multibyte #test",
"facets": [
{
"index": {
"byteStart": 0,
"byteEnd": 5
},
"features": [
{
"$type": "app.bsky.richtext.facet#tag",
"tag": "tags"
}
]
},
{
"index": {
"byteStart": 15,
"byteEnd": 25
},
"features": [
{
"$type": "app.bsky.richtext.facet#tag",
"tag": "multibyte"
}
]
},
{
"index": {
"byteStart": 26,
"byteEnd": 31
},
"features": [
{
"$type": "app.bsky.richtext.facet#tag",
"tag": "test"
}
]
}
]
}
In der Tat ist es notwendig, Tags vor dem Posten eigenhändig zu suchen und deren Position zu bestimmen. Ich habe den Atproto\Builders\Bluesky\RecordBuilder aus dem og. SDK erweitert und darin die Methode addText() erweitert:
class RecordBuilderWithTags extends RecordBuilder
{
public function addText($text): self
{
parent::addText($text);
$tags = $this->extractTags($text);
if (empty($tags)) {
return $this;
}
if (!isset($this->record->facets)) {
$this->record->facets = [];
}
foreach ($tags as $tag) {
$offset = 0;
while (($pos = strpos($text, $tag, $offset)) !== false) {
$offset = $pos + 1;
$this->record->facets[] = [
'index' => [
'byteStart' => $pos,
'byteEnd' => strlen($tag) + $pos,
],
'features' => [
[
'$type' => 'app.bsky.richtext.facet#tag',
'tag' => substr($tag, 1), // without '#'
]
]
];
}
}
return $this;
}
protected function extractTags(string $text): array
{
$pattern = '/#[A-Z0-9]+/i';
preg_match_all($pattern, $text, $matches);
$tags = $matches[0];
return array_unique($tags);
}
}
Es ist erforderlich, nicht die Multibyte-Funktionen mb_strpos() und mb_strlen() zu benutzen, da die API in den Werten byteStart und byteEnd wirklich die Position von Bytes und nicht von Zeichen erwartet.
Eine kleine Anmerkung, bevor jemand auf die schräge Idee kommt, das zu benutzen: Kombination von Tags wie #Proton und #ProtonAuthenticator führe zu Problemen, da strpos() mit #Proton auch die Position von #ProtonAuthenticator findet.
Ja, ich kann verstehen, dass man damit ein Höchstmaß an Flexibilität bei der Ausgestaltung der schlappen 300 Zeichen hat. Aber es ist auch absurd unkomfortabel.