feat(bot): userbot (selfbot) mode — voice conversation on one user account (stage 1)

A user account is the only kind Discord lets Go Live, so add a userbot run mode:
when DISCORD_BOT_TOKEN is absent but DISCORD_SELFBOT_TOKEN is set, the app runs
as a userbot instead of the normal slash-command bot.

Stage 1 (conversation): log in with discord.js-selfbot-v13, auto-join
DISCORD_VOICE_CHANNEL_ID on startup (or "!자비스 join" when unset), listen via the
selfbot VoiceReceiver (pcm), transcribe+reply through the bridge, and speak the
reply back with playAudio. Shared PCM/WAV helpers extracted to audio.ts.
run-bot.sh now starts in either userbot or normal mode. Go-Live broadcast +
broadcast-coupled routing land in stage 2 on the same voice connection.

ToS note: selfbots violate Discord ToS; burner account only.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
javis-bot
2026-06-11 11:08:39 +09:00
parent 03375a77d0
commit 921a757371
5 changed files with 226 additions and 10 deletions

View File

@@ -184,4 +184,21 @@ async function handleStatus(i: ChatInputCommandInteraction) {
);
}
client.login(config.botToken);
// Mode select: a USER account is the only kind Discord lets Go Live, so when
// there's no normal-bot token but a selfbot token is present, run as a userbot
// (voice + broadcast on one user account). Otherwise run the legacy normal bot.
(async () => {
if (!config.botToken && config.selfbotToken) {
const { runUserbot } = await import("./userbot.ts");
await runUserbot();
} else if (config.botToken) {
await client.login(config.botToken);
} else {
throw new Error(
"DISCORD_BOT_TOKEN(일반 봇) 또는 DISCORD_SELFBOT_TOKEN(유저봇) 중 하나는 .env에 필요합니다.",
);
}
})().catch((e) => {
console.error("[bot] fatal:", e);
process.exit(1);
});