fix(bot): tear down existing voice connection before re-joining

joinChannel reused a same-guild connection and re-subscribed a new player and
receiver each time, stacking duplicate speaking listeners (→ duplicate voice
turns) and error handlers. Now it no-ops if already in the target channel and
otherwise leaves the current connection first, so channel switches are clean.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
EJClaw
2026-08-22 12:00:51 +09:00
parent d3cf4e01b5
commit 7eb590b729

View File

@@ -205,7 +205,13 @@ async function joinChannel(guildId, channelId) {
const guild = await client.guilds.fetch(guildId).catch(() => null); const guild = await client.guilds.fetch(guildId).catch(() => null);
const channel = guild && await guild.channels.fetch(channelId).catch(() => null); const channel = guild && await guild.channels.fetch(channelId).catch(() => null);
if (!channel || !channel.isVoiceBased()) { log(`join failed: ${guildId}/${channelId} not a voice channel`); return; } if (!channel || !channel.isVoiceBased()) { log(`join failed: ${guildId}/${channelId} not a voice channel`); return; }
if (currentGuildId && currentGuildId !== guildId) leaveChannel(); if (currentGuildId === guildId && currentChannelId === channelId && getVoiceConnection(guildId)) {
log(`already in "${channel.name}"`); return;
}
// Always tear down any existing connection first. Re-subscribing a player and
// receiver onto a reused same-guild connection would stack duplicate speaking
// listeners (→ duplicate voice turns) and duplicate error handlers.
if (currentGuildId) leaveChannel();
const connection = joinVoiceChannel({ const connection = joinVoiceChannel({
channelId, guildId, adapterCreator: guild.voiceAdapterCreator, channelId, guildId, adapterCreator: guild.voiceAdapterCreator,
selfDeaf: false, selfMute: false, selfDeaf: false, selfMute: false,