An Elixir library for listening to events from an ATProtocol relay
(firehose/com.atproto.sync.subscribeRepos
). Eventually aiming to support any
ATProtocol subscription.
- Support for different subscriptions other than `com.atproto.sync.subscribeRepo'.
- Validation (signatures, making sure to only track handle active accounts, etc.) (see Firehose Validation Best Practices)
- Look into backfilling? See if there's better ways to do it.
- Built-in solutions for tracking resumption? (probably a pluggable solution to allow for different things like Mnesia, Postgres, etc.)
- Testing of multi-node/distribution.
- Tests
- Documentation
Add drinkup
to your mix.exs
.
def deps do
[
{:drinkup, "~> 0.1"}
]
end
Documentation can be found on HexDocs at https://hexdocs.pm/drinkup.
First, create a module implementing the Drinkup.Consumer
behaviour (only
requires a handle_event/1
function):
defmodule ExampleConsumer do
@behaviour Drinkup.Consumer
def handle_event(%Drinkup.Event.Commit{} = event) do
IO.inspect(event, label: "Got commit event")
end
def handle_event(_), do: :noop
end
Then add Drinkup and your consumer to your application's supervision tree:
defmodule MyApp.Application do
use Application
def start(_type, _args) do
children = [{Drinkup, %{consumer: ExampleConsumer}}]
Supervisor.start_link(children, strategy: :one_for_one)
end
end
You should then be able to start your application and start seeing
Got commit event: ...
in the terminal.
One of the main reasons for listening to an ATProto relay is to synchronise a
database with records. As a result, Drinkup provides a light extension around a
basic consumer, the RecordConsumer
, which only listens to commit events, and
transforms them into a slightly nicer structure to work around, calling your
handle_create/1
, handle_update/1
, and handle_delete/1
functions for each
record it comes across. It also allows for filtering of specific types of
records either by full name or with a
Regex match.
defmodule ExampleRecordConsumer do
# Will respond to any events either `app.bsky.feed.post` records, or anything under `app.bsky.graph`.
use Drinkup.RecordConsumer, collections: [~r/app\.bsky\.graph\..+/, "app.bsky.feed.post"]
alias Drinkup.RecordConsumer.Record
def handle_create(%Record{type: "app.bsky.feed.post"} = record) do
IO.inspect(record, label: "Bluesky post created")
end
def handle_create(%Record{type: "app.bsky.graph" <> _} = record) do
IO.inspect(record, label: "Bluesky graph updated")
end
def handle_update(record) do
# ...
end
def handle_delete(record) do
# ...
end
end
The process structure used in Drinkup is heavily inspired by the work done on Nostrum, an incredible Elixir library for Discord.
This project is licensed under the MIT License