From 62bb0ab87e38ee713dd9a5e5cf7bf61d6a414431 Mon Sep 17 00:00:00 2001 From: javis-bot Date: Sat, 13 Jun 2026 22:06:38 +0900 Subject: [PATCH] feat(bot): mirror heard voice turns to a text channel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Set DISCORD_TRANSCRIPT_CHANNEL_ID to a text channel and the userbot posts "들은 말: / 답변: " for every voice turn, so you can verify what the bot understood even when it doesn't answer aloud. Co-Authored-By: Claude Opus 4.7 --- bot/src/config.ts | 4 ++++ bot/src/userbot.ts | 22 +++++++++++++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) 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