Bluesky.bot

Make a bot in Python

This guide writes a bot that posts to Bluesky with atproto, the community Python SDK. It needs Python 3.9 or later.

1. Create an app password

Sign in to Bluesky as the bot, then open Settings → Privacy and security → App passwords and create one. A bot signs in with an app password, never with the account's main password.

2. Set up the project

bash
mkdir my-bot && cd my-bot
python -m venv .venv
source .venv/bin/activate
pip install atproto

Keep the credentials out of the code:

bash
export BLUESKY_HANDLE="weather.bluesky.bot"
export BLUESKY_APP_PASSWORD="xxxx-xxxx-xxxx-xxxx"

3. Write the bot

bot.py
# bot.py: post once as the bot. Run with `python bot.py`.
import os

from atproto import Client, client_utils

# The bot's own account, signed in with an app password
# (Settings > Privacy and security > App passwords), never its main password.
handle = os.environ.get("BLUESKY_HANDLE")
password = os.environ.get("BLUESKY_APP_PASSWORD")
if not handle or not password:
    raise SystemExit("Set BLUESKY_HANDLE and BLUESKY_APP_PASSWORD.")

client = Client()
client.login(handle, password)

# TextBuilder makes the link and the hashtag clickable.
text = (
    client_utils.TextBuilder()
    .text("Today: sunny, 21°C. Forecast at ")
    .link("example.com", "https://example.com")
    .text(" ")
    .tag("#weather", "weather")
)

post = client.send_post(text)
print(f"Posted {post.uri}")

What it does:

  • Client() talks to https://bsky.social by default. For a self-hosted server, pass its URL: Client("https://pds.example.com").
  • login opens a session with the handle and the app password.
  • TextBuilder builds the text and the facets that make the link and the hashtag clickable.
  • send_post creates the post; its uri is the post's at:// address.

4. Run it

bash
python bot.py

Next