Gaming data integration
Whether Sway can extend from social media into Twitch and Roblox, what data is actually obtainable, and what it would take to build.
No code exists for either platform. Every capability claim on these pages carries a source and a confidence level. Where something could not be verified it is labelled Unverified rather than smoothed over — read those as open engineering questions, not as features.
The three findings that matter
1. Sway has no OAuth, anywhere
The brief assumed we would reuse an existing OAuth path. There isn't one. All three current integrations connect by harvesting browser cookies from an in-app WebView and posting the serialised cookie string to the API.
| What we assumed | What is actually there |
|---|---|
| OAuth authorisation-code flow per provider | CookieWebView loads the platform login page and waits for a session cookie to appear |
| Token store with refresh | UserSocialAccount.cookie — one nullable String, no expiresAt, no refresh token, no scope |
| Encryption at rest | None. The cookie is written straight to the column. |
| Re-auth on expiry | Manual. Session death sets complete: false, cookie: null and fires a "reconnect required" alert. |
There is a GOOGLE_REDIRECT_URI in apps/api/wrangler.jsonc
pointing at /social-accounts/youtube/callback — that route
does not exist. It is dead config from an abandoned OAuth attempt,
as is the unused YoutubeAccountSchema with its accessToken
and refreshToken fields. Neither should be mistaken for a
foundation to build on.
Twitch and Roblox are genuine OAuth providers. This project would build the first real OAuth path in the codebase, including the token store, the refresh job, and the encryption precedent. That is foundational work the original scope did not account for.
2. The data model is post-shaped, end to end
Every unit of analysis in Sway is a Social Post, authored by a Social Author, carrying text or media an LLM can read. The post workflow rejects anything else outright:
const hasContent = preparedPost.post.text
|| preparedPost.post.images.length
|| preparedPost.post.audio;
if (!hasContent) return { success: false, error: 'Post has no content' };
"Played Fortnite for 90 minutes" has no text, no images and no audio. It would be rejected on the first pass. Gaming's native units — sessions, playtime, spend, friends, chat — have no model at all:
Play session
No table. Nearest is UserPostInteraction, which is keyed to a Post and has no duration.
Playtime / screen time
No table. The time_per_day: '1:20' in the weekly report is a hardcoded fixture with nothing behind it.
Spend / purchases
No table. Subscription is Sway's own Paddle billing — unrelated. No currency or transaction model exists.
Friends / social graph
No table. Author.followers is a creator vanity count, not the child's graph.
Chat / DMs
No table. TrustMessage is authored guidance copy, not inbound messages.
Moderation events
No table. Trust is derived only from classification probability against a threshold.
It is not all bad news. SocialPlatform is a table,
not an enum — adding twitch and roblox needs
no migration. Author is already
platform-scoped (youtube:UC… → twitch:<id>).
Alerts and notifications are fully platform-agnostic. The scheduler's
quota and priority logic fans out over a plain string[] of
platforms and does not care what they are.
3. The obtainable data is not the data parents want
Both platforms expose stated preference and account posture — who you follow, what you have chosen, how your settings are configured. Both are structurally poor at live behaviour and conversation, which is where the documented harm actually is. That asymmetry is the central product problem, and it is a design problem before it is an engineering one.
The consequence: the differentiated Sway signal here is change, not volume — a new unknown friend, a first mature-rated experience, a settings downgrade, a spend spike. Not "here are their messages", which we will not be able to offer.
How Sway ingests social data today
Everything a gaming integration does has to attach to this pipeline, so it is worth understanding before reading the integration plan.
cookie IS NOT NULL AND btrim(cookie) <> '',
so an OAuth-token account with a null cookie is invisible to the
scheduler.
Why this matters commercially
Confirmed Ofcom, Children and parents: media use and attitudes, June 2025. Gaming is the largest unmonitored surface in the Sway core age band.
How to read these docs
| If you are… | Read |
|---|---|
| An engineer scoping a spike | Twitch and Roblox capabilities, then the integration plan |
| A designer | Dashboard prototype — it derives from the current social dashboard, with every deviation annotated |
| Deciding whether to fund this | This page, then compliance & risk, then open questions |
| Trying to understand the platforms | What these platforms are |
Confidence labels used throughout
| Confirmed | Stated in official platform documentation, which was fetched and read |
| Likely | Credible secondary source — changelog, reputable analysis, well-sourced community answer |
| Unverified | Believed but not confirmed. Needs an engineering spike before anyone plans around it. |