Skip to content

Trying the Bluesky API

Posted on:

Recently, I ventured into the process of migrating my Twitter/Mastodon bot, ScoreMyWordle (https://github.com/shaneafsar/wordlescorer/), to Bluesky. This post will illuminate some of the insights I gained and challenges I stumbled upon during this journey.

Reflections on the Experience

  1. Notification Management: Bluesky utilizes an explicit “isRead” property for notifications, deviating from the process of retrieving notifications from a specific timestamp or “since” a particular ID, as expected by Mastodon and Twitter. This feature allowed me to eliminate the logic for storing the “last viewed” notification state, given that I marked the notifications as read. However, this can be a downside if your application relies on timestamp or ID-based filtering for any reason, such as analyzing notification patterns over time or maintaining a historical log of notifications. In such cases, you might need to reimplement some form of tracking to achieve your specific objectives.

  2. Working with Typescript API: Initially, the Typescript API was a joy to work with. However, I soon encountered difficulties with the runtime - specifically importing certain namespaces - even though it functioned smoothly in VSCode. I spent a significant amount of time researching a reference project to discern the right configuration. The projects that guided me were: https://github.com/hs4man21/bluesky-alt-text-ocr and https://github.com/philnash/bsky-bot. In the end, I had to forsake the recommended validation and type guards as seen in https://github.com/bluesky-social/atproto/tree/main/packages/api#validation-and-types.

  3. Triggering Follow Action: An unexpected consequence of triggering the follow action was that it incited a notification even if you’re already following the account. To prevent inundating myself with notifications after following my own bot account, I added this safeguard:

if (notif.reason === "follow") {
  /**
   * Warning! We need to check if we're already following this user.
   * Otherwise, we'll deluge them with notifs until this notification
   * disappears from the first page of our bot account.
   */
  if (!notif.author.viewer?.followedBy) {
    this.agent.follow(notif.author.did);
  }
}
  1. Undocumented Features: Understandably, since ATProtocol & Bluesky are in active development, there were some aspects not covered in the written documentation. For instance, a limitation of 25 URIs exists for the getPosts endpoint, an error returned via the response to the XRPC. In the future, I’m interested in utilizing an unofficial OpenAPI spec & generated client (such as https://github.com/rdmurphy/atproto-openapi-types) to see if it aids in troubleshooting.

Future Improvements

  1. Creating a Wordle-only Feed: Currently, the bot polls a public JSON search endpoint on the Bluesky app to pull all posts containing “wordle”. My aim is to create a dedicated Wordle feed that the bot can subscribe to, to fetch new posts.

  2. Implementing Streaming: While polling enabled the bot to be operational promptly, I’m curious to experiment with streaming (similar to the capabilities offered by Mastodon and Twitter) for notifications and timeline posts. This could offer a more efficient approach to updating content.

  3. Mentions: Currently, replies on bluesky don’t actually @ mention the account — it just renders the text of the account name. This is because I’m spoiled by the mastodon/twitter APIs automatically handling this for me, so I’ll need to adjust the bluesky bot to handle this.