New in the Reading Room: book recommendations from website visitors
A new Reading Room feature: website visitors can now recommend a book without a GitHub account. A Cloudflare Worker files a GitHub issue, and adding the approved label shelves it for everyone.
The Reading Room is a first-person 3D room you can walk through, built in Three.js and hosted on GitHub Pages — books on the shelves, a record in the corner, a table by the door. Click a spine to pull it out; the ones on the reading table are whatever I'm in the middle of.
Until now the table only held my own books. This update adds the room's first way for website visitors to put something on it: a book recommendation.
Links
- Room: readingroom.rr2.dev
- Repo: github.com/r-r-2/thereadingroom
- Sample recommendation: github.com/r-r-2/thereadingroom/issues/19
New feature: Website visitors can recommend a book without a GitHub account. The form files an issue; adding the approved label shelves it on the table for everyone. First real book through the pipe: The Secret, recommended by Swaa (#19).
Why add it this way
The room is static GitHub Pages. Website visitors shouldn't need an account, and unreviewed titles shouldn't land in the repo on their own. Issues are the queue; guestbook.js stays the source of truth.
How the feature works
- Visitor writes in the room. Quill / sign / table opens a form (title, author, name, why). Open Library can attach an ISBN and cover. Submit POSTs to a Cloudflare Worker — not to GitHub from the browser.
- Worker files an issue. It validates the fields, applies abuse limits (20 per hashed IP, 3/min burst, no links, duplicate/flood guards), and opens an issue labeled
recommendation, with the payload in a<!-- rr-guest -->JSON block. Secrets stay in Actions and get pushed to the Worker on deploy; the static page never sees them. - The submitter sees it right away. Their book appears on the table in this browser, with an "awaiting approval" tag (
localStorage). Other visitors do not see it on the table until it's shelved — only in the ledger's Waiting page. - Approve = shelve. Open the issue, add the
approvedlabel. The shelve Action appends the entry toguestbook.js, commits tomain, and closes the issue. Pages redeploys; the tag comes off for everyone. - Decline = close. Close the issue without
approved. The submitter's local copy is dropped on their next visit.
What powers it
- GitHub Issues — the moderation queue. Each recommendation is an issue (
recommendationlabel). Approve by addingapproved; decline by closing without it. - Cloudflare Worker — the public write path. Anonymous POST from the room, validation and abuse limits, then files the issue with a PAT. The static page never talks to GitHub.
- GitHub Actions — two workflows. One deploys the Worker (and pushes Actions secrets into Cloudflare). The other watches for
approvedand commits the entry toguestbook.js.