fix(stream): TEST-tab chat — resolve liveChatId from snippet, poll until the broadcast is live
The open creator report ('I still cannot post a chat message in the TEST tab',
feedback 'Chat polling couldn't start — Mock Chat Input is disabled') was a single
cause: the liveChatId never resolved. Two YouTube API facts:
1. The id lives in snippet.liveChatId — contentDetails has no such property
(TASK 44 read part=contentDetails: could never resolve).
https://developers.google.com/youtube/v3/live/docs/liveBroadcasts
2. It only exists once the broadcast is LIVE — the official sample lists
broadcastStatus=active, and our fetch ran before the frame pump pushed RTMP
(enableAutoStart flips ready→live). A ready-state list legitimately returns
no id.
https://github.com/youtube/api-samples/blob/master/java/src/main/java/com/google/api/services/samples/youtube/cmdline/live/GetLiveChatId.java
Fix: GetBroadcastLiveChatIdAsync reads part=snippet and polls with a bounded
retry (10x/2s); PrepareAndStartLiveAsync starts the frame pump FIRST, then
resolves the id. Chat stays non-fatal. Docs ai.md/TASKS.md/HANDOFF.md +
MyMistakes recipe updated same commit. TASK 44.
Good Dog: ONE integration test (GetBroadcastLiveChatIdAsync_Polls_Snippet_...
) drives a broadcast that gains its id mid-retry and asserts every request used
part=snippet. Gate: clean build 0 warnings, vstest 318/318.
This commit is contained in:
@@ -1560,6 +1560,15 @@ These are the hard facts behind every decision. Full list in `TASKS.md`.
|
||||
`StopStream` clears it in every path (including pump-failure rollback). Once the liveChatId
|
||||
resolves, `TestSession.BeginTest(broadcastId, liveChatId)` opens the **TEST drawer** (third
|
||||
right-rail pull-out, three-way one-open-at-a-time exclusivity wired in `MainViewModel.Ypp.cs`).
|
||||
**liveChatId resolution (fixed 2026-09-25, TASK 44):** the id is `snippet.liveChatId` —
|
||||
`contentDetails` has NO liveChatId property — and YouTube only populates it once the broadcast
|
||||
is LIVE (the official GetLiveChatId.java sample lists broadcastStatus=active). So
|
||||
`GetBroadcastLiveChatIdAsync(broadcastId, maxAttempts=10, delayMs=2000)` reads
|
||||
part=snippet and polls with a bounded retry, and `PrepareAndStartLiveAsync` starts the frame
|
||||
pump FIRST (the RTMP push is what flips ready→live via enableAutoStart) before resolving it.
|
||||
Chrome-debugging note: a fetch at broadcast-insert time (lifecycleStatus ready) legitimately
|
||||
returns no id — missing liveChatId is the ready state, not an auth failure, until ~20s post
|
||||
push.
|
||||
Drawer tooling: **Mock Chat Input** = a REAL `liveChat/messages.insert` (`YouTubeStreamService.InsertChatMessageAsync`)
|
||||
that round-trips through the real ~2s poll and renders through the live overlay path;
|
||||
**simulated Subscriber / New Member / Super Chat** = `YouTubeChatService.InjectSimulatedMessage`,
|
||||
|
||||
Reference in New Issue
Block a user