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.2.0.
- 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.
The first step before any major upgrade is to make a copy of your markdown config file. Your best bet is to save it in a separate directory such as backup_configs/
, or you will have to remember to set isEnabled
to false so it doesn't get picked up as a live config!
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
- Pagination
- Safe Mode
- New search term type: Users
- New search term type: Pinned posts
- 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