this string has no description
0
readme.md
1# teal.fm → Bluesky Bio Updater
2
3A Cloudflare Worker that automatically updates your Bluesky bio with your currently playing track from [teal.fm](https://teal.fm), and removes it when the status expires.
4
5## How it works
6
7On a schedule (every 1 minutes by default), the Worker:
8
91. Fetches your `fm.teal.alpha.actor.status` record from your PDS
102. If a track is active and not expired, appends a "Currently listening to: `{track}` by `{artist}`" line to your bio
113. If nothing is playing (or the status has expired), removes the line cleanly
124. Skips the Bluesky API call entirely if the bio hasn't changed
13
14Session tokens and the last injected bio line are cached in KV to minimise unnecessary API calls.
15
16## Prerequisites
17
18- A Cloudflare account
19- A [teal.fm](https://teal.fm) account with an active PDS status record
20- A Bluesky account with an [app password](https://bsky.app/settings/app-passwords)
21
22## Setup
23
24### 1. Create a KV namespace
25
261. Go to **Workers & Pages → KV** in the Cloudflare dashboard
272. Click **Create a namespace**, name it `TEALFM_BIO_KV`, and save
28
29### 2. Create the Worker
30
311. Go to **Workers & Pages → Create**
322. Choose **Create Worker**, give it a name, and click **Deploy**
333. Click **Edit Code** and paste in the contents of `src/index.js`
344. Before saving, update the two constants at the top of the file to point to your own PDS and DID:
35
36```js
37const STATUS_URL =
38 "https://your-pds.example.com/xrpc/com.atproto.repo.getRecord" +
39 "?repo=did:plc:yourdidhere" +
40 "&collection=fm.teal.alpha.actor.status" +
41 "&rkey=self";
42
43const BSKY_PDS = "https://your-pds.example.com";
44```
45
465. Click **Deploy**
47
48### 3. Bind the KV namespace
49
501. In your Worker, go to **Settings → Bindings**
512. Click **Add**, choose **KV Namespace**
523. Set the variable name to `TEALFM_BIO_KV` and select the namespace you created in step 1
534. Click **Save**
54
55### 4. Add secrets
56
571. In your Worker, go to **Settings → Environment Variables**
582. Add the following as **secrets** (click **Encrypt**):
59
60| Variable name | Value |
61|---------------|-------|
62| `BSKY_IDENTIFIER` | Your Bluesky handle or DID |
63| `BSKY_PASSWORD` | Your Bluesky app password |
64
653. Click **Save**
66
67### 5. Set the cron trigger
68
691. In your Worker, go to **Settings → Triggers**
702. Under **Cron Triggers**, click **Add Cron Trigger**
713. Enter `*/1 * * * *` to run every 1 minutes
724. Click **Save**
73
74## Manual trigger
75
76You can trigger a run at any time by visiting your Worker's `/run` endpoint in a browser:
77
78```
79https://your-worker.your-subdomain.workers.dev/run
80```
81
82## KV storage
83
84The Worker uses two KV keys:
85
86| Key | Purpose |
87|-----|---------|
88| `bsky_session` | Cached Bluesky session token (TTL: 90 min) |
89| `bio_last_np_line` | The exact now-playing line last injected into your bio (TTL: 1 hr) |
90
91The `bio_last_np_line` key lets the Worker reliably strip the previous line even if you manually edit your bio between runs.
92
93## Bio format
94
95When a track is playing, the following line is appended to your existing bio, separated by a blank line:
96
97```
98Currently listening to: Track Name by Artist Name
99```
100
101When nothing is playing, the line is removed and your original bio is restored exactly.
102
103## Configuration reference
104
105| Constant | Default | Description |
106|----------|---------|-------------|
107| `NOW_PLAYING_PREFIX` | `"Currently listening to: "` | Prefix used to identify and strip the injected line |
108| `KV_SESSION_KEY` | `"bsky_session"` | KV key for the cached session |
109| `KV_LAST_LINE_KEY` | `"bio_last_np_line"` | KV key for the last injected line |
110| Cron schedule | `*/2 * * * *` | How often the Worker runs (set under Settings → Triggers) |