# AT Protocol Tools Guide This guide demonstrates how to use the example tools together to explore the AT Protocol ecosystem. We'll walk through a complete workflow: finding interesting posts in the firehose, investigating user identities, and inspecting their repositories. ## Prerequisites Build all examples: ```bash dune build examples/ ``` Set up your credentials for `bsky_bot` (required for authenticated operations): ```bash export BSKY_USER="yourhandle.bsky.social" export BSKY_PASS="xxxx-xxxx-xxxx-xxxx" # App password from Settings > App Passwords ``` ## Overview of Tools | Tool | Purpose | |------|---------| | `feed_generator` | Subscribe to the firehose and filter events | | `identity_tool` | Resolve handles/DIDs and verify identities | | `repo_inspector` | Download and explore user repositories | | `bsky_bot` | Interact with Bluesky (post, timeline, profiles) | --- ## Step 1: Find Interesting Posts with feed_generator Start by subscribing to the firehose and filtering for posts containing a keyword of interest. Let's look for posts about "ocaml": ```bash `dune exec examples/feed_generator/feed_generator.exe -- \ --filter posts \ --keyword "ocaml" \ --limit 5 \ --content` ``` Example output: ``` Feed Generator ============== Type filter: posts Keyword: "ocaml" Connecting to wss://bsky.network/xrpc/com.atproto.sync.subscribeRepos... Connected! #commit seq=12345678 repo=did:plc:abc123xyz456 +app.bsky.feed.post/3abc123 "Just discovered OCaml! The type system is amazing..." #commit seq=12345680 repo=did:plc:def789uvw012 +app.bsky.feed.post/3def456 "Working on my first OCaml project today..." --- Stats: 1523 events (5 matched) | seq=12345700 | 8.2s | 185.7 evt/s --- ``` **Key information extracted:** - `did:plc:abc123xyz456` - The DID of a user who posted about OCaml - `app.bsky.feed.post/3abc123` - The record key of their post ### Generating a Feed Skeleton If you want to build a custom feed, use the `--skeleton` flag to output a feed skeleton: ```bash dune exec examples/feed_generator/feed_generator.exe -- \ --filter posts \ --keyword "rust" \ --limit 20 \ --skeleton ``` This outputs a JSON structure you can serve via `app.bsky.feed.getFeedSkeleton`: ```json { "feed": [ {"post": "at://did:plc:xxx/app.bsky.feed.post/abc123"}, {"post": "at://did:plc:yyy/app.bsky.feed.post/def456"} ] } ``` ### Monitoring Multiple Event Types Watch for posts, likes, and follows simultaneously: ```bash dune exec examples/feed_generator/feed_generator.exe -- \ --filter posts,likes,follows \ --limit 50 ``` --- ## Step 2: Verify User Identity with identity_tool Now that we have a DID from the firehose, let's verify the identity and get more details about the user. ### Verify Identity (Bidirectional) The default mode verifies that the DID and handle point to each other: ```bash dune exec examples/identity_tool/identity_tool.exe -- did:plc:abc123xyz456 ``` Example output: ``` PASSED DID: did:plc:abc123xyz456 Handle: alice.bsky.social Key: zQ3shXjHeiBuRCKmM... PDS: https://morel.us-east.host.bsky.network ``` This tells us: - The identity verification passed (handle and DID are correctly linked) - The user's handle is `alice.bsky.social` - Their signing key (for verifying commits) - Their PDS (Personal Data Server) URL ### Resolve Handle to DID If you have a handle and need the DID: ```bash dune exec examples/identity_tool/identity_tool.exe -- -H alice.bsky.social ``` Output: ``` Handle: alice.bsky.social DID: did:plc:abc123xyz456 ``` ### Resolve DID to Full Document Get the complete DID document with all services and keys: ```bash dune exec examples/identity_tool/identity_tool.exe -- -d did:plc:abc123xyz456 ``` Output: ``` DID: did:plc:abc123xyz456 Handle: at://alice.bsky.social Key: zQ3shXjHeiBuRCKmM... (Multikey) Service: AtprotoPersonalDataServer -> https://morel.us-east.host.bsky.network ``` --- ## Step 3: Inspect User Repository with repo_inspector With the verified DID, we can download and inspect the user's entire repository. The tool automatically resolves the user's PDS from their DID document. ### Repository Summary Get an overview of the repository: ```bash dune exec examples/repo_inspector/repo_inspector.exe -- did:plc:abc123xyz456 ``` Example output: ``` Repository Inspector ==================== Resolving PDS for did:plc:abc123xyz456... PDS: https://morel.us-east.host.bsky.network Fetching https://morel.us-east.host.bsky.network/xrpc/com.atproto.sync.getRepo?did=did:plc:abc123xyz456... CAR Header ---------- Version: 1 Roots: 1 - bafyreib... Blocks: 1234 Commit ------ DID: did:plc:abc123xyz456 Version: 3 Rev: 3la7j2xyz... Data: bafyreic... Collections ----------- app.bsky.feed.post: 456 app.bsky.feed.like: 789 app.bsky.graph.follow: 123 app.bsky.actor.profile: 1 Total records: 1369 ``` ### List Collections See all collections with record counts: ```bash dune exec examples/repo_inspector/repo_inspector.exe -- \ did:plc:abc123xyz456 --collections ``` ### Browse Records View individual records: ```bash dune exec examples/repo_inspector/repo_inspector.exe -- \ did:plc:abc123xyz456 --records --limit 10 ``` Output: ``` Records ------- app.bsky.feed.post/3abc123 CID: bafyreig... Text: Just discovered OCaml! The type system is amazing... app.bsky.feed.post/3def456 CID: bafyreih... Text: Working on my second OCaml project... ... and 454 more ``` ### Filter by Collection View only posts: ```bash dune exec examples/repo_inspector/repo_inspector.exe -- \ did:plc:abc123xyz456 --records --collection app.bsky.feed.post --limit 20 ``` View only follows: ```bash dune exec examples/repo_inspector/repo_inspector.exe -- \ did:plc:abc123xyz456 --records --collection app.bsky.graph.follow --limit 20 ``` ### Verify Commit Signature Check the repository commit signature: ```bash dune exec examples/repo_inspector/repo_inspector.exe -- \ did:plc:abc123xyz456 --verify ``` ### Skip PDS Resolution If you already know the PDS URL (from identity_tool or a previous run), you can skip the resolution step: ```bash dune exec examples/repo_inspector/repo_inspector.exe -- \ did:plc:abc123xyz456 --pds https://morel.us-east.host.bsky.network ``` --- ## Step 4: Get User Profile with bsky_bot For a more user-friendly view, use `bsky_bot` to get the profile (requires authentication): ```bash dune exec examples/bsky_bot/bsky_bot.exe -- \ --user "$BSKY_USER" \ --password "$BSKY_PASS" \ --profile alice.bsky.social ``` Output: ``` Logged in as yourhandle.bsky.social Handle: @alice.bsky.social DID: did:plc:abc123xyz456 Name: Alice Bio: OCaml enthusiast and functional programming advocate Followers: 1234 Following: 567 Posts: 456 ``` ### View Your Timeline See recent posts from people you follow: ```bash dune exec examples/bsky_bot/bsky_bot.exe -- \ --user "$BSKY_USER" \ --password "$BSKY_PASS" \ --timeline --limit 10 ``` ### Follow a User Follow someone using their DID (obtained from identity_tool or feed_generator): ```bash dune exec examples/bsky_bot/bsky_bot.exe -- \ --user "$BSKY_USER" \ --password "$BSKY_PASS" \ --follow did:plc:abc123xyz456 ``` --- ## Complete Workflow Example Here's a complete example workflow to find OCaml enthusiasts and explore their content: ```bash #!/bin/bash # 1. Find users posting about OCaml echo "=== Finding OCaml posts ===" dune exec examples/feed_generator/feed_generator.exe -- \ --filter posts --keyword "ocaml" --limit 3 --json 2>/dev/null | \ head -3 # Let's say we found: did:plc:z72i7hdynmk6r22z27h6tvur DID="did:plc:z72i7hdynmk6r22z27h6tvur" # 2. Verify the identity echo -e "\n=== Verifying identity ===" dune exec examples/identity_tool/identity_tool.exe -- "$DID" # 3. Get their handle from the verification and look up their profile HANDLE="jay.bsky.social" # Extracted from step 2 echo -e "\n=== Getting profile ===" dune exec examples/bsky_bot/bsky_bot.exe -- \ --user "$BSKY_USER" --password "$BSKY_PASS" \ --profile "$HANDLE" # 4. Inspect their repository echo -e "\n=== Repository overview ===" dune exec examples/repo_inspector/repo_inspector.exe -- "$DID" # 5. See their recent posts echo -e "\n=== Recent posts ===" dune exec examples/repo_inspector/repo_inspector.exe -- \ "$DID" --records --collection app.bsky.feed.post --limit 5 ``` --- ## Advanced Usage ### JSON Output for Scripting The feed_generator supports JSON output for integration with other tools: ```bash dune exec examples/feed_generator/feed_generator.exe -- \ --filter posts --keyword "atproto" --limit 5 --json --content ``` You can pipe this to `jq` for further processing: ```bash dune exec examples/feed_generator/feed_generator.exe -- \ --filter posts --limit 10 --json 2>/dev/null | \ jq -r '.repo' | sort | uniq ``` ### Resume from Cursor If you need to resume from a specific point in the firehose: ```bash dune exec examples/feed_generator/feed_generator.exe -- \ --cursor 1234567890 --limit 100 ``` ### Monitoring Identity Changes Watch for handle changes and identity updates: ```bash dune exec examples/feed_generator/feed_generator.exe -- \ --filter identities,handles --limit 20 ``` ### Watching Account Events Monitor account activations and deactivations: ```bash dune exec examples/feed_generator/feed_generator.exe -- \ --filter accounts --limit 10 ``` --- ## Architecture Overview ``` +-------------------+ | Bluesky Relay | | bsky.network | +-------------------+ | | WebSocket (firehose) v +-------------------+ | feed_generator | | (filter events) | +-------------------+ | | DID extracted v +-------------------+ +-------------------+ +-------------------+ | identity_tool |<---->| PLC Directory | | User's PDS | | (resolve/verify) | | DID Documents | | | +-------------------+ +-------------------+ +-------------------+ | ^ | DID verified | v | +-------------------+ | | repo_inspector |------------------------------------------+ | (download & parse)| com.atproto.sync.getRepo +-------------------+ +-------------------+ | bsky_bot |-------> Authenticated XRPC calls | (social actions) | (post, timeline, profile, follow) +-------------------+ ``` ## Troubleshooting ### Connection Errors If the firehose connection fails: - Check your internet connection - The relay at `bsky.network` may be temporarily unavailable - Try again after a few seconds ### Identity Resolution Failures If identity verification fails: - The handle may have changed recently (DNS propagation delay) - The DID document may be temporarily unavailable - Try resolving the handle and DID separately to diagnose ### Large Repositories For users with many records: - Use `--limit` to restrict the number of records shown - Use `--collection` to filter to specific record types - Repository download may take several seconds for active users --- ## Next Steps - Build a custom feed generator using `feed_generator` as a template - Create a bot that responds to mentions using `bsky_bot` - Build analytics tools using `repo_inspector` to analyze user behavior - Implement identity verification in your applications using `identity_tool` See the individual README files in each example directory for more details: - [bsky_bot/README.md](bsky_bot/README.md) - [feed_generator/README.md](feed_generator/README.md) - [identity_tool/README.md](identity_tool/README.md) - [repo_inspector/README.md](repo_inspector/README.md)