DEV Community

Fernando Tricas García
Fernando Tricas García

Posted on

So, you want to publish in Bluesky with a python program?

Bluesky is a microblogging social platform that has been available for aproximately a year. Currently, access is by invitation only, but invitations are becoming more readily available. If you don't have one yet, you should receive one soon.

In my quest to experiment with the platform, I aimed to publish posts programmatically. I stumbled upon a helpful resource, Posting via the Bluesky API, which guided me in getting started.

Bluesky utilizes the AT protocol so I conducted a quick search to find a Python implementation of it, available at atproto. You can install it on your system using the usual method:

pip install -U atproto
Enter fullscreen mode Exit fullscreen mode

Once installed, you can start posting using the appropriate code. For instance, you can post a text message with a line like this:

You can post a text message with some line such as:

client.send_post(text='Hello World!')
Enter fullscreen mode Exit fullscreen mode

provided, of course, that you are authenticated, and so on.

However, I wanted to publish text with links, and simply writing a URL in your text won't automatically create a link:

Example of publication in Bluesky, with link not interpreted and then, as a reply, with the link interpreted

To achieve this, I needed to do some research. You can see the difference in the reply between having a link and not having one. You can include additional information when you write by using what they call 'facets.' For adding a link, you can use the AppBskyRichtextFacet, which allows you to:

  • Add a uri
  • Specify the start and end indices of the URI in your text

For example, if you want to insert some text before your URI, you can do something like this:

models.AppBskyRichtextFacet.Main(
            features=[models.AppBskyRichtextFacet.Link(uri=uri)],
            index=models.AppBskyRichtextFacet.ByteSlice(byte_start=len(text)+1,
                                                        byte_end=len(text)+len(uri)+1),
            )
Enter fullscreen mode Exit fullscreen mode

Note that you are specifying the position where your URI begins and ends. You can append it to your list of facets and send it as text to your Bluesky account.

You can see the complete program at:

from atproto import Client, models


def main():
    client = Client()
    password = input("Password? ")
    profile = client.login('fernand0.bsky.social', password)
    print('Welcome,', profile.display_name)

    facets =  []

    text = 'Mi GitHub:'
    uri = 'http://github.com/fernand0'
    facets.append(
            models.AppBskyRichtextFacet.Main(
                features=[models.AppBskyRichtextFacet.Link(uri=uri)],
                index=models.AppBskyRichtextFacet.ByteSlice(byte_start=len(text)+1,
                                                            byte_end=len(text)+len(uri)+1),
                )
            )

    text = f"{text} {uri}"
    response = client.com.atproto.repo.create_record(
        models.ComAtprotoRepoCreateRecord.Data(
            repo=client.me.did,
            collection=models.ids.AppBskyFeedPost,
            record=models.AppBskyFeedPost.Main(created_at=client.get_current_time_iso(), text=text, facets=facets),
        )
    )
    print(f"Response: {response}")


if __name__ == '__main__':
    main()
Enter fullscreen mode Exit fullscreen mode

You can download the code in this publish in bluesky gist.

Top comments (0)