-
-
Notifications
You must be signed in to change notification settings - Fork 5
Cloudflare Workers
Nine Cloudflare Workers back the parts of Orchard that need a credential the app must not
ship, or a service that should not run per-client. They live under workers/, each as its
own npm project with its own wrangler.jsonc.
If you self-host Orchard's backend, this page is your index. Every worker has its own README with exact provisioning steps.
| Worker | What it does | Backing |
|---|---|---|
bpm |
Tempo and musical-key lookup | GetSongBPM |
concerts |
Nearby music-event discovery | Ticketmaster |
lastfm |
Signs and forwards Last.fm auth and scrobbles | Last.fm |
listening-party |
Room coordination and WebRTC signaling | Durable Objects |
song-links |
Cross-service share links | D1 |
support |
Two-way support reports | D1, R2, Discord, GitHub |
artwork-proxy |
Animated artwork MP4 to cacheable GIF | External converter |
artist-metadata |
Broad artist genre resolution | iTunes, D1 |
artist-packs |
Official artist pack distribution | Static content |
The recurring reason is credential ownership. Orchard is open source and its binaries are
distributed publicly, so any API key inside the app is a published API key. The lastfm
worker owns Orchard's Last.fm API key and shared secret and signs requests on the client's
behalf; the bpm worker owns the GetSongBPM key; concerts owns the Ticketmaster key.
None of those secrets are committed or bundled.
The second reason is quota and caching. bpm ranks and normalizes results and caches
successful lookups specifically to protect GetSongBPM's hourly quota, which per-client
requests would burn through.
Each worker is provisioned the same way:
cd workers/<name>
npm install
npx wrangler login
npx wrangler secret put <SECRET_NAME>
npm run deployMost have npm run check for validation before deploying. After deployment, use the
assigned workers.dev URL or configure a custom domain.
GET /bpm?title=Master%20of%20Puppets&artist=Metallicatitle is required, artist optional. Returns bpm, key, openKey, timeSignature,
and matched song metadata. GET /health is a liveness check.
The root page carries the backlink GetSongBPM's API terms require, and the deployed URL must be registered at GetSongBPM's API page.
/events?location=Example%20City,%20CA
/events?location=00000
/events?lat=0&lng=0
Needs the Ticketmaster key as a secret.
Needs both LASTFM_API_KEY and LASTFM_SHARED_SECRET. The desktop keeps each user's
session key encrypted locally; neither credential reaches the client.
Coordination and signaling only. It never proxies or streams media. Endpoints and socket messages are documented in Listening Parties.
D1-backed, storing one canonical Orchard song row per track.
npm run d1:create
# copy the printed database_id into wrangler.jsonc
npm run d1:migrate:localYouTube and YouTube Music resolve directly from a video id. Apple Music and Deezer resolve
through public lookup APIs. TIDAL resolves through the official API when credentials are
configured. Spotify stays a branded search link, because Spotify's catalog search API is
blocked for this application. Set ARTWORK_API_ORIGIN to a compatible Apple Music artwork
service to fill in missing cover art.
The most involved one. It stores anonymous report identities and conversations in D1, keeps screenshots in a private R2 bucket, opens one private Discord forum thread per report, and mirrors each report description into a public-safe GitHub issue.
npx wrangler d1 create orchard-support
npx wrangler r2 bucket create orchard-support-screenshotsSet SUPPORT_URL and GITHUB_REPOSITORY in wrangler.jsonc. Attribution uses a GitHub App
with Device Flow enabled and read/write access to Issues; only the app's public client
id goes in GITHUB_CLIENT_ID. The client secret and private key are never added to
Orchard, because the desktop flow does not use either.
Never commit ids, bot tokens, or local .dev.vars files.
/convert.gif?url=<encoded Apple artwork MP4 URL>
The worker validates input, authenticates to the conversion service, streams its response,
and caches successful artwork at the edge. Actual conversion runs on a separate server
(services/artwork-converter/). Worker and converter share a random token, stored as a
worker secret. Set CONVERTER_URL in wrangler.jsonc.
curl -sG 'https://<worker>/artist' \
--data-urlencode 'artist=SZA' \
--data-urlencode 'album=SOS' \
--data-urlencode 'youtubeBrowseId=UC...'Orchard sends an artist name and a known album. The worker only returns a genre when the album belongs to the same iTunes artist id, which is what stops two artists sharing a name from being merged. Confirmed mappings are cached in D1.
Serves official artist pack content from workers/artist-packs/content/. See
Artist Packs.
Workers with a test/ directory run their tests through their own npm scripts. The support
worker uses Vitest.
Every one of these depends on an upstream that can change without notice. When a feature stops working, the worker is usually reporting an upstream problem rather than having one. See Troubleshooting.
Orchard is licensed AGPL-3.0-or-later from 4.0.0 onward. Copyright © 2025–2026 SFG545. Orchard is not affiliated with or endorsed by YouTube or Google.
Using Orchard
Features
- Playback and Queues
- Explicit and Age-Restricted Tracks
- Best Mix
- Smart Crossfade
- Audio Engine
- Song Cache
- Library and Discovery
- Replay
- Listening Parties
- Orchard Connect
- Integrations
- Appearance
- Artist Packs
Mobile
Development
- Architecture
- Building from Source
- Native Audio Analyzer
- Cloudflare Workers
- Releases and Updates
- Contributing
Policy