fix(bot): auto-start broadcast on voice join in userbot mode

The "couple broadcast to voice" feature only wired auto-start into the
normal-bot join handler. Userbot mode (the only mode that can actually Go
Live) was added later with Go-Live deferred to a "stage 2" that never
landed, so the running deployment had no path to start a broadcast.

Extract the coupling into a shared bot/src/broadcast.ts (auto-start on
join, report live state to the brain each turn, voice toggle) and wire it
into both index.ts and userbot.ts so both modes behave identically. Add a
behavioural test for the auto-start + toggle contract.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
javis-bot
2026-06-13 14:39:29 +09:00
parent d6c029d7d5
commit 568a1ae50b
4 changed files with 174 additions and 39 deletions

View File

@@ -19,6 +19,7 @@
import type { VoiceBasedChannel } from "discord.js";
import { config } from "./config.ts";
import { joinChannel, leaveGuild } from "./voice.ts";
import { maybeCoupleBroadcast, stopBroadcast } from "./broadcast.ts";
type AnyClient = any;
@@ -43,6 +44,11 @@ async function joinAndListen(client: AnyClient, channelId: string): Promise<void
// joinVoiceChannel (it exposes id, guild.id and guild.voiceAdapterCreator).
const session = await joinChannel(channel as unknown as VoiceBasedChannel);
session.onTurn = ({ transcript, reply }) => console.log(`🗣️ ${transcript}\n🤖 ${reply}`);
// Screen-share mode (STREAM_BROWSER=true): auto-start the broadcast on join,
// report its live state to the brain each turn, and let the brain toggle it by
// voice. Userbot is the only mode that can actually Go Live, so without this
// wiring the broadcast never starts. No-op when STREAM_BROWSER=false.
await maybeCoupleBroadcast(session, { guildId: channel.guild.id, voiceChannelId: channel.id });
console.log(`🎙️ 유저봇이 '${channel.name}' 음성채널에 참여했습니다.`);
}
@@ -72,6 +78,9 @@ export async function runUserbot(): Promise<void> {
const ch = msg.member?.voice?.channel || msg.author?.voice?.channel;
if (ch) await joinAndListen(client, ch.id).catch((e) => console.error("[userbot] join cmd:", e));
} else if (content === "!자비스 leave" || content === "!jarvis leave") {
// Leaving voice also ends the broadcast — don't leave a stream live with
// no session driving it.
await stopBroadcast(config.guildId);
leaveGuild(config.guildId);
}
});