diff --git a/bot/src/config.ts b/bot/src/config.ts index 691ba96..7c7ee6a 100644 --- a/bot/src/config.ts +++ b/bot/src/config.ts @@ -27,6 +27,10 @@ export const config = { // Userbot auto-join: if set, the userbot joins this voice channel on startup; // if empty, it waits for a text command (e.g. "!μžλΉ„μŠ€ join") to join. autoJoinChannelId: opt("DISCORD_VOICE_CHANNEL_ID"), + // Optional text channel where the bot mirrors every voice turn it heard + // (transcript + reply) so you can verify what it understood even when it + // doesn't answer aloud. + transcriptChannelId: opt("DISCORD_TRANSCRIPT_CHANNEL_ID"), // --- Python brain bridge --- bridgeUrl: opt("BRIDGE_URL", "http://127.0.0.1:8765"), diff --git a/bot/src/userbot.ts b/bot/src/userbot.ts index 4f8ef72..ac34e14 100644 --- a/bot/src/userbot.ts +++ b/bot/src/userbot.ts @@ -34,6 +34,21 @@ async function loadSelfbot(): Promise { } } +/** Mirror a heard voice turn (transcript + reply) into a text channel. */ +async function postTranscript(client: AnyClient, transcript: string, reply: string): Promise { + const chId = config.transcriptChannelId; + if (!chId) return; + try { + const ch: any = await client.channels.fetch(chId).catch(() => null); + if (ch?.send) { + const r = (reply || "").trim(); + await ch.send(`πŸ—£οΈ 듀은 말: ${transcript}\nπŸ€– λ‹΅λ³€: ${r || "(무응닡)"}`); + } + } catch (e) { + console.error("[userbot] transcript post failed:", e); + } +} + async function joinAndListen(client: AnyClient, channelId: string): Promise { const channel: any = await client.channels.fetch(channelId).catch(() => null); if (!channel || channel.isVoice?.() === false) { @@ -43,7 +58,12 @@ async function joinAndListen(client: AnyClient, channelId: string): Promise console.log(`πŸ—£οΈ ${transcript}\nπŸ€– ${reply}`); + session.onTurn = ({ transcript, reply }) => { + console.log(`πŸ—£οΈ ${transcript}\nπŸ€– ${reply}`); + // Mirror every heard utterance (and the reply, if any) to a text channel so + // you can see what the bot understood even when it doesn't answer aloud. + void postTranscript(client, transcript, 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