You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

discord.js中VoiceState无法一致更新 移动语音频道成员命令故障

问题解决办法

问题原因

你遇到的VoiceState更新不一致问题,核心有两点:

  1. 直接读取discord.js本地缓存的voiceStates数据,缓存没有和网关事件实时同步,用户断开连接的事件推送延迟时就会出现状态滞后
  2. 没有在Discord开发者后台开启对应的特权网关权限,导致用户断开语音的事件没有推送给机器人,本地缓存永远不会更新

修复步骤

第一步:开启开发者后台特权Intent

打开Discord Developer Portal,进入你的机器人应用的「Bot」设置页,找到Privileged Gateway Intents板块,打开Server Voice States的开关,保存设置。你代码里已经声明了GUILD_VOICE_STATES intent,配合后台开关就能完整接收所有语音状态变更事件。

第二步:修改代码,优先取实时状态,避免直接读缓存

不要从全局guild缓存取语音状态,直接用interaction.member.voice获取和当前交互绑定的最新语音状态,准确度更高;如果需要全服务器的语音状态,先主动fetch再操作,不要直接读cache。
修改后的命令执行代码如下:

//The command file
const Discord= require('discord.js');
const {SlashCommandBuilder} = require("@discordjs/builders");
module.exports = {
    data: new SlashCommandBuilder()
        .setName('move')
        .setDescription('Move all the members to a specific voice channel')
        .addChannelOption(option =>
            option.setName('voicechannel')
                .setDescription('The voice channel to move everyone in')
                .setRequired(true)),
    async execute(interaction) {
        const authorVoiceState = interaction.member.voice;
        const targetChannel = interaction.options.getChannel('voicechannel');
        // 直接用实时状态判断,不走缓存
        if (!authorVoiceState.channel) {
            return await interaction.reply({content : 'You need to be in a voice channel first', ephemeral: true});
        }
        if (targetChannel.id === authorVoiceState.channel.id) {
            return await interaction.reply({content : 'Can\'t move to the same channel', ephemeral: true});
        }
        // 拉取全服最新的语音状态,主动fetch不走缓存
        const allVoiceStates = await interaction.guild.voiceStates.fetch();
        // 实现移动成员逻辑:遍历触发者所在频道的所有成员,移动到目标频道
        authorVoiceState.channel.members.each(async member => {
            if (member.voice.channel) await member.voice.setChannel(targetChannel);
        });
        await interaction.reply({content : 'ok', ephemeral: true});
    },
};

如果还是偶现状态不一致的情况,可以额外给语音状态对象加判断,channelId为null的时候直接视为用户已经断开语音即可。

内容的提问来源于stack exchange,提问作者itsaikara

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 18:03:00