mirror of
https://github.com/prdlk/x-bookmarks-rss.git
synced 2026-08-02 17:31:42 +00:00
70 lines
2.4 KiB
Markdown
70 lines
2.4 KiB
Markdown
# X Bookmarks → RSS
|
|
|
|
A tiny [Hono](https://hono.dev) app on Cloudflare Workers that turns your X (Twitter)
|
|
bookmarks into a live RSS 2.0 feed. Uses the official X API v2 (OAuth 2.0 user context).
|
|
State lives in a single **D1** database.
|
|
|
|
Personal/single-user: the feed is unguarded (`/feed.xml`, no key). Bookmarks are stored in
|
|
D1 and accumulate, so tweets stay in your feed even after they scroll out of X's 100-item
|
|
bookmarks API window.
|
|
|
|
## How it works
|
|
|
|
- There is **no login route**. You seed one OAuth2 refresh token into D1 once; from then on
|
|
the app refreshes the access token itself on every sync (refresh tokens rotate and the new
|
|
one is written straight back to D1).
|
|
- `GET /feed.xml` — if the last sync is older than `SYNC_TTL_SECONDS`, it refreshes the
|
|
access token, pages through your bookmarks, and upserts them into D1; then it renders RSS
|
|
from **all** stored rows (newest first). Sync failures are swallowed — the feed still
|
|
serves what's already stored.
|
|
|
|
## Setup
|
|
|
|
### 1. Create the D1 database
|
|
|
|
```sh
|
|
npm install
|
|
wrangler d1 create x-bookmarks-db # paste the printed database_id into wrangler.jsonc
|
|
npm run db:init # applies schema.sql to the remote DB
|
|
```
|
|
|
|
### 2. Set secrets (used to refresh the token)
|
|
|
|
```sh
|
|
wrangler secret put X_CLIENT_ID
|
|
wrangler secret put X_CLIENT_SECRET
|
|
```
|
|
|
|
`SYNC_TTL_SECONDS` (default 900) and `MAX_ITEMS` (default 100, items pulled per sync) are
|
|
plain vars in `wrangler.jsonc`.
|
|
|
|
### 3. Seed your refresh token
|
|
|
|
You need one OAuth2 refresh token with the `tweet.read users.read bookmark.read
|
|
offline.access` scopes (this is the only step that requires a one-time authorization — every
|
|
sync afterward is automatic). Once you have it:
|
|
|
|
```sh
|
|
export X_CLIENT_ID=... # same values as the secrets above
|
|
export X_CLIENT_SECRET=...
|
|
scripts/seed-token.sh "<your-refresh-token>"
|
|
```
|
|
|
|
The script validates the token, captures the rotated token, and writes `refresh_token` +
|
|
`user_id` into the D1 `meta` table.
|
|
|
|
### 4. Deploy & subscribe
|
|
|
|
```sh
|
|
wrangler deploy
|
|
```
|
|
|
|
Add `https://<your-worker>.workers.dev/feed.xml` to your RSS reader.
|
|
|
|
## Notes
|
|
|
|
- Refresh tokens rotate on every use and are written back to D1 immediately.
|
|
- If syncs start failing (token revoked), re-run `scripts/seed-token.sh` with a fresh token.
|
|
- The feed is unguarded by design (personal use). Don't host it where you'd mind it being
|
|
readable, or re-add a key check.
|