Discord.js按钮交互问题:用户频道检测逻辑失效
Discord.js 按钮点击事件中语音频道检测失效问题修复
问题背景
处理pohovor_request按钮点击事件时,需实现两个检测逻辑:
- 服务器是否存在拥有指定角色的用户(此功能正常)
- 点击按钮的用户是否处于指定语音频道(此功能失效,无论用户是否在目标频道,Bot均输出“Ok”)
问题原因
原代码中使用channel.members.has(user.id)检测用户是否在目标频道,存在两个核心问题:
channel.members依赖Bot的成员缓存,若用户未被Bot缓存(如刚加入频道、缓存未更新),会导致判断错误user是全局用户对象,直接用其ID匹配频道成员缓存,不如使用服务器成员实例(member)的语音状态信息可靠
修复方案
改用interaction.member获取点击用户的服务器成员实例,直接检查其语音频道ID是否与目标频道ID匹配,跳过缓存依赖,提升检测准确性。
修改后的完整代码
client.on('interactionCreate', async (interaction) => { if (!interaction.isButton()) return; const { customId, member, guild } = interaction; if (customId === 'pohovor_request') { const targetRoleID = roles['aktivniSpravcePohovoru']; const targetChannelID = channels['cekarna']; const role = guild.roles.cache.get(targetRoleID); // 用some()替代filter.size,无需创建新数组,性能更优 if (!role || !guild.members.cache.some(m => m.roles.cache.has(role.id))) { await interaction.reply('Je nám líto, ale momentálně na serveru není nikdo s požadovanou rolí.'); return; } // 直接检查成员当前语音频道ID是否匹配目标频道 if (!member.voice.channelId || member.voice.channelId !== targetChannelID) { await interaction.reply('Je nám líto, ale musíte být připojeni ve specifickém hlasovém kanálu pro žádost o pohovor.'); return; } console.log("Ok"); } });
关键修改说明
- 替换
user为member:interaction.member是用户在当前服务器的成员实例,包含完整的服务器内状态信息(如语音状态),比全局user对象更适合服务器内的权限/状态检测。 - 直接检查语音频道ID:
member.voice.channelId直接返回用户当前所在语音频道的ID(若未在频道则为null),无需依赖频道成员缓存,结果更准确且性能更好。 - 优化角色检测逻辑:使用
Array.some()替代filter().size,只要找到一个符合条件的成员就停止遍历,避免不必要的数组创建,提升代码效率。
内容的提问来源于stack exchange,提问作者dargr
相关产品推荐
相关产品推荐

