From 7f5a476574914a0aa266db784ea28a3dd194d3d4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 4 Jan 2026 14:24:10 +0000 Subject: [PATCH 01/16] Initial plan From 14016dd839d9638660bd6de357fc1e9689120684 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 4 Jan 2026 14:28:53 +0000 Subject: [PATCH 02/16] docs: add youtube integration plan Co-authored-by: Geczy <1036968+Geczy@users.noreply.github.com> --- TechnicalOverview.md | 80 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/TechnicalOverview.md b/TechnicalOverview.md index 743e5cd5..d6b353e8 100644 --- a/TechnicalOverview.md +++ b/TechnicalOverview.md @@ -126,6 +126,86 @@ Secrets management uses Doppler, and injects into every Docker build on the fly. ![image](https://user-images.githubusercontent.com/1036968/235396718-f4cb5929-01f2-4937-ab7c-d7695fb931b6.png) +## YouTube integration implementation plan + +### Objectives and success criteria + +- Deliver feature parity (or clear MVP subset) for streamers who broadcast on YouTube Live in addition to Twitch. +- Keep the existing Twitch stack stable by isolating changes behind a provider abstraction. +- Preserve latency-sensitive flows (game events → chat/output) with <5s added delay, accounting for YouTube chat polling intervals. +- Track adoption via number of linked YouTube channels, active live chats, and command success/error rates. + +### Scope and phased rollout + +1. **Foundation (P0)**: OAuth + channel linkage, data model readiness, secrets/infra wiring, basic health checks. +2. **Chat + stream lifecycle (P1)**: Bidirectional chat bridge (commands/responses), live/offline detection, moderation/error handling. +3. **Feature parity (P2)**: Dota-driven automations (predictions/polls, overlays, auto-messages), localization, moderator controls. +4. **Hardening & rollout (P3)**: Observability, rate-limit tuning, canary rollout to a small cohort, documentation and support. + +### Architecture approach + +- **Provider abstraction**: Introduce a `StreamingProvider` interface in `shared-utils` to unify auth tokens, chat send/receive, and stream status checks. Keep Twitch implementations intact and add a YouTube implementation that plugs into the same sockets used by `packages/twitch-chat`. +- **New packages/services**: + - `packages/youtube-chat`: Mirrors `twitch-chat` but uses YouTube LiveChat APIs for ingest and message dispatch; reuses shared command handlers where possible. + - `packages/youtube-events`: Mirrors `twitch-events` for stream lifecycle and channel updates (using `liveBroadcasts`, `videos`, `subscriptions` APIs). Emits the same internal events consumed by downstream services. +- **Sockets and API surface**: Extend existing socket events to include `provider` metadata so frontends and other services can route messages to the correct transport without duplicating handlers. +- **Deployment**: Add Docker targets and compose entries mirroring Twitch services; gate startup on presence of Google credentials to avoid breaking existing environments. + +### Authentication and permissions + +- Create a Google Cloud project + OAuth client (web app) and store credentials via Doppler alongside Twitch secrets. +- Scopes: `https://www.googleapis.com/auth/youtube.readonly` (live metadata), `.../youtube.force-ssl` (chat read/write), `.../youtube.channel-memberships.creator` if membership-specific features are needed. Keep scope set minimal for MVP. +- Flow: front-end initiates Google OAuth; Supabase `accounts` table already supports generic providers—store `provider: 'google' | 'youtube'` with `refresh_token`, `access_token`, `expires_at`, `scope`. +- Token refresh: implement Google OAuth refresh logic in `shared-utils` alongside existing Twitch token helpers; add retry/backoff and revocation detection. + +### Data model and configuration + +- Users table already has a `youtube` field (channel id/url). Enforce population during linkage; validate channel ownership by comparing OAuth channel id. +- Add configuration fields (Supabase) for YouTube-specific toggles: chat language fallback, poll enablement, command prefixes, rate-limit ceilings. +- Add tables/rows for live chat state if needed (e.g., `youtube_live_chats` storing `liveChatId`, `nextPageToken`, `pollIntervalMs`, last seen message timestamp) to avoid duplicate processing. + +### Chat ingestion and command handling (P1) + +- Use `liveBroadcasts.list` to find the active broadcast and obtain `liveChatId`. +- Poll `liveChatMessages.list` respecting `pollingIntervalMillis` and page tokens; store `messageId`/timestamp to prevent replays. +- Normalize inbound messages into the existing command bus (user id, channel id, roles, message text). Map YouTube roles to Twitch equivalents (owner → broadcaster, moderator → moderator, member → sub, none → viewer). +- Outbound messages: use `liveChatMessages.insert`; centralize rate limiting (YouTube default ~11,000 messages/day) and fall back to compact messaging when near limits. +- Moderation: handle errors for slow mode, members-only, or chat disabled; surface disable reasons through the same cache/telemetry used in Twitch (`disable_notifications` equivalents). + +### Stream lifecycle and events (P1/P2) + +- Detect live/offline via `liveBroadcasts.list` and `videos.list` status; emit internal `stream.online`/`stream.offline` events matching the payload shape from `twitch-events`. +- Track title/category changes via `videos.update` or polling; propagate to overlays and chat announcements. +- Implement health checks (cron) similar to Twitch subscription health: verify token validity, channel linkage, and active liveChatId presence; auto-heal by re-fetching live broadcast. + +### Feature parity mapping (P2) + +- **Predictions/bets**: Use YouTube Polls (if available) or emulate via chat messages + reaction parsing; keep Supabase `advanced_bets` logic but flag provider to avoid mixing metrics. +- **Auto chat commands**: Reuse existing handlers (MMR, notable players, items) with provider-aware transport. +- **Overlays and sockets**: Ensure socket payloads include provider/channel identifiers so overlays work cross-platform without duplicating UI logic. +- **Localization**: Reuse existing i18n files; add YouTube-specific system messages (errors, rate-limit notices). + +### Observability, reliability, and limits (P3) + +- Metrics: poll latency, messages processed/sent, error codes per API, rate-limit headroom, per-channel disable events. +- Logging: standardize Winston context fields (`provider`, `channelId`, `liveChatId`, `error.code`). +- Alerts: trigger when polling falls behind (timestamp gap), repeated auth failures, or message send failures > threshold. +- Quotas: track Google API quotas; add circuit breakers to pause non-essential features when nearing limits. + +### Rollout plan + +- Internal dogfood on a test channel; record flows and log volumes. +- Beta allowlist (Supabase flag) to enable YouTube per user without affecting Twitch users. +- Gradually expand cohort; monitor metrics and support channels. +- Documentation: add setup guide (creating Google credentials, linking account), update README and dashboard onboarding once stable. + +### Risks and mitigations + +- **Higher latency from polling**: keep Dota-triggered messages concise, allow configurable batching, and pre-emptively refresh `liveChatId` on reconnect. +- **Quota exhaustion**: cache broadcast/channel metadata aggressively; avoid redundant `liveChatMessages.insert` retries. +- **Token revocation**: health checks plus UI banner; disable features gracefully and request re-auth. +- **Feature gaps vs. Twitch**: define MVP (chat commands + stream status) and stage advanced features after stability metrics are green. + ## Technical Overview ### Internal microservices From ee3fc75a179576c59433b62ee88d677817bf61b0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 4 Jan 2026 14:29:55 +0000 Subject: [PATCH 03/16] docs: clarify youtube plan details Co-authored-by: Geczy <1036968+Geczy@users.noreply.github.com> --- TechnicalOverview.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/TechnicalOverview.md b/TechnicalOverview.md index d6b353e8..f202c6c3 100644 --- a/TechnicalOverview.md +++ b/TechnicalOverview.md @@ -154,8 +154,8 @@ Secrets management uses Doppler, and injects into every Docker build on the fly. ### Authentication and permissions - Create a Google Cloud project + OAuth client (web app) and store credentials via Doppler alongside Twitch secrets. -- Scopes: `https://www.googleapis.com/auth/youtube.readonly` (live metadata), `.../youtube.force-ssl` (chat read/write), `.../youtube.channel-memberships.creator` if membership-specific features are needed. Keep scope set minimal for MVP. -- Flow: front-end initiates Google OAuth; Supabase `accounts` table already supports generic providers—store `provider: 'google' | 'youtube'` with `refresh_token`, `access_token`, `expires_at`, `scope`. +- Scopes: `https://www.googleapis.com/auth/youtube.readonly` (live metadata), `https://www.googleapis.com/auth/youtube.force-ssl` (chat read/write), `https://www.googleapis.com/auth/youtube.channel-memberships.creator` if membership-specific features are needed. Keep scope set minimal for MVP. +- Flow: front-end initiates Google OAuth; Supabase `accounts` table already supports generic providers—store `provider: 'youtube'` with `refresh_token`, `access_token`, `expires_at`, `scope`, and channel metadata to disambiguate from any other Google-linked features. - Token refresh: implement Google OAuth refresh logic in `shared-utils` alongside existing Twitch token helpers; add retry/backoff and revocation detection. ### Data model and configuration @@ -169,7 +169,7 @@ Secrets management uses Doppler, and injects into every Docker build on the fly. - Use `liveBroadcasts.list` to find the active broadcast and obtain `liveChatId`. - Poll `liveChatMessages.list` respecting `pollingIntervalMillis` and page tokens; store `messageId`/timestamp to prevent replays. - Normalize inbound messages into the existing command bus (user id, channel id, roles, message text). Map YouTube roles to Twitch equivalents (owner → broadcaster, moderator → moderator, member → sub, none → viewer). -- Outbound messages: use `liveChatMessages.insert`; centralize rate limiting (YouTube default ~11,000 messages/day) and fall back to compact messaging when near limits. +- Outbound messages: use `liveChatMessages.insert`; centralize rate limiting against YouTube Live Chat quota units (per current API docs) and fall back to compact messaging when near limits. - Moderation: handle errors for slow mode, members-only, or chat disabled; surface disable reasons through the same cache/telemetry used in Twitch (`disable_notifications` equivalents). ### Stream lifecycle and events (P1/P2) From a71b5dad006aa622b8672c8f741e8c08f8811e4c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 4 Jan 2026 14:30:29 +0000 Subject: [PATCH 04/16] docs: tighten youtube plan guidance Co-authored-by: Geczy <1036968+Geczy@users.noreply.github.com> --- TechnicalOverview.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/TechnicalOverview.md b/TechnicalOverview.md index f202c6c3..dcf019b2 100644 --- a/TechnicalOverview.md +++ b/TechnicalOverview.md @@ -154,7 +154,7 @@ Secrets management uses Doppler, and injects into every Docker build on the fly. ### Authentication and permissions - Create a Google Cloud project + OAuth client (web app) and store credentials via Doppler alongside Twitch secrets. -- Scopes: `https://www.googleapis.com/auth/youtube.readonly` (live metadata), `https://www.googleapis.com/auth/youtube.force-ssl` (chat read/write), `https://www.googleapis.com/auth/youtube.channel-memberships.creator` if membership-specific features are needed. Keep scope set minimal for MVP. +- Scopes: `https://www.googleapis.com/auth/youtube.readonly` (live metadata), `https://www.googleapis.com/auth/youtube.force-ssl` (chat read/write—needed instead of broader `.../youtube`), `https://www.googleapis.com/auth/youtube.channel-memberships.creator` if membership-specific features are needed. Re-evaluate if a narrower live-stream scope (e.g., `youtube.liveBroadcast`) is sufficient before requesting broader access. - Flow: front-end initiates Google OAuth; Supabase `accounts` table already supports generic providers—store `provider: 'youtube'` with `refresh_token`, `access_token`, `expires_at`, `scope`, and channel metadata to disambiguate from any other Google-linked features. - Token refresh: implement Google OAuth refresh logic in `shared-utils` alongside existing Twitch token helpers; add retry/backoff and revocation detection. @@ -167,7 +167,7 @@ Secrets management uses Doppler, and injects into every Docker build on the fly. ### Chat ingestion and command handling (P1) - Use `liveBroadcasts.list` to find the active broadcast and obtain `liveChatId`. -- Poll `liveChatMessages.list` respecting `pollingIntervalMillis` and page tokens; store `messageId`/timestamp to prevent replays. +- Poll `liveChatMessages.list` respecting `pollingIntervalMillis` and page tokens; store `messageId`/timestamp with a short TTL (24–48h) to prevent replays without unbounded growth. - Normalize inbound messages into the existing command bus (user id, channel id, roles, message text). Map YouTube roles to Twitch equivalents (owner → broadcaster, moderator → moderator, member → sub, none → viewer). - Outbound messages: use `liveChatMessages.insert`; centralize rate limiting against YouTube Live Chat quota units (per current API docs) and fall back to compact messaging when near limits. - Moderation: handle errors for slow mode, members-only, or chat disabled; surface disable reasons through the same cache/telemetry used in Twitch (`disable_notifications` equivalents). @@ -180,7 +180,7 @@ Secrets management uses Doppler, and injects into every Docker build on the fly. ### Feature parity mapping (P2) -- **Predictions/bets**: Use YouTube Polls (if available) or emulate via chat messages + reaction parsing; keep Supabase `advanced_bets` logic but flag provider to avoid mixing metrics. +- **Predictions/bets**: Use YouTube Polls (if available) or emulate via chat messages + reaction parsing (feature-flagged, with documented parsing and error handling). Keep Supabase `advanced_bets` logic but flag provider to avoid mixing metrics. - **Auto chat commands**: Reuse existing handlers (MMR, notable players, items) with provider-aware transport. - **Overlays and sockets**: Ensure socket payloads include provider/channel identifiers so overlays work cross-platform without duplicating UI logic. - **Localization**: Reuse existing i18n files; add YouTube-specific system messages (errors, rate-limit notices). From 414c4918eba8b161b1cb44dc16e8cf3d8e55a102 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 4 Jan 2026 14:31:02 +0000 Subject: [PATCH 05/16] docs: refine youtube quotas and poll plan Co-authored-by: Geczy <1036968+Geczy@users.noreply.github.com> --- TechnicalOverview.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/TechnicalOverview.md b/TechnicalOverview.md index dcf019b2..8bf9aafc 100644 --- a/TechnicalOverview.md +++ b/TechnicalOverview.md @@ -169,7 +169,7 @@ Secrets management uses Doppler, and injects into every Docker build on the fly. - Use `liveBroadcasts.list` to find the active broadcast and obtain `liveChatId`. - Poll `liveChatMessages.list` respecting `pollingIntervalMillis` and page tokens; store `messageId`/timestamp with a short TTL (24–48h) to prevent replays without unbounded growth. - Normalize inbound messages into the existing command bus (user id, channel id, roles, message text). Map YouTube roles to Twitch equivalents (owner → broadcaster, moderator → moderator, member → sub, none → viewer). -- Outbound messages: use `liveChatMessages.insert`; centralize rate limiting against YouTube Live Chat quota units (per current API docs) and fall back to compact messaging when near limits. +- Outbound messages: use `liveChatMessages.insert`; centralize rate limiting against YouTube Data API quota units (default 10,000/day; `liveChatMessages.list` ~5 units, `liveChatMessages.insert` ~50 units per current docs) and fall back to compact messaging when near limits. - Moderation: handle errors for slow mode, members-only, or chat disabled; surface disable reasons through the same cache/telemetry used in Twitch (`disable_notifications` equivalents). ### Stream lifecycle and events (P1/P2) @@ -180,7 +180,7 @@ Secrets management uses Doppler, and injects into every Docker build on the fly. ### Feature parity mapping (P2) -- **Predictions/bets**: Use YouTube Polls (if available) or emulate via chat messages + reaction parsing (feature-flagged, with documented parsing and error handling). Keep Supabase `advanced_bets` logic but flag provider to avoid mixing metrics. +- **Predictions/bets**: YouTube does not expose poll creation via API; offer a manual-prompt flow (announce options in chat and parse reactions/keywords under a feature flag) or disable the feature for YouTube if accuracy is insufficient. Keep Supabase `advanced_bets` logic but flag provider to avoid mixing metrics. - **Auto chat commands**: Reuse existing handlers (MMR, notable players, items) with provider-aware transport. - **Overlays and sockets**: Ensure socket payloads include provider/channel identifiers so overlays work cross-platform without duplicating UI logic. - **Localization**: Reuse existing i18n files; add YouTube-specific system messages (errors, rate-limit notices). From 01b3406ab992bca63e56801a7276399c52a2896c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 4 Jan 2026 14:32:06 +0000 Subject: [PATCH 06/16] docs: add provider contract and compat notes Co-authored-by: Geczy <1036968+Geczy@users.noreply.github.com> --- TechnicalOverview.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/TechnicalOverview.md b/TechnicalOverview.md index 8bf9aafc..70a8d3f8 100644 --- a/TechnicalOverview.md +++ b/TechnicalOverview.md @@ -144,11 +144,11 @@ Secrets management uses Doppler, and injects into every Docker build on the fly. ### Architecture approach -- **Provider abstraction**: Introduce a `StreamingProvider` interface in `shared-utils` to unify auth tokens, chat send/receive, and stream status checks. Keep Twitch implementations intact and add a YouTube implementation that plugs into the same sockets used by `packages/twitch-chat`. +- **Provider abstraction**: Introduce a `StreamingProvider` interface in `shared-utils` to unify auth tokens, chat send/receive, and stream status checks (e.g., `authenticate/refresh`, `getLiveState`, `subscribeToChat`, `sendMessage`, `disconnect`, `mapRoles`). Keep Twitch implementations intact and add a YouTube implementation that plugs into the same sockets used by `packages/twitch-chat`. - **New packages/services**: - `packages/youtube-chat`: Mirrors `twitch-chat` but uses YouTube LiveChat APIs for ingest and message dispatch; reuses shared command handlers where possible. - `packages/youtube-events`: Mirrors `twitch-events` for stream lifecycle and channel updates (using `liveBroadcasts`, `videos`, `subscriptions` APIs). Emits the same internal events consumed by downstream services. -- **Sockets and API surface**: Extend existing socket events to include `provider` metadata so frontends and other services can route messages to the correct transport without duplicating handlers. +- **Sockets and API surface**: Extend existing socket events to include `provider` metadata so frontends and other services can route messages to the correct transport without duplicating handlers. Default provider to `twitch` when omitted and version new events if payload shapes change to keep existing consumers working. - **Deployment**: Add Docker targets and compose entries mirroring Twitch services; gate startup on presence of Google credentials to avoid breaking existing environments. ### Authentication and permissions @@ -169,7 +169,7 @@ Secrets management uses Doppler, and injects into every Docker build on the fly. - Use `liveBroadcasts.list` to find the active broadcast and obtain `liveChatId`. - Poll `liveChatMessages.list` respecting `pollingIntervalMillis` and page tokens; store `messageId`/timestamp with a short TTL (24–48h) to prevent replays without unbounded growth. - Normalize inbound messages into the existing command bus (user id, channel id, roles, message text). Map YouTube roles to Twitch equivalents (owner → broadcaster, moderator → moderator, member → sub, none → viewer). -- Outbound messages: use `liveChatMessages.insert`; centralize rate limiting against YouTube Data API quota units (default 10,000/day; `liveChatMessages.list` ~5 units, `liveChatMessages.insert` ~50 units per current docs) and fall back to compact messaging when near limits. +- Outbound messages: use `liveChatMessages.insert`; centralize rate limiting against YouTube Data API quota units (default 10,000/day; `liveChatMessages.list` and `insert` unit costs to be confirmed against current docs) and fall back to compact messaging when near limits. - Moderation: handle errors for slow mode, members-only, or chat disabled; surface disable reasons through the same cache/telemetry used in Twitch (`disable_notifications` equivalents). ### Stream lifecycle and events (P1/P2) @@ -180,7 +180,7 @@ Secrets management uses Doppler, and injects into every Docker build on the fly. ### Feature parity mapping (P2) -- **Predictions/bets**: YouTube does not expose poll creation via API; offer a manual-prompt flow (announce options in chat and parse reactions/keywords under a feature flag) or disable the feature for YouTube if accuracy is insufficient. Keep Supabase `advanced_bets` logic but flag provider to avoid mixing metrics. +- **Predictions/bets**: Verify whether YouTube exposes poll creation via `liveChatMessages.insert` variants; if unsupported or unreliable, fall back to a manual-prompt flow (announce options in chat and parse reactions/keywords under a feature flag) or disable the feature for YouTube. Keep Supabase `advanced_bets` logic but flag provider to avoid mixing metrics. - **Auto chat commands**: Reuse existing handlers (MMR, notable players, items) with provider-aware transport. - **Overlays and sockets**: Ensure socket payloads include provider/channel identifiers so overlays work cross-platform without duplicating UI logic. - **Localization**: Reuse existing i18n files; add YouTube-specific system messages (errors, rate-limit notices). From ced43822c4620fe4eed52252dc3cf8797e866d29 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 4 Jan 2026 14:33:08 +0000 Subject: [PATCH 07/16] docs: update youtube scopes and quotas Co-authored-by: Geczy <1036968+Geczy@users.noreply.github.com> --- TechnicalOverview.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/TechnicalOverview.md b/TechnicalOverview.md index 70a8d3f8..84640ce9 100644 --- a/TechnicalOverview.md +++ b/TechnicalOverview.md @@ -154,7 +154,7 @@ Secrets management uses Doppler, and injects into every Docker build on the fly. ### Authentication and permissions - Create a Google Cloud project + OAuth client (web app) and store credentials via Doppler alongside Twitch secrets. -- Scopes: `https://www.googleapis.com/auth/youtube.readonly` (live metadata), `https://www.googleapis.com/auth/youtube.force-ssl` (chat read/write—needed instead of broader `.../youtube`), `https://www.googleapis.com/auth/youtube.channel-memberships.creator` if membership-specific features are needed. Re-evaluate if a narrower live-stream scope (e.g., `youtube.liveBroadcast`) is sufficient before requesting broader access. +- Scopes: `https://www.googleapis.com/auth/youtube.readonly` (live metadata), `https://www.googleapis.com/auth/youtube` for chat read/write (Google currently flags `.../youtube.force-ssl` as deprecated), `https://www.googleapis.com/auth/youtube.channel-memberships.creator` if membership-specific features are needed. Re-evaluate if a narrower live-stream scope (e.g., `youtube.liveBroadcast`) is sufficient before requesting broader access. - Flow: front-end initiates Google OAuth; Supabase `accounts` table already supports generic providers—store `provider: 'youtube'` with `refresh_token`, `access_token`, `expires_at`, `scope`, and channel metadata to disambiguate from any other Google-linked features. - Token refresh: implement Google OAuth refresh logic in `shared-utils` alongside existing Twitch token helpers; add retry/backoff and revocation detection. @@ -169,7 +169,7 @@ Secrets management uses Doppler, and injects into every Docker build on the fly. - Use `liveBroadcasts.list` to find the active broadcast and obtain `liveChatId`. - Poll `liveChatMessages.list` respecting `pollingIntervalMillis` and page tokens; store `messageId`/timestamp with a short TTL (24–48h) to prevent replays without unbounded growth. - Normalize inbound messages into the existing command bus (user id, channel id, roles, message text). Map YouTube roles to Twitch equivalents (owner → broadcaster, moderator → moderator, member → sub, none → viewer). -- Outbound messages: use `liveChatMessages.insert`; centralize rate limiting against YouTube Data API quota units (default 10,000/day; `liveChatMessages.list` and `insert` unit costs to be confirmed against current docs) and fall back to compact messaging when near limits. +- Outbound messages: use `liveChatMessages.insert`; centralize rate limiting against YouTube Data API quota units (default 10,000/day). As of Jan 2026 docs: `liveChatMessages.list` ~5 units, `liveChatMessages.insert` ~50 units, `liveBroadcasts.list` ~1 unit per call—update if Google revises quotas. Fall back to compact messaging when near limits. - Moderation: handle errors for slow mode, members-only, or chat disabled; surface disable reasons through the same cache/telemetry used in Twitch (`disable_notifications` equivalents). ### Stream lifecycle and events (P1/P2) @@ -201,7 +201,7 @@ Secrets management uses Doppler, and injects into every Docker build on the fly. ### Risks and mitigations -- **Higher latency from polling**: keep Dota-triggered messages concise, allow configurable batching, and pre-emptively refresh `liveChatId` on reconnect. +- **Higher latency from polling**: keep Dota-triggered messages concise, allow configurable batching, and preemptively refresh `liveChatId` on reconnect. - **Quota exhaustion**: cache broadcast/channel metadata aggressively; avoid redundant `liveChatMessages.insert` retries. - **Token revocation**: health checks plus UI banner; disable features gracefully and request re-auth. - **Feature gaps vs. Twitch**: define MVP (chat commands + stream status) and stage advanced features after stability metrics are green. From 079f68245d289447cbef124b96a3d15ff8547e7b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 4 Jan 2026 14:42:54 +0000 Subject: [PATCH 08/16] docs: add kick integration plan Co-authored-by: Geczy <1036968+Geczy@users.noreply.github.com> --- TechnicalOverview.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/TechnicalOverview.md b/TechnicalOverview.md index 84640ce9..781c8bb5 100644 --- a/TechnicalOverview.md +++ b/TechnicalOverview.md @@ -206,6 +206,17 @@ Secrets management uses Doppler, and injects into every Docker build on the fly. - **Token revocation**: health checks plus UI banner; disable features gracefully and request re-auth. - **Feature gaps vs. Twitch**: define MVP (chat commands + stream status) and stage advanced features after stability metrics are green. +## Kick integration implementation plan (parity with Twitch/YouTube where possible) + +- **Objectives**: Deliver Kick chat/stream parity for the listed Twitch-dependent features: bets open/close, online/offline detection, automatic username change detection, poll/bets overlay, W/L tracking (beyond 12h), and avoiding manual `!resetwl`. +- **Provider model**: Reuse `StreamingProvider` contract; add a Kick implementation with provider-aware sockets defaulting to Twitch for backward compatibility. +- **Auth**: Document Kick OAuth (or token) flow, scopes, and refresh handling; store as `provider: 'kick'` in Supabase `accounts` with channel metadata. +- **Chat + commands**: Map existing chat command handlers to Kick transport; ensure role mapping (broadcaster/mod/moderator/subscriber) and rate-limiting aligned to Kick limits. +- **Bets/Polls**: If Kick exposes programmatic bet/poll APIs, wire analogous calls; otherwise, provide feature-flagged chat-driven fallback and disable overlay triggers when unsupported. +- **Online/offline + username changes**: Poll or subscribe to Kick stream status/user profile updates; emit `stream.online/offline` equivalents and detect display-name changes to update downstream caches. +- **W/L tracking**: Use Kick live-status to bound the window instead of 12h; auto-reset W/L on new session start to remove manual `!resetwl`. +- **Observability**: Add provider-tagged metrics/logging for Kick transport, auth failures, and command success/error rates; health checks to verify channel linkage and live-status detection. + ## Technical Overview ### Internal microservices From cce0b8fa1e5e4642c50452fe1d3019493db7ec3b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 4 Jan 2026 14:43:46 +0000 Subject: [PATCH 09/16] docs: clarify kick objectives wording Co-authored-by: Geczy <1036968+Geczy@users.noreply.github.com> --- TechnicalOverview.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/TechnicalOverview.md b/TechnicalOverview.md index 781c8bb5..4ad8d084 100644 --- a/TechnicalOverview.md +++ b/TechnicalOverview.md @@ -208,10 +208,10 @@ Secrets management uses Doppler, and injects into every Docker build on the fly. ## Kick integration implementation plan (parity with Twitch/YouTube where possible) -- **Objectives**: Deliver Kick chat/stream parity for the listed Twitch-dependent features: bets open/close, online/offline detection, automatic username change detection, poll/bets overlay, W/L tracking (beyond 12h), and avoiding manual `!resetwl`. +- **Objectives**: Deliver Kick chat/stream parity for core Twitch-dependent features: bets open/close, online/offline detection, automatic username change detection, poll/bets overlay, W/L tracking beyond 12h without manual `!resetwl`, plus the existing chat commands. - **Provider model**: Reuse `StreamingProvider` contract; add a Kick implementation with provider-aware sockets defaulting to Twitch for backward compatibility. - **Auth**: Document Kick OAuth (or token) flow, scopes, and refresh handling; store as `provider: 'kick'` in Supabase `accounts` with channel metadata. -- **Chat + commands**: Map existing chat command handlers to Kick transport; ensure role mapping (broadcaster/mod/moderator/subscriber) and rate-limiting aligned to Kick limits. +- **Chat + commands**: Map existing chat command handlers to Kick transport; ensure role mapping (broadcaster/moderator/subscriber) and rate-limiting aligned to Kick limits. - **Bets/Polls**: If Kick exposes programmatic bet/poll APIs, wire analogous calls; otherwise, provide feature-flagged chat-driven fallback and disable overlay triggers when unsupported. - **Online/offline + username changes**: Poll or subscribe to Kick stream status/user profile updates; emit `stream.online/offline` equivalents and detect display-name changes to update downstream caches. - **W/L tracking**: Use Kick live-status to bound the window instead of 12h; auto-reset W/L on new session start to remove manual `!resetwl`. From 5fb2669e677b783ad31b4fcf1124da5a0ddfcea1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 4 Jan 2026 14:44:29 +0000 Subject: [PATCH 10/16] docs: expand kick integration structure Co-authored-by: Geczy <1036968+Geczy@users.noreply.github.com> --- TechnicalOverview.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/TechnicalOverview.md b/TechnicalOverview.md index 4ad8d084..d02dd2ab 100644 --- a/TechnicalOverview.md +++ b/TechnicalOverview.md @@ -208,14 +208,15 @@ Secrets management uses Doppler, and injects into every Docker build on the fly. ## Kick integration implementation plan (parity with Twitch/YouTube where possible) -- **Objectives**: Deliver Kick chat/stream parity for core Twitch-dependent features: bets open/close, online/offline detection, automatic username change detection, poll/bets overlay, W/L tracking beyond 12h without manual `!resetwl`, plus the existing chat commands. -- **Provider model**: Reuse `StreamingProvider` contract; add a Kick implementation with provider-aware sockets defaulting to Twitch for backward compatibility. -- **Auth**: Document Kick OAuth (or token) flow, scopes, and refresh handling; store as `provider: 'kick'` in Supabase `accounts` with channel metadata. -- **Chat + commands**: Map existing chat command handlers to Kick transport; ensure role mapping (broadcaster/moderator/subscriber) and rate-limiting aligned to Kick limits. -- **Bets/Polls**: If Kick exposes programmatic bet/poll APIs, wire analogous calls; otherwise, provide feature-flagged chat-driven fallback and disable overlay triggers when unsupported. -- **Online/offline + username changes**: Poll or subscribe to Kick stream status/user profile updates; emit `stream.online/offline` equivalents and detect display-name changes to update downstream caches. -- **W/L tracking**: Use Kick live-status to bound the window instead of 12h; auto-reset W/L on new session start to remove manual `!resetwl`. -- **Observability**: Add provider-tagged metrics/logging for Kick transport, auth failures, and command success/error rates; health checks to verify channel linkage and live-status detection. +- **Objectives & scope**: Deliver Kick chat/stream parity for core Twitch-dependent features: bets open/close, online/offline detection, automatic username change detection, poll/bets overlay, W/L tracking beyond 12h without manual `!resetwl`, plus the existing chat commands. +- **Architecture**: Reuse the `StreamingProvider` contract and provider-aware sockets (default to Twitch when missing) to plug in a Kick transport; add `packages/kick-chat` and `packages/kick-events` mirrors if separation is needed. +- **Authentication**: Document Kick OAuth/token flow, scopes/permissions, refresh, and revocation handling; store as `provider: 'kick'` with channel metadata in Supabase `accounts`. +- **Data model/config**: Store Kick channel id/username and feature toggles (bets/polls enabled, overlay hooks, W/L auto-reset) and any chat state needed to dedupe messages (with TTL). +- **Chat + commands**: Map existing chat command handlers to Kick transport; normalize roles (broadcaster/moderator/subscriber) and tune rate limits to Kick caps. +- **Bets/Polls**: If Kick exposes programmatic bet/poll APIs, call them; otherwise, use feature-flagged chat-driven fallback (and disable overlay triggers when unsupported) to avoid misleading UI. +- **Online/offline + username changes**: Poll/subscribe to Kick stream status and profile updates; emit `stream.online/offline` equivalents and detect display-name changes to refresh caches and overlays. +- **W/L tracking**: Bound W/L windows using Kick live sessions; auto-reset at session start to remove manual `!resetwl` and allow accurate last-session stats. +- **Observability & rollout**: Add provider-tagged metrics/logs for Kick transport/auth/command success; health checks for channel linkage and live-status detection; gate rollout behind a Kick beta allowlist before broad enablement. ## Technical Overview From 24b1557bd96cd423fbbf2fd8ac7299c02fe8dab7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 4 Jan 2026 14:45:17 +0000 Subject: [PATCH 11/16] docs: specify kick poll fallback Co-authored-by: Geczy <1036968+Geczy@users.noreply.github.com> --- TechnicalOverview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TechnicalOverview.md b/TechnicalOverview.md index d02dd2ab..59a943a5 100644 --- a/TechnicalOverview.md +++ b/TechnicalOverview.md @@ -213,7 +213,7 @@ Secrets management uses Doppler, and injects into every Docker build on the fly. - **Authentication**: Document Kick OAuth/token flow, scopes/permissions, refresh, and revocation handling; store as `provider: 'kick'` with channel metadata in Supabase `accounts`. - **Data model/config**: Store Kick channel id/username and feature toggles (bets/polls enabled, overlay hooks, W/L auto-reset) and any chat state needed to dedupe messages (with TTL). - **Chat + commands**: Map existing chat command handlers to Kick transport; normalize roles (broadcaster/moderator/subscriber) and tune rate limits to Kick caps. -- **Bets/Polls**: If Kick exposes programmatic bet/poll APIs, call them; otherwise, use feature-flagged chat-driven fallback (and disable overlay triggers when unsupported) to avoid misleading UI. +- **Bets/Polls**: If Kick exposes programmatic bet/poll APIs, call them; otherwise, use a feature-flagged chat-driven fallback (announce options as numbered keywords like `1`/`2` and count matching messages or reactions) and disable overlay triggers when unsupported to avoid misleading UI. - **Online/offline + username changes**: Poll/subscribe to Kick stream status and profile updates; emit `stream.online/offline` equivalents and detect display-name changes to refresh caches and overlays. - **W/L tracking**: Bound W/L windows using Kick live sessions; auto-reset at session start to remove manual `!resetwl` and allow accurate last-session stats. - **Observability & rollout**: Add provider-tagged metrics/logs for Kick transport/auth/command success; health checks for channel linkage and live-status detection; gate rollout behind a Kick beta allowlist before broad enablement. From 1be7f14428ca9a43c58b00b4915ffb330a159d39 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 4 Jan 2026 14:46:06 +0000 Subject: [PATCH 12/16] docs: add kick auth and fallback specifics Co-authored-by: Geczy <1036968+Geczy@users.noreply.github.com> --- TechnicalOverview.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/TechnicalOverview.md b/TechnicalOverview.md index 59a943a5..81b6568b 100644 --- a/TechnicalOverview.md +++ b/TechnicalOverview.md @@ -210,10 +210,10 @@ Secrets management uses Doppler, and injects into every Docker build on the fly. - **Objectives & scope**: Deliver Kick chat/stream parity for core Twitch-dependent features: bets open/close, online/offline detection, automatic username change detection, poll/bets overlay, W/L tracking beyond 12h without manual `!resetwl`, plus the existing chat commands. - **Architecture**: Reuse the `StreamingProvider` contract and provider-aware sockets (default to Twitch when missing) to plug in a Kick transport; add `packages/kick-chat` and `packages/kick-events` mirrors if separation is needed. -- **Authentication**: Document Kick OAuth/token flow, scopes/permissions, refresh, and revocation handling; store as `provider: 'kick'` with channel metadata in Supabase `accounts`. +- **Authentication**: Document Kick OAuth/token flow with chat read/write scopes (or equivalent), target endpoints for live status (`/api/v2/channels/{channel}` or current live-status API), and chat send/receive. Refresh at 50–70% of token lifetime and handle revocation; store as `provider: 'kick'` with channel metadata in Supabase `accounts`. - **Data model/config**: Store Kick channel id/username and feature toggles (bets/polls enabled, overlay hooks, W/L auto-reset) and any chat state needed to dedupe messages (with TTL). -- **Chat + commands**: Map existing chat command handlers to Kick transport; normalize roles (broadcaster/moderator/subscriber) and tune rate limits to Kick caps. -- **Bets/Polls**: If Kick exposes programmatic bet/poll APIs, call them; otherwise, use a feature-flagged chat-driven fallback (announce options as numbered keywords like `1`/`2` and count matching messages or reactions) and disable overlay triggers when unsupported to avoid misleading UI. +- **Chat + commands**: Map existing chat command handlers to Kick transport; normalize roles (channel owner → broadcaster, moderator → moderator, subscriber/supporter → subscriber) and tune rate limits to Kick chat caps (start conservatively at ~10 msgs/30s and adjust once documented limits are confirmed). +- **Bets/Polls**: If Kick exposes programmatic bet/poll APIs, call them; otherwise, use a feature-flagged chat-driven fallback: announce options as numbered keywords (`1`/`2`), accept votes for a fixed window (e.g., 60–120s), dedupe by user to one vote, count keyword matches/reactions, and disable overlay triggers when unsupported to avoid misleading UI. - **Online/offline + username changes**: Poll/subscribe to Kick stream status and profile updates; emit `stream.online/offline` equivalents and detect display-name changes to refresh caches and overlays. - **W/L tracking**: Bound W/L windows using Kick live sessions; auto-reset at session start to remove manual `!resetwl` and allow accurate last-session stats. - **Observability & rollout**: Add provider-tagged metrics/logs for Kick transport/auth/command success; health checks for channel linkage and live-status detection; gate rollout behind a Kick beta allowlist before broad enablement. From fc7419db3b4d8557dded447e3d1fe4b7bfc0a5e0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 4 Jan 2026 14:46:49 +0000 Subject: [PATCH 13/16] docs: clarify kick endpoints and limits Co-authored-by: Geczy <1036968+Geczy@users.noreply.github.com> --- TechnicalOverview.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/TechnicalOverview.md b/TechnicalOverview.md index 81b6568b..aa3e4049 100644 --- a/TechnicalOverview.md +++ b/TechnicalOverview.md @@ -206,13 +206,13 @@ Secrets management uses Doppler, and injects into every Docker build on the fly. - **Token revocation**: health checks plus UI banner; disable features gracefully and request re-auth. - **Feature gaps vs. Twitch**: define MVP (chat commands + stream status) and stage advanced features after stability metrics are green. -## Kick integration implementation plan (parity with Twitch/YouTube where possible) +## Kick integration implementation plan - **Objectives & scope**: Deliver Kick chat/stream parity for core Twitch-dependent features: bets open/close, online/offline detection, automatic username change detection, poll/bets overlay, W/L tracking beyond 12h without manual `!resetwl`, plus the existing chat commands. - **Architecture**: Reuse the `StreamingProvider` contract and provider-aware sockets (default to Twitch when missing) to plug in a Kick transport; add `packages/kick-chat` and `packages/kick-events` mirrors if separation is needed. -- **Authentication**: Document Kick OAuth/token flow with chat read/write scopes (or equivalent), target endpoints for live status (`/api/v2/channels/{channel}` or current live-status API), and chat send/receive. Refresh at 50–70% of token lifetime and handle revocation; store as `provider: 'kick'` with channel metadata in Supabase `accounts`. +- **Authentication**: Document Kick OAuth/token flow with chat read/write scopes (or equivalent), target endpoints for live status (e.g., `https://kick.com/api/v2/channels/{channel}`—placeholder until confirmed) and chat send/receive. Refresh at 50–70% of token lifetime and handle revocation; store as `provider: 'kick'` with channel metadata in Supabase `accounts`. - **Data model/config**: Store Kick channel id/username and feature toggles (bets/polls enabled, overlay hooks, W/L auto-reset) and any chat state needed to dedupe messages (with TTL). -- **Chat + commands**: Map existing chat command handlers to Kick transport; normalize roles (channel owner → broadcaster, moderator → moderator, subscriber/supporter → subscriber) and tune rate limits to Kick chat caps (start conservatively at ~10 msgs/30s and adjust once documented limits are confirmed). +- **Chat + commands**: Map existing chat command handlers to Kick transport; normalize roles (channel owner → broadcaster, moderator → moderator, subscriber/supporter → subscriber) and tune rate limits to Kick chat caps (start conservatively at ~10 msgs/30s—explicitly provisional—and adjust once documented limits are confirmed). - **Bets/Polls**: If Kick exposes programmatic bet/poll APIs, call them; otherwise, use a feature-flagged chat-driven fallback: announce options as numbered keywords (`1`/`2`), accept votes for a fixed window (e.g., 60–120s), dedupe by user to one vote, count keyword matches/reactions, and disable overlay triggers when unsupported to avoid misleading UI. - **Online/offline + username changes**: Poll/subscribe to Kick stream status and profile updates; emit `stream.online/offline` equivalents and detect display-name changes to refresh caches and overlays. - **W/L tracking**: Bound W/L windows using Kick live sessions; auto-reset at session start to remove manual `!resetwl` and allow accurate last-session stats. From 2eb7d5d810a28d208c07a207ad59cbd05c14a32a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 4 Jan 2026 14:47:33 +0000 Subject: [PATCH 14/16] docs: expand kick auth and polls detail Co-authored-by: Geczy <1036968+Geczy@users.noreply.github.com> --- TechnicalOverview.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/TechnicalOverview.md b/TechnicalOverview.md index aa3e4049..00f287ec 100644 --- a/TechnicalOverview.md +++ b/TechnicalOverview.md @@ -210,10 +210,10 @@ Secrets management uses Doppler, and injects into every Docker build on the fly. - **Objectives & scope**: Deliver Kick chat/stream parity for core Twitch-dependent features: bets open/close, online/offline detection, automatic username change detection, poll/bets overlay, W/L tracking beyond 12h without manual `!resetwl`, plus the existing chat commands. - **Architecture**: Reuse the `StreamingProvider` contract and provider-aware sockets (default to Twitch when missing) to plug in a Kick transport; add `packages/kick-chat` and `packages/kick-events` mirrors if separation is needed. -- **Authentication**: Document Kick OAuth/token flow with chat read/write scopes (or equivalent), target endpoints for live status (e.g., `https://kick.com/api/v2/channels/{channel}`—placeholder until confirmed) and chat send/receive. Refresh at 50–70% of token lifetime and handle revocation; store as `provider: 'kick'` with channel metadata in Supabase `accounts`. +- **Authentication**: Mirror YouTube detail: front-end starts Kick OAuth, exchange auth code for access/refresh, request chat read/write + profile scopes (to confirm against Kick docs), and persist `provider: 'kick'` with channel metadata in Supabase `accounts`. Refresh at 50–70% of token lifetime, detect `invalid_grant`/revocation, surface re-auth UI, and target live-status endpoints (e.g., `https://kick.com/api/v2/channels/{channel}` placeholder until confirmed) plus chat send/receive APIs. - **Data model/config**: Store Kick channel id/username and feature toggles (bets/polls enabled, overlay hooks, W/L auto-reset) and any chat state needed to dedupe messages (with TTL). -- **Chat + commands**: Map existing chat command handlers to Kick transport; normalize roles (channel owner → broadcaster, moderator → moderator, subscriber/supporter → subscriber) and tune rate limits to Kick chat caps (start conservatively at ~10 msgs/30s—explicitly provisional—and adjust once documented limits are confirmed). -- **Bets/Polls**: If Kick exposes programmatic bet/poll APIs, call them; otherwise, use a feature-flagged chat-driven fallback: announce options as numbered keywords (`1`/`2`), accept votes for a fixed window (e.g., 60–120s), dedupe by user to one vote, count keyword matches/reactions, and disable overlay triggers when unsupported to avoid misleading UI. +- **Chat + commands**: Map existing chat command handlers to Kick transport; normalize roles (channel owner → broadcaster, moderator → moderator, subscriber/supporter → subscriber) and tune rate limits to Kick chat caps (start conservatively at ~10 msgs/30s—explicitly provisional—and replace with documented limits after reviewing Kick API rate guidance). +- **Bets/Polls**: If Kick exposes programmatic bet/poll APIs, call them; otherwise, use a feature-flagged chat-driven fallback: announce options as numbered keywords (`1`/`2`), accept votes for a fixed window (e.g., 60–120s), dedupe by user to one vote (store per-voter choice in memory/Redis with TTL), tally at window close, and emit results to chat/overlay only when data is present (disable overlay triggers when unsupported). - **Online/offline + username changes**: Poll/subscribe to Kick stream status and profile updates; emit `stream.online/offline` equivalents and detect display-name changes to refresh caches and overlays. - **W/L tracking**: Bound W/L windows using Kick live sessions; auto-reset at session start to remove manual `!resetwl` and allow accurate last-session stats. - **Observability & rollout**: Add provider-tagged metrics/logs for Kick transport/auth/command success; health checks for channel linkage and live-status detection; gate rollout behind a Kick beta allowlist before broad enablement. From 9459cbbefee84bebc675707a945415b65a7da624 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 4 Jan 2026 14:48:04 +0000 Subject: [PATCH 15/16] docs: clarify kick auth wording Co-authored-by: Geczy <1036968+Geczy@users.noreply.github.com> --- TechnicalOverview.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/TechnicalOverview.md b/TechnicalOverview.md index 00f287ec..30425187 100644 --- a/TechnicalOverview.md +++ b/TechnicalOverview.md @@ -210,9 +210,9 @@ Secrets management uses Doppler, and injects into every Docker build on the fly. - **Objectives & scope**: Deliver Kick chat/stream parity for core Twitch-dependent features: bets open/close, online/offline detection, automatic username change detection, poll/bets overlay, W/L tracking beyond 12h without manual `!resetwl`, plus the existing chat commands. - **Architecture**: Reuse the `StreamingProvider` contract and provider-aware sockets (default to Twitch when missing) to plug in a Kick transport; add `packages/kick-chat` and `packages/kick-events` mirrors if separation is needed. -- **Authentication**: Mirror YouTube detail: front-end starts Kick OAuth, exchange auth code for access/refresh, request chat read/write + profile scopes (to confirm against Kick docs), and persist `provider: 'kick'` with channel metadata in Supabase `accounts`. Refresh at 50–70% of token lifetime, detect `invalid_grant`/revocation, surface re-auth UI, and target live-status endpoints (e.g., `https://kick.com/api/v2/channels/{channel}` placeholder until confirmed) plus chat send/receive APIs. +- **Authentication**: Follow the same provider auth pattern: front-end starts Kick OAuth, exchange auth code for access/refresh, request chat read/write + profile scopes (to confirm against Kick docs), and persist `provider: 'kick'` with channel metadata in Supabase `accounts`. Refresh at 50–70% of token lifetime, detect `invalid_grant`/revocation, surface re-auth UI, and target live-status endpoints (e.g., `https://kick.com/api/v2/channels/{channel}` placeholder until confirmed) plus chat send/receive APIs. - **Data model/config**: Store Kick channel id/username and feature toggles (bets/polls enabled, overlay hooks, W/L auto-reset) and any chat state needed to dedupe messages (with TTL). -- **Chat + commands**: Map existing chat command handlers to Kick transport; normalize roles (channel owner → broadcaster, moderator → moderator, subscriber/supporter → subscriber) and tune rate limits to Kick chat caps (start conservatively at ~10 msgs/30s—explicitly provisional—and replace with documented limits after reviewing Kick API rate guidance). +- **Chat + commands**: Map existing chat command handlers to Kick transport; normalize roles (channel owner → broadcaster, moderator → moderator, subscriber/supporter → subscriber) and tune rate limits to Kick chat caps (**TODO: replace provisional ~10 msgs/30s with documented limits after reviewing Kick API rate guidance**). - **Bets/Polls**: If Kick exposes programmatic bet/poll APIs, call them; otherwise, use a feature-flagged chat-driven fallback: announce options as numbered keywords (`1`/`2`), accept votes for a fixed window (e.g., 60–120s), dedupe by user to one vote (store per-voter choice in memory/Redis with TTL), tally at window close, and emit results to chat/overlay only when data is present (disable overlay triggers when unsupported). - **Online/offline + username changes**: Poll/subscribe to Kick stream status and profile updates; emit `stream.online/offline` equivalents and detect display-name changes to refresh caches and overlays. - **W/L tracking**: Bound W/L windows using Kick live sessions; auto-reset at session start to remove manual `!resetwl` and allow accurate last-session stats. From 1e9c94a4040462f35429bb8b8c011852b828b623 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 4 Jan 2026 14:48:50 +0000 Subject: [PATCH 16/16] docs: mark kick api checks as blockers Co-authored-by: Geczy <1036968+Geczy@users.noreply.github.com> --- TechnicalOverview.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/TechnicalOverview.md b/TechnicalOverview.md index 30425187..d9aa99ba 100644 --- a/TechnicalOverview.md +++ b/TechnicalOverview.md @@ -210,9 +210,9 @@ Secrets management uses Doppler, and injects into every Docker build on the fly. - **Objectives & scope**: Deliver Kick chat/stream parity for core Twitch-dependent features: bets open/close, online/offline detection, automatic username change detection, poll/bets overlay, W/L tracking beyond 12h without manual `!resetwl`, plus the existing chat commands. - **Architecture**: Reuse the `StreamingProvider` contract and provider-aware sockets (default to Twitch when missing) to plug in a Kick transport; add `packages/kick-chat` and `packages/kick-events` mirrors if separation is needed. -- **Authentication**: Follow the same provider auth pattern: front-end starts Kick OAuth, exchange auth code for access/refresh, request chat read/write + profile scopes (to confirm against Kick docs), and persist `provider: 'kick'` with channel metadata in Supabase `accounts`. Refresh at 50–70% of token lifetime, detect `invalid_grant`/revocation, surface re-auth UI, and target live-status endpoints (e.g., `https://kick.com/api/v2/channels/{channel}` placeholder until confirmed) plus chat send/receive APIs. +- **Authentication**: Follow the same provider auth pattern: front-end starts Kick OAuth, exchange auth code for access/refresh, request chat read/write + profile scopes (to confirm against Kick docs), and persist `provider: 'kick'` with channel metadata in Supabase `accounts`. Refresh at 50–70% of token lifetime, detect `invalid_grant`/revocation, surface re-auth UI, and target live-status endpoints (e.g., `https://kick.com/api/v2/channels/{channel}` placeholder—**must be replaced with confirmed endpoints before implementation**) plus chat send/receive APIs. - **Data model/config**: Store Kick channel id/username and feature toggles (bets/polls enabled, overlay hooks, W/L auto-reset) and any chat state needed to dedupe messages (with TTL). -- **Chat + commands**: Map existing chat command handlers to Kick transport; normalize roles (channel owner → broadcaster, moderator → moderator, subscriber/supporter → subscriber) and tune rate limits to Kick chat caps (**TODO: replace provisional ~10 msgs/30s with documented limits after reviewing Kick API rate guidance**). +- **Chat + commands**: Map existing chat command handlers to Kick transport; normalize roles (channel owner → broadcaster, moderator → moderator, subscriber/supporter → subscriber) and tune rate limits to Kick chat caps (**BLOCKER before rollout: replace provisional ~10 msgs/30s with documented limits after reviewing Kick API rate guidance**). - **Bets/Polls**: If Kick exposes programmatic bet/poll APIs, call them; otherwise, use a feature-flagged chat-driven fallback: announce options as numbered keywords (`1`/`2`), accept votes for a fixed window (e.g., 60–120s), dedupe by user to one vote (store per-voter choice in memory/Redis with TTL), tally at window close, and emit results to chat/overlay only when data is present (disable overlay triggers when unsupported). - **Online/offline + username changes**: Poll/subscribe to Kick stream status and profile updates; emit `stream.online/offline` equivalents and detect display-name changes to refresh caches and overlays. - **W/L tracking**: Bound W/L windows using Kick live sessions; auto-reset at session start to remove manual `!resetwl` and allow accurate last-session stats.