Building a Self-Serve Streaming Login Code Portal for Friends & Family
I've been raising an Apple Family for a while now, but as of late I'm seeing a lot more "I'm sorry"s in the "Can you send me the streaming code?" text.
I get a few texts per week asking for this code, and while it's nice lording my magnamity as their only tether to the final season of Stranger Things, I know it's annoying for them too.
So I am here to tell you about my Christmas gift to these fine people ranging in age from 16-72, who all live in a big house with me so as to not break terms and/or conditions.
System Overview
Gmail Label → Gmail Watch → Google Pub/Sub
→ OIDC-authenticated push
→ Next.js API Route
→ Postgres (fresh/used)
→ UI (real + decoy codes)
Step 1: Gmail → Pub/Sub
- I made a dedicated Gmail label for streaming logins based on exact match sender & subject attributes.
- Using Gmail's watch API, send a Pub/Sub notification any time a message is marked with that label.
The push subscription uses Google OIDC tokens, which are verified server-side to ensure incoming data security. The issuer must be google, the signature must be correct, and the audience matches my expectation. Only Gmail and Pub/Sub push can hit this endpoint.
Step 2: Code Extraction
When the webhook fires, my Next.js API route:
- Grabs the newest labeled message
- Parses the provider (Disney+, HBO Max, etc.)
- Extracts a valid six-digit login code
- Records it in Postgres with a timestamp and a “used” flag for clearing the page after expiration or use
Only the newest unexpired, unused code is eligible for display.
Step 3: The Decoy Wall
Misdirection as a service! The UI has a wall of streaming services, each with a six-digit code. There's only one real code, and the family member joining knows the right one. This is, of course, not perfect, but a fun little wrinkle to add for security's sake.
The UI displays a list of streaming services. Each service card contains:
- a service label
- “Latest login code”
- timestamp
- a six-digit number
Only one is the Real McCoy, the rest are decoys so I can still have one way to annoy people who need these codes from me. The idea is that a malicious actor wouldn't know which code was accurate, and ideally a friend triggering this would get their first.
Step 4: Expiration & Invalidation
Two important safety rules:
- 15-minute TTL: codes are wiped after 15 minutes of creation.
- Clear-all: When someone retrieves their code and taps “Clear all,” the server marks the code as used and wipes it from Postgres.
No client-side hiding tricks. Actual server-side revocation.
Why This Exists
This was a quick little chore for fun, and was mostly rooted in empathy for not wanting people to feel bad asking for something. This took a few hours and ended up being a fun learning experience.
The final experience is simple: a friend/family member visits a private URL, clicks their streaming service, and gets the code immediately. Clear it when you're done just for security's sake. Nobody sends a text or feels like a nuisance.
Closing Thoughts
Some of the projects I'll always remmeber the most are those I do outside of work that are truly meaningful to me. This is not that.
This was a fun one to make my friends' lives easier, stopping me from getting distracted, and share a learning experience that I hope doesn't provoke the streaming services to tighten security further.
Cool to check out Pub/Sub and Gmail's watch API! Looking forward to using these again soon.
