atproto libraries implementation in ocaml
1# AT Protocol Tools Guide
2
3This 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.
4
5## Prerequisites
6
7Build all examples:
8
9```bash
10dune build examples/
11```
12
13Set up your credentials for `bsky_bot` (required for authenticated operations):
14
15```bash
16export BSKY_USER="yourhandle.bsky.social"
17export BSKY_PASS="xxxx-xxxx-xxxx-xxxx" # App password from Settings > App Passwords
18```
19
20## Overview of Tools
21
22| Tool | Purpose |
23|------|---------|
24| `feed_generator` | Subscribe to the firehose and filter events |
25| `identity_tool` | Resolve handles/DIDs and verify identities |
26| `repo_inspector` | Download and explore user repositories |
27| `bsky_bot` | Interact with Bluesky (post, timeline, profiles) |
28
29---
30
31## Step 1: Find Interesting Posts with feed_generator
32
33Start by subscribing to the firehose and filtering for posts containing a keyword of interest. Let's look for posts about "ocaml":
34
35```bash
36`dune exec examples/feed_generator/feed_generator.exe -- \
37 --filter posts \
38 --keyword "ocaml" \
39 --limit 5 \
40 --content`
41```
42
43Example output:
44
45```
46Feed Generator
47==============
48
49Type filter: posts
50Keyword: "ocaml"
51
52Connecting to wss://bsky.network/xrpc/com.atproto.sync.subscribeRepos...
53Connected!
54
55#commit seq=12345678 repo=did:plc:abc123xyz456
56 +app.bsky.feed.post/3abc123 "Just discovered OCaml! The type system is amazing..."
57#commit seq=12345680 repo=did:plc:def789uvw012
58 +app.bsky.feed.post/3def456 "Working on my first OCaml project today..."
59
60--- Stats: 1523 events (5 matched) | seq=12345700 | 8.2s | 185.7 evt/s ---
61```
62
63**Key information extracted:**
64- `did:plc:abc123xyz456` - The DID of a user who posted about OCaml
65- `app.bsky.feed.post/3abc123` - The record key of their post
66
67### Generating a Feed Skeleton
68
69If you want to build a custom feed, use the `--skeleton` flag to output a feed skeleton:
70
71```bash
72dune exec examples/feed_generator/feed_generator.exe -- \
73 --filter posts \
74 --keyword "rust" \
75 --limit 20 \
76 --skeleton
77```
78
79This outputs a JSON structure you can serve via `app.bsky.feed.getFeedSkeleton`:
80
81```json
82{
83 "feed": [
84 {"post": "at://did:plc:xxx/app.bsky.feed.post/abc123"},
85 {"post": "at://did:plc:yyy/app.bsky.feed.post/def456"}
86 ]
87}
88```
89
90### Monitoring Multiple Event Types
91
92Watch for posts, likes, and follows simultaneously:
93
94```bash
95dune exec examples/feed_generator/feed_generator.exe -- \
96 --filter posts,likes,follows \
97 --limit 50
98```
99
100---
101
102## Step 2: Verify User Identity with identity_tool
103
104Now that we have a DID from the firehose, let's verify the identity and get more details about the user.
105
106### Verify Identity (Bidirectional)
107
108The default mode verifies that the DID and handle point to each other:
109
110```bash
111dune exec examples/identity_tool/identity_tool.exe -- did:plc:abc123xyz456
112```
113
114Example output:
115
116```
117PASSED
118DID: did:plc:abc123xyz456
119Handle: alice.bsky.social
120Key: zQ3shXjHeiBuRCKmM...
121PDS: https://morel.us-east.host.bsky.network
122```
123
124This tells us:
125- The identity verification passed (handle and DID are correctly linked)
126- The user's handle is `alice.bsky.social`
127- Their signing key (for verifying commits)
128- Their PDS (Personal Data Server) URL
129
130### Resolve Handle to DID
131
132If you have a handle and need the DID:
133
134```bash
135dune exec examples/identity_tool/identity_tool.exe -- -H alice.bsky.social
136```
137
138Output:
139
140```
141Handle: alice.bsky.social
142DID: did:plc:abc123xyz456
143```
144
145### Resolve DID to Full Document
146
147Get the complete DID document with all services and keys:
148
149```bash
150dune exec examples/identity_tool/identity_tool.exe -- -d did:plc:abc123xyz456
151```
152
153Output:
154
155```
156DID: did:plc:abc123xyz456
157Handle: at://alice.bsky.social
158Key: zQ3shXjHeiBuRCKmM... (Multikey)
159Service: AtprotoPersonalDataServer -> https://morel.us-east.host.bsky.network
160```
161
162---
163
164## Step 3: Inspect User Repository with repo_inspector
165
166With 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.
167
168### Repository Summary
169
170Get an overview of the repository:
171
172```bash
173dune exec examples/repo_inspector/repo_inspector.exe -- did:plc:abc123xyz456
174```
175
176Example output:
177
178```
179Repository Inspector
180====================
181
182Resolving PDS for did:plc:abc123xyz456...
183PDS: https://morel.us-east.host.bsky.network
184
185Fetching https://morel.us-east.host.bsky.network/xrpc/com.atproto.sync.getRepo?did=did:plc:abc123xyz456...
186
187CAR Header
188----------
189Version: 1
190Roots: 1
191 - bafyreib...
192Blocks: 1234
193
194Commit
195------
196DID: did:plc:abc123xyz456
197Version: 3
198Rev: 3la7j2xyz...
199Data: bafyreic...
200
201Collections
202-----------
203 app.bsky.feed.post: 456
204 app.bsky.feed.like: 789
205 app.bsky.graph.follow: 123
206 app.bsky.actor.profile: 1
207
208Total records: 1369
209```
210
211### List Collections
212
213See all collections with record counts:
214
215```bash
216dune exec examples/repo_inspector/repo_inspector.exe -- \
217 did:plc:abc123xyz456 --collections
218```
219
220### Browse Records
221
222View individual records:
223
224```bash
225dune exec examples/repo_inspector/repo_inspector.exe -- \
226 did:plc:abc123xyz456 --records --limit 10
227```
228
229Output:
230
231```
232Records
233-------
234app.bsky.feed.post/3abc123
235 CID: bafyreig...
236 Text: Just discovered OCaml! The type system is amazing...
237
238app.bsky.feed.post/3def456
239 CID: bafyreih...
240 Text: Working on my second OCaml project...
241
242... and 454 more
243```
244
245### Filter by Collection
246
247View only posts:
248
249```bash
250dune exec examples/repo_inspector/repo_inspector.exe -- \
251 did:plc:abc123xyz456 --records --collection app.bsky.feed.post --limit 20
252```
253
254View only follows:
255
256```bash
257dune exec examples/repo_inspector/repo_inspector.exe -- \
258 did:plc:abc123xyz456 --records --collection app.bsky.graph.follow --limit 20
259```
260
261### Verify Commit Signature
262
263Check the repository commit signature:
264
265```bash
266dune exec examples/repo_inspector/repo_inspector.exe -- \
267 did:plc:abc123xyz456 --verify
268```
269
270### Skip PDS Resolution
271
272If you already know the PDS URL (from identity_tool or a previous run), you can skip the resolution step:
273
274```bash
275dune exec examples/repo_inspector/repo_inspector.exe -- \
276 did:plc:abc123xyz456 --pds https://morel.us-east.host.bsky.network
277```
278
279---
280
281## Step 4: Get User Profile with bsky_bot
282
283For a more user-friendly view, use `bsky_bot` to get the profile (requires authentication):
284
285```bash
286dune exec examples/bsky_bot/bsky_bot.exe -- \
287 --user "$BSKY_USER" \
288 --password "$BSKY_PASS" \
289 --profile alice.bsky.social
290```
291
292Output:
293
294```
295Logged in as yourhandle.bsky.social
296Handle: @alice.bsky.social
297DID: did:plc:abc123xyz456
298Name: Alice
299Bio: OCaml enthusiast and functional programming advocate
300Followers: 1234
301Following: 567
302Posts: 456
303```
304
305### View Your Timeline
306
307See recent posts from people you follow:
308
309```bash
310dune exec examples/bsky_bot/bsky_bot.exe -- \
311 --user "$BSKY_USER" \
312 --password "$BSKY_PASS" \
313 --timeline --limit 10
314```
315
316### Follow a User
317
318Follow someone using their DID (obtained from identity_tool or feed_generator):
319
320```bash
321dune exec examples/bsky_bot/bsky_bot.exe -- \
322 --user "$BSKY_USER" \
323 --password "$BSKY_PASS" \
324 --follow did:plc:abc123xyz456
325```
326
327---
328
329## Complete Workflow Example
330
331Here's a complete example workflow to find OCaml enthusiasts and explore their content:
332
333```bash
334#!/bin/bash
335
336# 1. Find users posting about OCaml
337echo "=== Finding OCaml posts ==="
338dune exec examples/feed_generator/feed_generator.exe -- \
339 --filter posts --keyword "ocaml" --limit 3 --json 2>/dev/null | \
340 head -3
341
342# Let's say we found: did:plc:z72i7hdynmk6r22z27h6tvur
343
344DID="did:plc:z72i7hdynmk6r22z27h6tvur"
345
346# 2. Verify the identity
347echo -e "\n=== Verifying identity ==="
348dune exec examples/identity_tool/identity_tool.exe -- "$DID"
349
350# 3. Get their handle from the verification and look up their profile
351HANDLE="jay.bsky.social" # Extracted from step 2
352
353echo -e "\n=== Getting profile ==="
354dune exec examples/bsky_bot/bsky_bot.exe -- \
355 --user "$BSKY_USER" --password "$BSKY_PASS" \
356 --profile "$HANDLE"
357
358# 4. Inspect their repository
359echo -e "\n=== Repository overview ==="
360dune exec examples/repo_inspector/repo_inspector.exe -- "$DID"
361
362# 5. See their recent posts
363echo -e "\n=== Recent posts ==="
364dune exec examples/repo_inspector/repo_inspector.exe -- \
365 "$DID" --records --collection app.bsky.feed.post --limit 5
366```
367
368---
369
370## Advanced Usage
371
372### JSON Output for Scripting
373
374The feed_generator supports JSON output for integration with other tools:
375
376```bash
377dune exec examples/feed_generator/feed_generator.exe -- \
378 --filter posts --keyword "atproto" --limit 5 --json --content
379```
380
381You can pipe this to `jq` for further processing:
382
383```bash
384dune exec examples/feed_generator/feed_generator.exe -- \
385 --filter posts --limit 10 --json 2>/dev/null | \
386 jq -r '.repo' | sort | uniq
387```
388
389### Resume from Cursor
390
391If you need to resume from a specific point in the firehose:
392
393```bash
394dune exec examples/feed_generator/feed_generator.exe -- \
395 --cursor 1234567890 --limit 100
396```
397
398### Monitoring Identity Changes
399
400Watch for handle changes and identity updates:
401
402```bash
403dune exec examples/feed_generator/feed_generator.exe -- \
404 --filter identities,handles --limit 20
405```
406
407### Watching Account Events
408
409Monitor account activations and deactivations:
410
411```bash
412dune exec examples/feed_generator/feed_generator.exe -- \
413 --filter accounts --limit 10
414```
415
416---
417
418## Architecture Overview
419
420```
421 +-------------------+
422 | Bluesky Relay |
423 | bsky.network |
424 +-------------------+
425 |
426 | WebSocket (firehose)
427 v
428 +-------------------+
429 | feed_generator |
430 | (filter events) |
431 +-------------------+
432 |
433 | DID extracted
434 v
435+-------------------+ +-------------------+ +-------------------+
436| identity_tool |<---->| PLC Directory | | User's PDS |
437| (resolve/verify) | | DID Documents | | |
438+-------------------+ +-------------------+ +-------------------+
439 | ^
440 | DID verified |
441 v |
442+-------------------+ |
443| repo_inspector |------------------------------------------+
444| (download & parse)| com.atproto.sync.getRepo
445+-------------------+
446
447+-------------------+
448| bsky_bot |-------> Authenticated XRPC calls
449| (social actions) | (post, timeline, profile, follow)
450+-------------------+
451```
452
453## Troubleshooting
454
455### Connection Errors
456
457If the firehose connection fails:
458- Check your internet connection
459- The relay at `bsky.network` may be temporarily unavailable
460- Try again after a few seconds
461
462### Identity Resolution Failures
463
464If identity verification fails:
465- The handle may have changed recently (DNS propagation delay)
466- The DID document may be temporarily unavailable
467- Try resolving the handle and DID separately to diagnose
468
469### Large Repositories
470
471For users with many records:
472- Use `--limit` to restrict the number of records shown
473- Use `--collection` to filter to specific record types
474- Repository download may take several seconds for active users
475
476---
477
478## Next Steps
479
480- Build a custom feed generator using `feed_generator` as a template
481- Create a bot that responds to mentions using `bsky_bot`
482- Build analytics tools using `repo_inspector` to analyze user behavior
483- Implement identity verification in your applications using `identity_tool`
484
485See the individual README files in each example directory for more details:
486- [bsky_bot/README.md](bsky_bot/README.md)
487- [feed_generator/README.md](feed_generator/README.md)
488- [identity_tool/README.md](identity_tool/README.md)
489- [repo_inspector/README.md](repo_inspector/README.md)