One chat window, two bots, no agreement between them
Collab streams used to be simple for chat tools. Each channel had its own chat, its own bot, and its own rules, and the only overlap was a shoutout. Twitch's Shared Chat changes that. Twitch's help center describes it as combining the chats of collaborating channels so messages sent in one channel duplicate into the others.
For a bot that owns paid moments, that creates three questions nobody had to answer before. Whose viewer typed this command? Whose stream should react? And whose chat should see the reply? If your setup does not answer them on purpose, it answers them by accident, usually by letting someone else's community trigger your overlay or letting your command help text flood someone else's chat.
How Shared Chat starts and ends
According to Twitch's help article, Shared Chat is off by default when a Stream Together session starts, and only the host decides whether to turn it on. The host can start it from the Stream Together backstage window or with the /sharedchat command. Guests need to be live to join, and a guest who is not live yet can join manually once they are. Individual guests can leave Shared Chat while staying in the Stream Together session, and leaving takes their community with them.
That lifecycle matters for tooling because the chat can change shape in the middle of a show. A guest might leave after twenty minutes. The host might end sharing but keep the video collab running. A bot that assumes the chat looks the same at hour two as it did at minute one will misjudge a lot of messages.
What your bot can see
Twitch's EventSub reference gives chat messages a set of source fields. source_broadcaster_user_id is null when a message happens in the same channel as the broadcaster you subscribed to, and it is not null when the message came from another participant's channel during a shared session. You also get the source login and name, a source_message_id, and source_badges. There is a related is_source_only flag that says whether a message was delivered only to its source channel.
Separate subscription types announce the session itself: channel.shared_chat.begin, channel.shared_chat.update, and channel.shared_chat.end, each documented as beta at the time of writing. The API also has a Get Shared Chat Session endpoint that returns the active session for a channel, and it returns an empty array if the channel is not in one.
The practical read is straightforward. The source fields tell you who is talking. The session events tell you when the rules should change. The API call lets a bot that just restarted figure out whether it missed the begin event.
Sort commands into three scopes
Not every command should behave the same in a shared session. A simple sort works for most channels, and it helps to write it down before the collab rather than deciding live.
The key test for each command is whether the person typing has seen your rules, your prices, and your moderation expectations. A viewer in the partner's chat window has seen none of that. They are reading a merged chat, and your command name might look like any other chat shortcut.
- Local-only: anything that spends money, plays audio, or puts a viewer's content on your overlay. Act only when the source is your own channel.
- Session-wide: harmless fun like a dice roll or a poll vote, if you and your collab partner both want it. Agree on it ahead of time.
- Host-only: commands that control the collab itself, such as scene or queue controls. Restrict to your own mod list, not to anyone with a moderator badge on screen.
A source badge is not your moderator list
The source_badges field describes what badges the chatter has in the channel the message came from. A moderator badge there means the person moderates the partner's channel, not yours. If your command permissions read badges straight off the message, a partner's moderator could suddenly be allowed to clear your queue or approve paid content.
Check permissions against your own channel's moderator list and your own VIP and subscriber status. Treat messages from another source channel as unprivileged until your own records say otherwise. If Twitch's help article describes cross-channel moderation behavior you want to rely on, test it with your partner before the stream instead of assuming it matches your bot's behavior.
The alert mistake that is easy to miss
Twitch's chat notification event lists the notice types that are shared during a Shared Chat session, with a note that the list is subject to change. Alongside the ordinary types, there are variants that start with shared_chat, including shared_chat_sub, shared_chat_resub, shared_chat_sub_gift, shared_chat_community_sub_gift, shared_chat_raid, shared_chat_announcement, and a few more.
Those are events from the partner's channel being shown in yours. If your alert logic matches on a prefix, or treats any unknown notice type as a sub, a partner's new subscriber can trigger your sub alert. That is confusing for your viewers, unfair to the partner, and awkward for the person whose name flashes on the wrong stream.
Map notice types explicitly. Known own-channel types fire your alerts. The shared_chat variants either do nothing or feed a quiet, clearly labeled overlay if you and your partner agree on it. Anything unknown is logged and ignored until someone reads the docs again.
Where your bot's replies go
Twitch's Send Chat Message reference says that behavior depends on the token type. With an app access token, messages go only to the source channel by default, which Twitch says has been the case since May 19, 2025, and you can send to every channel in the session by setting for_source_only to false. With a user access token, messages go to all channels in the session, and that behavior cannot be changed. Chat announcements follow the same pattern.
This means the same line of code can behave two ways depending on how your bot authenticates. A pinned reminder about your tip page and your TTS rules is useful to your own viewers and noise to someone else's. Decide which token your bot uses for command replies, and keep replies about your paid features inside your own channel.
There is a cost. If a partner's viewer types your command and your reply stays in your channel, they see nothing back. The cleanest answer is to ignore commands from other source channels entirely, so there is no silent failure to explain. If you want to answer, send one short line to the whole session and nothing else.
Money follows the page, not the chat window
Paid TTS, paid alerts, and Upload Corner purchases generally start from a tip page or a paid-interaction link, not from a chat message. That makes ownership easy to state: the stream whose page the viewer paid on is the stream that reacts. A viewer who is reading the merged chat from the partner's side still pays through the page they chose.
The risk is messaging, not payment. If your chat command or panel text points viewers to a link while the partner's viewers can read it, some of them will use it without knowing it is not part of the collab. Say clearly on screen whose page it is. When you want a joint paid moment, such as a split tip goal, set it up deliberately with both channels rather than letting it happen through shared chat.
Switch policy on the session events
Use the session events as the trigger for a collab mode. On begin, command handling switches to local-only for money and overlays, shared_chat notice types are muted, and replies stay in channel. On end or when your channel leaves, the bot returns to normal. If you subscribe to update, treat it as a reason to re-read the participant list rather than assuming it is only the host that changed.
A bot that restarts in the middle of a session misses the begin event. On startup, call Get Shared Chat Session for your channel. If it returns a session, enter collab mode immediately. If it returns an empty array, you are in normal mode. That one check removes a whole category of strange behavior after a reconnect.
New viewers from the partner's community will also show up in your moderation queue with no history. Treat their first submissions the way you treat any first-time submitter: held for review, with a plain reason if you reject.
A ten-minute drill with your collab partner
Before the real stream, start a Stream Together session with a friend and turn on Shared Chat. Have each side type one local-only command, one session-wide command, and one command that tries a moderator-only action. Confirm that only your own channel's viewers can trigger paid overlays, that the moderator command fails for a source-channel moderator, and that a test sub in the partner's channel does not fire your alert.
- Local paid command typed from the partner's side: ignored or politely refused.
- Session-wide command: works for both sides and replies once.
- Partner moderator tries a privileged command: refused by your own list.
- Partner gets a test subscriber: no alert on your overlay.
- Bot restarts mid-session: collab mode comes back on its own.
Quick answers
Does Shared Chat turn on automatically for Stream Together?
No. Twitch's help article says it is off by default when a Stream Together session begins, and only the host decides whether to turn it on.
How can my bot tell which channel a message came from?
Read the source fields on the chat message event. source_broadcaster_user_id is null for your own channel and set when the message came from another participant's channel during a shared session.
Why did my sub alert fire for the other streamer's subscriber?
Most likely your alert logic matched a shared_chat notice type as an ordinary sub or treated an unknown type as one. Match known types explicitly and ignore the shared_chat variants unless you and your partner agree on a joint display.
Should my bot reply to commands typed from the partner's chat?
Usually no. The viewer has not seen your rules, and a reply sent only to your channel may never reach them. Ignoring cross-channel paid commands avoids silent failures and keeps the collab focused on the show.
