Contrails is an ATProto Feed Generator backed by Cloudflare Workers and Bluesky Search.
Fork or copy the repository and edit CONFIG.md
to define your feed generator.
Deploy right from GitHub Actions to Cloudflare Workers.
The current release is 0.0.4.
- Bluesky Social account
- GitHub account (Sign up or Login)
- Cloudflare account (Sign up or Login)
- A moderate-to-high tolerance for adventure
- Create a Cloudflare Worker
- Create a Cloudflare API Token (the Edit Workers template is fine)
- Create a Bluesky App Password
- Fork this repository
- In your fork's Settings > Secrets and variables > Actions, set the following:
- Variable:
BLUESKY_HANDLE
- Variable:
CLOUDFLARE_ACCOUNT_ID
- Variable:
CLOUDFLARE_WORKER_NAME
- Secret:
BLUESKY_APP_PASSWORD
- Secret:
CLOUDFLARE_API_TOKEN
- Edit CONFIG.md in your fork
- Go to Actions > 1. Check Requirements, select Run Workflow, refresh and wait for completion
- Go to Actions > 2. Deploy to Cloudflare, select Run Workflow, refresh and wait for completion
- Go to Actions > 3. Publish Feed Generator, select Run Workflow, refresh and wait for completion
- Visit the
BLUESKY_HANDLE
profile, e.g. https://bsky.app/profile/jcsalterego.bsky.social and then the Feeds tab
The longer (and incomplete) instructions can be found in INSTALL.md.
In the event you'd like to pull in the latest changes into a fork of Contrails, GitHub has great documentation here: GitHub Docs: Syncing a fork
- Pinned posts support
- Multiple feed support
- Ignore blockquotes in CONFIG.md (to allow comments).
- Delete Feed Generator workflow
- Initial Release
Ed. Note: Bluesky Search is now called Palomar.
flowchart LR
subgraph Bluesky
PDS["PDS"]
end
subgraph GitHub
subgraph MD_Config["CONFIG.md"]
searchTerms
end
subgraph CloudflareDeploy["Cloudflare Deploy"]
Worker_JS
CloudflareApiToken("CLOUDFLARE_API_TOKEN")
CloudflareAccountID("CLOUDFLARE_ACCOUNT_ID")
CloudflareWorkerName("CLOUDFLARE_WORKER_NAME")
end
subgraph BlueskyDeploy["Bluesky Deploy"]
PublishFeedGenerator
BlueskyHandle("BLUESKY_HANDLE")
BlueskyAppPassword("BLUESKY_APP_PASSWORD")
end
MD_Config --> Worker_JS["worker.js"]
MD_Config --> PublishFeedGenerator["publishFeedGenerator.ts"]
end
subgraph "Cloudflare Worker"
CloudflareWorker[worker.js]
end
CloudflareDeploy -->|Deploy to Cloudflare| CloudflareWorker
BlueskyDeploy -->|Publish Feed Generator| PDS
sequenceDiagram
actor CoffeeTeaLover
participant Bluesky
participant Cloudflare as Cloudflare Worker
participant Bluesky Search
CoffeeTeaLover->>+Bluesky: get Coffee&Tea custom feed
Bluesky->>+Cloudflare: get Coffee&Tea custom feed
Cloudflare->>+Bluesky Search: search "coffee" and "tea"
Bluesky Search->>+Cloudflare: posts matching "coffee" and "tea"
Cloudflare->>+Bluesky: IDs of posts matching "coffee" and "tea"
Bluesky->>+CoffeeTeaLover: posts for Coffee&Tea custom feed