The Bluesky furry feed, sometimes referred to as bff, is written mostly in Go. It broadly consists of a data ingester, the feed generation service, and a moderation system for—among other uses—approving new users to the feed.
After cloning this repository, install the following required system dependencies if you don’t have them yet:
- The latest Go 1.20 version,
- Docker, and
- docker-compose if your Docker version doesn’t
support running
docker compose
as subcommand of Docker.
In addition to this, we’re using sqlc
and migrate
to manage our
database schema. Install them by executing the following commands:
$ go install github.com/kyleconroy/sqlc/cmd/sqlc@v1.19.0
$ go install -tags 'postgres' github.com/golang-migrate/migrate/v4/cmd/migrate@latest
In order to run the ingest and feed server, you need to start a local
development database. Start it by executing docker-compose up -d
. If
you want to turn it off again, execute docker-compose down
. You can
learn more about docker-compose in the official docs.
Now that your database is running, you need to initially run all database migrations, so that all required tables are created. You’ll need to re-run this any time we create a new migration.
$ migrate -path store/migrations -database "postgres://bff:bff@localhost:5432/bff?sslmode=disable" up
1/u candidate_actors (Xms)
2/u create_candidate_post (Xms)
3/u create_candidate_like (Xms)
4/u create_candidate_follow (Xms)
...
Both the server and cli need a Bluesky login to start. Copy the
.env.example
to .env
and follow the instructions in there.
With the database running and the schema migrated, you can start the main
bff server (aka. bffsrv
):
$ go run ./cmd/bffsrv/
...
You may also want to use the cli (aka. bffctl
) to e.g. interact with
the database or find a did by a user’s handle.
$ go run ./cmd/bffctl/ -e local
NAME:
bffctl - The swiss army knife of any BFF operator
...
By default, the ingest saves no data because no user is registered as
so-called candidate actor. To add a user as candidate actor and allow
the ingest server to collect their posts, likes, and follows, add them
to the database using bffctl (where HANDLE
is your Bluesky handle, such
as ottr.sh
):
$ go run ./cmd/bffctl/ -e local db ca add --handle HANDLE
...
2023-07-07T01:26:56.071+0200 INFO bffctl/db.go:175 successfully added
We use sqlc
to generate type-safe code from raw SQL queries and
migrate
to create & manage migrations.
To create a migration, run this command in the project root where
NAME
is the name of your migration, such as create_post_candidate
:
$ migrate create -ext sql -dir store/migrations -seq NAME
/.../store/migrations/000010_NAME.up.sql
/.../store/migrations/000010_NAME.down.sql
The queries in the *.up.sql
file are executed when running the
up
command using migrate. To rollback the latest
migration, run migrate’s down
command.
$ migrate -path store/migrations -database "postgres://bff:bff@localhost:5432/bff?sslmode=disable" down 1
10/d NAME (39.10048ms)
After applying a new migration or editing a query, such as in
store/queries/candidate_posts.sql
, we need to generate the sqlc
bindings for the database schema and all queries:
$ sqlc generate --experimental
While the official Bluesky client supports feeds, you may prefer using SkyFeed, a community-created client with feed support.
You need HTTPS, so use Cloudflare Tunnel or similar when developing.