Bluesky Social Cookbook

repository·main·Indexed 42 days ago

https://github.com/bluesky-social/cookbook

A collection of example projects and scripts for AT Protocol (atproto) development. Includes Go implementations for OAuth CLI and web applications, a repository export utility (go-repo-export), an XRPC API server example, and Python scripts for creating Bluesky posts.

Tokens
16.7K
Snippets
55
Records
70
Agent score
54%

What's inside Bluesky Cookbook

  1. Explore ATProto Hacker Cookbook examples

    main

    The ATProto Hacker Cookbook is a collection of example projects and scripts designed to help developers get started with AT Protocol (atproto) development. It includes implementations for posting to Bluesky, building bots, exporting repositories, and implementing OAuth services using various languages including Python, TypeScript, and Go.

    Available example projects:
    
    * How to make a post in Bluesky (Python)
    * Starter kit for a Bluesky bot (TypeScript)
    * Download and Inspect Repository (Go)
    * OAuth Web Service (Python)
    * OAuth Web Service (Go)
    * OAuth CLI App (Go)
    * XRPC API Server (Go)
  2. Configure OAuth Client scopes and metadata

    main

    When initializing a ClientConfig, you must define the permissions your application requests from the user via the scopes array.

    Key Concepts

    • atproto scope: Required for all applications to indicate the client is using the ATProto profile of OAuth.
    • Granular Scopes: You can request specific permissions, such as repo:app.bsky.feed.post?action=create to allow creating Bluesky posts without granting broader repository access.
    • Client Metadata: If hosting at a publicly-reachable hostname (not localhost), you must host a "client metadata" document. The SDK can help generate this via Server.ClientMetadata.

    Best Practice: Only request the minimum permissions required for your app to function to improve user trust and security.

  3. How the Vanilla JS OAuth flow works

    main

    This SPA implementation uses the @atproto/oauth-client-browser package to manage the OAuth lifecycle.

    Authentication Flow

    1. Handle Resolution: The user enters their handle. The OAuth SDK resolves the handle to locate the user's PDS (Personal Data Server). In this example, bsky.social is used as the handle resolution service.
    2. Redirection: The application redirects the user to the PDS's login page.
    3. Authorization: The PDS prompts the user to authorize the app for the requested scopes.
    4. Callback: Upon user acceptance, the user is redirected back to the application.

    Post-Authentication

    Once the OAuth session is established, an @atproto/api Agent is instantiated. This agent uses the OAuth credentials to make authenticated API requests, such as creating a Bluesky post record via the doPost() function.

  4. How to manage OAuth sessions with ClientAuthStore

    main

    Maintaining OAuth sessions requires storing state, including session tokens and refresh tokens. The SDK manages this state via the ClientAuthStore interface.

    To use the SDK, you must provide your own implementation of this interface. The example implementation in this repository uses SQLite (sqlitestore.go). For production environments, a Redis-backed implementation is recommended.

  5. Make authenticated requests with `Agent` or `BskyAgent`

    main

    Once a user is signed in, you can interact with the ATProto network using agents.

    • PdsAgentProvider: Demonstrates how to create an Agent instance to make authenticated requests directly to the user's Personal Data Server (PDS).
    • BskyAgentProvider: Demonstrates how to create a BskyAgent to interact with a dedicated appview (such as the Bluesky public API).

    An implementation example using both agents is located in app/(authenticated)/index.tsx.

  6. Quickstart: Set up the Python OAuth Web Service

    main

    This project demonstrates how to implement a Python web service using Flask and SQLite that authenticates via atproto OAuth. It uses uv for dependency management.

    Prerequisites

    1. Install uv (installation guide).
    2. A globally routed domain name with a valid HTTPS certificate (required for production deployment).

    Local Setup

    1. Sync dependencies:
      uv sync
    2. Configure environment variables:
      • Copy example.env to .env.
      • Generate a FLASK_SECRET_KEY for cookie session security.
      • Generate a FLASK_CLIENT_SECRET_JWK for the OAuth confidential client.
    3. Run the service:
      uv run -- flask run

    Note: For local testing, the service automatically uses a localhost client ID.

    uv sync
    # After updating .env with secrets
    uv run -- flask run
  7. Install go-repo-export

    main

    You can install go-repo-export directly using the Go toolchain without cloning the repository, or build it from source. Ensure you have the Go programming language toolchain installed first.

    # Install and run directly
    go install github.com/bluesky-social/cookbook/go-repo-export@latest
    
    go-repo-export [...]
    
    # Or build from source
    git clone https://github.com/bluesky-social/cookbook
    cd cookbook/go-repo-export
    go build ./...
    
    ./go-repo-export [...]
  8. Generate secrets for Flask and OAuth

    main

    To run the service, you must populate the .env file with two specific secrets. Use the following commands to generate them:

    1. FLASK_SECRET_KEY: Used for cookie session security. Generate a hex string using Python's secrets module.
    2. FLASK_CLIENT_SECRET_JWK: Used for the OAuth confidential client. Run the provided generate_jwk.py script.
    # Generate FLASK_SECRET_KEY
    uv run python3 -c 'import secrets; print(secrets.token_hex())'
    
    # Generate FLASK_CLIENT_SECRET_JWK
    uv run ./generate_jwk.py
    uv run python3 -c 'import secrets; print(secrets.token_hex())'
    uv run ./generate_jwk.py
  9. Deploy the OAuth Web App to a non-localhost environment

    main

    To deploy the application to a public-facing server, you must ensure the client metadata document is publicly accessible via HTTPS with a valid certificate. The Authorization Server requires this document during the authentication process.

    1. Copy the template metadata file: oauth-client-metadata.example.json to oauth-client-metadata.json.
    2. Replace all instances of EXAMPLE.COM with your actual public hostname (ensure the hostname is lowercase).

    You can use sed to perform this replacement:

    sed s/EXAMPLE.COM/my-real-hostname.com/g oauth-client-metadata.example.json > oauth-client-metadata.json
    sed s/EXAMPLE.COM/my-real-hostname.com/g oauth-client-metadata.example.json > oauth-client-metadata.json
  10. Run the Python script to create a Bluesky post

    main

    The create_bsky_post.py script demonstrates how to create posts using the Bluesky API, including various features and embed options. To run the script and see the available options and arguments, execute it from your terminal.

    Prerequisites

    • Python 3.11 (tested)
    • requests package
    • bs4 (BeautifulSoup) package
    ./create_bsky_post.py