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

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");
  }
});

关键修改说明

  1. 替换user为member:interaction.member是用户在当前服务器的成员实例,包含完整的服务器内状态信息(如语音状态),比全局user对象更适合服务器内的权限/状态检测。
  2. 直接检查语音频道ID:member.voice.channelId直接返回用户当前所在语音频道的ID(若未在频道则为null),无需依赖频道成员缓存,结果更准确且性能更好。
  3. 优化角色检测逻辑:使用Array.some()替代filter().size,只要找到一个符合条件的成员就停止遍历,避免不必要的数组创建,提升代码效率。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 17:58:31