fix(stream): the subscription script ignored Stream's product scoping - #1153
Conversation
…#1134) Applied against the live app and it was refused: UpdateApp failed: invalid event types for hook 44a1d716-…: event types [message.flagged user.flagged] do not belong to product 'video' Stream partitions event types by product and a hook may only carry its own. The app has exactly one hook, scoped to `video`. The two chat-moderation events can never live on it. The script had no concept of `product`, so it reported all five unsubscribed events as plainly "missing" — which reads as one write away from fixed. Two of them were impossible. Worse, `updateAppSettings` rejects the whole payload atomically, so the single impossible event cost the three achievable ones in the same write and nothing landed at all. Now each hook is offered only what its product permits, and any handled event with no hook to carry it is reported as a configuration gap rather than a pending write. The script does not create the missing hook: that decides a public URL and starts real deliveries, so it belongs to a human in the dashboard, exactly as the existing "no webhook at all" branch already does. Verified against production. The video hook went 6 -> 9 events, so call.session_participant_joined / _left and call.session_started now deliver and MeetingAttendance can finally be written. Chat moderation stays dead until a 'chat' hook exists — which the script now says out loud instead of implying it is one run away. Part of #1134
✅ Deploy Preview for familiarise ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
Warning Review limit reached
Next review available in: 111 minutes You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|




Found by running the script from #1141 against production, which is the only place it could have been found. Part of #1134.
What happened
--applywas refused outright:Stream partitions event types by product, and a hook may only carry events from its own. This app has exactly one hook, scoped to
video. The two chat-moderation events can never live on it, no matter how many times the script runs.Why the old script made this worse rather than surfacing it
It had no concept of
product. Its dry run reported all five unsubscribed events as plainly "missing", which reads as one write away from fixed:And because
updateAppSettingsrejects the payload atomically, the two impossible events cost the three achievable ones in the same write. Nothing landed. The script would have kept reporting the same five as missing forever, with the operator reasonably concluding the write simply had not been run.What it does now
Each hook is offered only the events its product permits, and anything left over is reported as a configuration gap rather than a pending write:
The script deliberately does not create the missing hook. Creating one decides a public URL and starts real deliveries against it, so it belongs to a human in the dashboard — the same reasoning the existing "no webhook configured at all" branch already applies.
A hook with no
productset is treated as unconstrained rather than skipped: the field is optional in the SDK, and refusing to widen a hook we cannot classify would be worse than letting Stream reject it with a precise message.Verified in production
The video hook went 6 → 9 events.
call.session_participant_joined,call.session_participant_leftandcall.session_startednow deliver, soMeetingAttendancecan be written for the first time — it has been sitting at zero rows, which is what madedetect-consultant-no-showsa job running daily against an empty table.Chat moderation stays dead until a
chathook exists. That is now stated out loud rather than implied to be one run away.7 suites pass, tsc and eslint clean.
Operator follow-up
Create a second webhook in the Stream dashboard with product
chat, pointing athttps://familiarisenow.com/api/stream/webhooks, then re-run the script to subscribeuser.flaggedandmessage.flagged.