DiscordJS V13如何检测用户是否在语音频道?缓存不更新问题求解
问题原因
discord.js 会默认缓存成员的语音状态数据,你代码中调用的interaction.member.fetch()仅会刷新成员的基础账号信息,不会同步更新语音状态,因此没有开启语音状态监听的情况下,缓存数据不会自动更新,就会出现始终拿到启动时旧状态的问题。
修复方案
方案一:开启语音状态网关意图(推荐)
初始化 Client 实例时添加GuildVoiceStates网关意图,开启后机器人会自动监听服务器内所有语音状态变更事件,实时更新本地缓存,无需额外编写刷新逻辑。
初始化示例代码:
import { Client, GatewayIntentBits } from 'discord.js'; const client = new Client({ intents: [ GatewayIntentBits.Guilds, // 基础服务器意图必须保留 GatewayIntentBits.GuildVoiceStates, // 新增语音状态意图 // 其他你用到的意图正常保留即可 ] });
方案二:修改指令逻辑主动获取实时状态
如果你暂时不想调整意图配置,直接修改play指令的逻辑即可,无需额外fetch成员信息:
export const interactionListener = async (interaction, client) => { if (!interaction.isCommand()) return; const { commandName } = interaction; switch (commandName) { case 'play': // 直接从当前服务器缓存中取实时成员状态 const member = interaction.guild.members.cache.get(interaction.user.id); const channel = member.voice.channel; if (!channel) { // 注意必须响应用户交互,否则会出现交互超时报错 await interaction.reply('你当前不在语音频道中'); } else { await interaction.reply('执行后续逻辑'); } } };
额外注意点
- 你的原代码中
let channel = await user.voice.channel;里的await是多余的,voice.channel是同步属性,不需要异步等待 - 交互触发后必须调用
interaction.reply()或者interaction.deferReply()响应,否则3秒后会报交互未响应的错误
内容的提问来源于stack exchange,提问作者user3643309
相关产品推荐
相关产品推荐

