Small serverless helpers for cv.fairviewlogic.io. Each helper is a self-contained Lambda deployed via SST v3 (Ion).
| Helper | Endpoint | Purpose |
|---|---|---|
reading-collector |
Lambda function URL | Accepts a URL from Mark's phone (via iOS Shortcut or web form) and commits it to data/reading.yaml in the cv site, which triggers a rebuild |
- Node 22+ (SST CLI + config)
- Go 1.24+ (Lambda runtimes)
- AWS credentials for
sst deploy(region:eu-west-2)
npm install # first time
npx sst dev # live Lambda proxy — invokes local Go code on real AWS eventsnpx sst secret set SharedSecret <secret> # once, per stage
npx sst secret set GitHubToken <fine-grained-PAT> # once, per stage — scoped to cv.fairviewlogic.io, Contents: R/W
npx sst deploy # to the "dev" stage (default)
npx sst deploy --stage production # for the live stageDeploy prints the function URL as readingCollectorUrl. That URL is what the phone and web form both talk to.
helpers/
├── sst.config.ts # SST v3 stack definition
├── package.json
├── tsconfig.json
└── functions/
└── reading-collector/
├── go.mod
├── main.go # handler + method router
├── title.go # URL → title, with fallback
├── github.go # GitHub Contents API (get/put/retry)
├── entries.go # YAML schema + prepend
└── web/
└── reading.html # embedded static form (served on GET /)
The Lambda function URL is public but unlisted. Auth is a single shared secret header (X-Shared-Secret) passed on every request. The secret is stored in AWS SSM Parameter Store via sst.Secret and linked to the function at deploy time — never in code.
- Web form: prompts once, stores the secret in
localStorage. A "Forget secret" link clears it. A 401 response wipes it and re-prompts on next submit. - iOS Shortcut: inlines the secret into the request headers. It lives in your iCloud Shortcuts library; nothing on-device outside the Shortcuts app can read it.
The Lambda serves the form itself on GET /. Just bookmark the function URL — on first use you'll get a prompt() for the secret, paste it once, submit URLs after that. No CORS setup needed since form and POST share an origin.
One-time setup, then "Send to reading list" appears in the Share Sheet in Safari, Reddit, Hacker News apps, anywhere that offers URL sharing.
Setup:
- Open Shortcuts app → + to create a new Shortcut.
- Rename it "Send to reading list" (top of screen).
- Tap the (i) info button:
- Toggle Show in Share Sheet ON.
- Under Share Sheet Types, deselect everything except URLs and Safari web pages. (Keeps it out of unrelated share menus.)
Actions — add in this order:
-
Get Contents of URL
- URL: your Lambda function URL (paste it verbatim)
- Method: POST
- Headers (tap Add new header twice):
Content-Type→application/jsonX-Shared-Secret→ your shared secret (paste it verbatim)
- Request Body: JSON
- Add field:
url→ tap the field value, choose the magic variable Shortcut Input from the suggestion bar.
- Add field:
-
Get Dictionary Value (so we can pull the title out of the response for the notification)
- Get: Value
- Key:
title - Dictionary: Contents of URL (auto-suggested — it's the previous action's output)
-
Show Notification
- Title:
Reading list - Body: type "Added: " then insert the magic variable Dictionary Value.
- Title:
Try it:
- Run the Shortcut once from inside the Shortcuts app to make sure it works (it'll use whatever URL happens to be the fallback — either paste a test URL into the "Shortcut Input" prompt or ignore the notification).
- Open Safari, go to any article, hit Share → scroll to find your Shortcut. Tap it. The notification should pop within a couple of seconds with the article title.
Optional polish:
- Add to home screen: in the Shortcut list, long-press → Share → Add to Home Screen. Gives you a one-tap send button for a URL currently on the clipboard.
- Silent mode: replace "Show Notification" with "Play Haptic" if you'd rather not see the notification.
- Error handling: add an "If" action after step 2 checking whether the dictionary has an
errorkey; if so, show that instead. Rarely needed once the pipeline is up.
Debugging checklist:
- No Shortcut in the Share Sheet? Long-press the Share Sheet button → Edit Actions → make sure it's enabled.
- Nothing happens on tap? Run the Shortcut manually from inside the app — errors surface as a toast there but are silent in the Share Sheet.
- Notification says "Added: " with a blank title? The Lambda succeeded but the title fetch fell through to fallback. Bug on the target site, not on you.
- 401 or other errors? Load the function URL in Safari — you'll see the web form, which gives you a friendlier error state to debug from.