Much like last fall’s version of the Twitterpocalypse saw people running to Mastodon (and, seemingly, quickly running back to Twitter) as a replacement social media platform, this summer’s edition has seen a shift to Bluesky social. As I try to keep my various sites relevant, that means learning how to have them interact programmatically with yet another social network’s API.
The documentation for the AT protocol is relatively dense but, thankfully, Felicitas Pojtinger has a freaking awesome cURL interaction cheatsheet to get started. And Bluesky uses its own API so if you want to know how something works, even if it’s not particularly documented, you can inspect your own network traffic as you do it and go from there.
From that, I built a PHP helper class for interacting with Bluesky that looks a lot like all those previously-mentioned helper classes. You can authenticate using a user’s handle and app password, which will get you their DID and API key, or you can skip straight to supplying the DID and API key.
Then, if you want to send a post (I refuse to call them Skeets), it looks something like this:
That one specifically defines its language as English but the language parameter is seemingly not required.
The format for the args can get complicated quickly. For example: Replies. Unlike Twitter, where you only need to specify the ID of the Tweet you’re replying to, Bluesky sends more information about the entire thread. Which seems unnecessary because they should be able to get this information from the ID of the post you’re replying to but what do I know? Maybe, like language, some of this isn’t actually required but the Bluesky app sends it and I haven’t experimented enough to see what’s actually necessary.
I’ve obfuscated a little bit in the above, and because I was lazy about it, the parent (post we’re replying to) and root (first post in the thread) are identical. Sometimes that’s going to happen, though, like when you’re replying to a post with no replies or the first post in a thread.
Or maybe you want to post with an image, which requires uploading the image (which I’ve assumed is a PNG in this example) as a blob and then referencing it in the post:
I’ve barely scratched the surface with this but the point, for me, wasn’t do to a deep dive or anything, it was just to do the helper class that enables further interactions.