atproto libraries implementation in ocaml
Feed Generator#
AT Protocol firehose client with filtering and feed skeleton generation.
This example demonstrates how to:
- Subscribe to the Bluesky network firehose using
atproto-sync - Filter events by type (posts, likes, follows, etc.)
- Filter posts by keyword content
- Parse and decode CAR files and DAG-CBOR records
- Generate feed skeleton output for custom feed generators
Building#
dune build examples/feed_generator/feed_generator.exe
Usage#
dune exec examples/feed_generator/feed_generator.exe -- [OPTIONS]
Options#
| Option | Description |
|---|---|
--cursor <INT64> |
Resume from a specific sequence number |
--limit <INT> |
Stop after N matched events |
--filter <TYPES> |
Filter by event type (comma-separated) |
-k, --keyword <STRING> |
Filter posts containing keyword (case-insensitive) |
--json |
Output events as JSON |
--content |
Include decoded record content in output |
-s, --skeleton |
Output feed skeleton at end (for custom feeds) |
Event Types#
Available filter types:
posts- app.bsky.feed.post recordslikes- app.bsky.feed.like recordsfollows- app.bsky.graph.follow recordsreposts- app.bsky.feed.repost recordsblocks- app.bsky.graph.block recordslists- app.bsky.graph.list recordsprofiles- app.bsky.actor.profile recordsfeeds- app.bsky.feed.generator recordscommits- all commit eventsidentities- identity change eventsaccounts- account status eventshandles- handle change eventstombstones- account deletion events
Examples#
Watch all posts#
feed_generator --filter posts
Filter posts by keyword#
feed_generator --filter posts --keyword "ocaml" --limit 10
Generate a feed skeleton#
Collect posts matching a keyword and output a feed skeleton suitable for serving via app.bsky.feed.getFeedSkeleton:
feed_generator --filter posts --keyword "rust" --limit 50 --skeleton
Output includes:
{
"feed": [
{"post": "at://did:plc:xxx/app.bsky.feed.post/abc123"},
{"post": "at://did:plc:yyy/app.bsky.feed.post/def456"}
]
}
JSON output with full record content#
feed_generator --filter posts --json --content --limit 5
Watch multiple event types#
feed_generator --filter posts,likes,follows --limit 100
Resume from a cursor#
feed_generator --cursor 1234567890 --limit 50
Watch all activity with decoded content#
feed_generator --content
Architecture#
The tool uses several AT Protocol libraries:
- atproto-sync: Firehose subscription and event parsing
- atproto-ipld: CAR file parsing, DAG-CBOR decoding, CID handling
Key components:
- WebSocket client: TLS-enabled WebSocket connection to the relay
- Event handler: Processes commit, identity, account, and other events
- Type filter: Matches operations against Lexicon record types
- Keyword filter: Case-insensitive text search in post records
- Feed skeleton: Collects AT URIs for matched posts
Building a Custom Feed#
To build a complete custom feed generator:
- Use this tool to prototype your filtering logic
- Run with
--skeletonto verify the output format - Implement a persistent service that:
- Subscribes to the firehose continuously
- Stores matched post URIs in a database
- Serves the feed via XRPC endpoint
app.bsky.feed.getFeedSkeleton - Publishes a feed generator record to your repository
See the AT Protocol Feed Generator documentation for more details.