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

Discord.js机器人语音状态检测异常,重启才生效求助

Discord.js机器人语音状态检测缓存问题解决

问题场景

我写了一段Discord.js代码,用来检测用户是否在语音频道里,如果没在就提醒他们别在特定频道发消息。代码如下:

const { Client, GatewayIntentBits } = require('discord.js');
require('dotenv/config')

var guildID = "1128642534483****"

const client = new Client({
    intents: [
        GatewayIntentBits.Guilds,
        GatewayIntentBits.GuildMessages,
        GatewayIntentBits.MessageContent,
        GatewayIntentBits.GuildMembers,
        GatewayIntentBits.GuildPresences
    ],
});

client.on('ready', (c) => {
    console.log('The bot is ready')
})

client.on('messageCreate', message => {
    console.log(1)
    if (message.content !== "") {
        console.log(2)
        if(!message.author.bot) {
            const Guild = client.guilds.cache.get(guildID); // Getting the guild.
            const Member = Guild.members.cache.get(message.author.id); // Getting the member.
                if (Member.voice.channel) {
                console.log(`${Member.user.tag} is connected to ${Member.voice.channel.name}!`);
                } 
                if (!Member.voice.channel) {
                console.log(`${Member.user.tag} is not connected.`);
                message.reply({ content: 'This is the voice chat channel.'})
                    .then(msg => {
                setTimeout(() => msg.delete(), 7500)
                })
            };            
        }             
    }
})

client.login(process.env.TOKEN)

遇到的问题:先加入语音频道再部署Node服务,之后离开语音频道发消息,机器人还是认为我在语音频道,不会发提示。不管我怎么切换语音状态,结果都一样,必须重启Node服务才会更新判断。我是JS和Discord.js新手,试过async函数但没解决,求帮忙。


问题原因

你现在是从Guild.members.cache里取成员数据,但Discord.js的缓存不会自动实时同步用户的语音状态变化。服务启动时缓存了用户当时的语音状态,之后的状态变更不会自动更新到缓存里,所以机器人一直用旧数据判断。


解决方法

方法1:直接用message.member获取实时成员状态

message对象自带的member属性就是当前服务器里发消息的成员实例,会实时反映最新状态,不用从全局缓存里查:

client.on('messageCreate', message => {
    console.log(1)
    if (message.content !== "" && !message.author.bot) {
        console.log(2)
        const member = message.member;
        if (member.voice.channel) {
            console.log(`${member.user.tag} is connected to ${member.voice.channel.name}!`);
        } else {
            console.log(`${member.user.tag} is not connected.`);
            message.reply({ content: 'This is the voice chat channel.'})
                .then(msg => setTimeout(() => msg.delete(), 7500))
        }            
    }
})

方法2:启用语音状态意图并监听状态更新(可选)

如果需要全局跟踪所有用户的语音状态变化,先添加GuildVoiceStates意图,再监听voiceStateUpdate事件确保缓存同步:
首先修改客户端的intents配置:

const client = new Client({
    intents: [
        GatewayIntentBits.Guilds,
        GatewayIntentBits.GuildMessages,
        GatewayIntentBits.MessageContent,
        GatewayIntentBits.GuildMembers,
        GatewayIntentBits.GuildPresences,
        GatewayIntentBits.GuildVoiceStates // 新增这个意图
    ],
});

然后添加监听事件:

client.on('voiceStateUpdate', (oldState, newState) => {
    console.log(`${newState.member.user.tag} 从 ${oldState.channel?.name || '无频道'} 切换到 ${newState.channel?.name || '无频道'}`);
    // 状态变化时缓存会自动更新,这里可按需加额外处理
});

方法3:主动拉取最新成员数据(备选)

如果必须从guild获取成员,用fetch方法主动拉取最新数据,不要依赖缓存:

client.on('messageCreate', async message => { // 加async支持await
    console.log(1)
    if (message.content !== "" && !message.author.bot) {
        console.log(2)
        const guild = client.guilds.cache.get(guildID);
        const member = await guild.members.fetch(message.author.id); // 主动获取最新数据
        if (member.voice.channel) {
            console.log(`${member.user.tag} is connected to ${member.voice.channel.name}!`);
        } else {
            console.log(`${member.user.tag} is not connected.`);
            message.reply({ content: 'This is the voice chat channel.'})
                .then(msg => setTimeout(() => msg.delete(), 7500))
        }            
    }
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 10:48:17