Mise à jour du plugin pour oText

J'ai mis à jour mon plugin oText me permettant de pleinement POSSE (*Publish (on your) Own Site, Syndicate Elsewhere*). Le support Mastodon est amélioré avec l'ajout des quatre premières images ainsi que des hashtags. Plus intéressant encore, le support de Bluesky, encore en beta sur invitation, est terminé. Quelques notes sur le support de Bluesky :

1. Contrairement à Mastodon où l'on peut poster avec un token d'application, ici posséder un mot de passe d'application n'est que la première étape. Il faudra, avec ce mot de passe, récupérer un jeton valable un certain temps (je n'ai pas été en mesure de déterminer cette durée, mais il ne semble pas nécessaire de le renouveler lors d'un traitement rapide comme l'envoi d'un post avec des images). Concrètement, en PHP cela donne ça :

lang-php
// Get API key with app password
$apiTarget = rtrim($head['pds'], '/') . '/xrpc/com.atproto.server.createSession';
$apiHeaders = [
	'Content-Type: application/json'
];
$apiPayload = '{ "identifier": "' . $head['repo'] . '", "password": "' . $head['password'] . '" }';
$apiKey = _post($apiTarget, $apiHeaders, $apiPayload);

$headers = [
	'Authorization: Bearer ' . $apiKey["accessJwt"],
	'Content-Type: application/json',
	'Accept: application/json',
	'Accept-Charset: utf-8'
];

2. Sur le protocole AT sous-jacent, tout est un `record` inscrit dans une `collection` d'un `repository`. Le `repository`, c'est l'utilisateur (au format `did:plc:xxxx`), la `collection` la catégorie du record (`app.bsky.feed.post` pour un post, mais on peut imaginer d'autres applications comme des recettes de cuisine qui appartiendraient à `app.bsky.cookbook.recipe` par exemple). S'abonner à quelqu'un est un `record` sur la collection `app.bsky.graph.follow`, faire un like est un `record` sur la collection `app.bsky.feed.like`, etc. Supprimer ces `records`, c'est à l'inverse supprimer des posts, des follows, des likes…

3. Il y a une grande différenciation opérée entre le serveur (appelé PDS) et le client. Contrairement à la quasi totalité des réseaux sociaux, il ne suffit pas d'envoyer du texte au serveur pour que les mentions, les liens, les citations et les *website cards* soient convertis : il faut le faire côté client au moment de poster, et ajouter le tout à la requête qui s'occupera de poster. Le nombre de requêtes nécessaires pour construire la requête finale peut donc vite grimper (notamment pour les mentions). Les liens et mentions sont des `facets` où il s'agira d'explicitement dire au serveur : de tel caractère à tel caractère, c'est un lien dont voici l'URL, de tel autre à tel autre, c'est une mention dont voici l'utilisateur. Images, vidéos, citations et *website cards* sont des `embeds` qui demanderont chacun un traitement particulier, sachant que l'on ne peut avoir plus d'un type d'`embed` par post. Je vois déjà pas mal d'inconvénients côté client, et côté serveur ça semble faciliter le travail d'algorithmes de monétisation et de tracking (beaucoup plus simple de savoir combien de personnes ont posté le lien d'une adresse donnée). Comme ça recrée des liens HTML de façon agnostique, on pourra voir apparaître les mêmes problèmes de phishing : truc.gouv.fr s'affiche partout comme un lien vers une administration reconnue, mais renvoie en réalité vers un site bidon.

4. Contrairement à Twitter ou Mastodon, la suppression d'un post se fait non pas par une requête `DELETE` mais par une requête `POST`…

5. Pour les images, j'ai vu des exemples utiliser `fopen()`, mais ça produit des images tronquées. Il faut utiliser `file_get_contents()`.

6. Il y a un endpoint `xprc/com.atproto.repo.putRecord` qui semble être là pour modifier un `record`, donc possiblement un post. Je n'ai pas essayé.

7. Dans l'ensemble, une implémentation du protocole AT pour poster demande plus de boulot. Pas seulement au niveau du client, mais également au niveau du nombre de requêtes (demande d'une clé API, demande des DID, upload des miniatures des cards, etc.).

8. Je n'ai vu nulle part de paramètre de « visibilité » permettant de créer des profils privés. Même sans code d'invitation, il est à l'heure actuelle possible de lire le contenu d'un post (je le fais d'une requête GET pour les liens que je poste). Ne pensez donc pas que vous êtes protégé⋅e⋅s derrière un rideau opaque.

9. Notez que Bluesky et le protocole AT sous-jacent n'en sont qu'à leurs balbutiements. Y a vraiment rien. Un simple script PHP de la moitié d'1 Mo fait déjà plus. Mastodon et ActivityPub en 2017 faisaient déjà plus. Nul doute qu'il faudra réécrire un tas de code au fur et à mesure. Je vois gros comme une maison que les hashtags vont demander encore un traitement différent, là où c'est juste l'affaire d'ajouter # dans un pouet/tweet, et ce n'est qu'un exemple.

10. La grosse séparation serveur/client/application (un même serveur gardant en mémoire des `records` qui peuvent être de tout type) peut être intéressant. J'ai juste peur qu'il y ait une disparité des clients à ce niveau (« Découvrez l'application payante qui vous donne accès aux recettes de cuisine ! Vidéos en option. »).

Voilà. La documentation est encore peu fournie, il a fallu y aller au *trial and error* à de nombreux endroits, malgré un billet de blog plus dense et un exemple en bash. Je n'ai pas trouvé de quoi avancer dans les quelques librairies PHP qui existent à l'heure actuelle, elles sont dans leur immense majorité limitée à l'envoi d'un post texte ou d'une image, bottant en touche toute la complexité qu'il y avait. Comme toujours, mon code est hébergé ici et sur Codeberg, donc n'hésitez pas à y jeter un œil.

----

Permaliens :