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

Discord.js v12监听用户加入语音频道发消息无响应及报错问题

问题原因&解决方案

第一个版本(无触发无报错)的问题

  • 你在文件顶部单独new Discord.Client()创建的client实例没有经过登录流程,和你框架run方法传入的已登录client是完全独立的两个实例,你把voiceStateUpdate事件绑定到了未登录的空client上,自然不会触发任何事件回调。

第二个版本(报错Cannot read property 'channelID' of undefined)的问题

  • discord.js v12的voiceStateUpdate事件返回的newState本身就是VoiceState类型的对象,直接自带channelID属性,不需要额外加.voice字段,你多写的.voice层级不存在,所以触发了空指针报错。
  • 同时voiceStateUpdate事件默认返回两个参数:oldState(用户更新前的语音状态)、newState(用户更新后的语音状态),只拿一个参数会导致逻辑判断有漏洞,比如用户在目标语音频道内静音、调整音量也会重复触发提醒。

修复后的可用代码

const BaseEvent = require('../../utils/structures/BaseEvent');

module.exports = class ReadyEvent extends BaseEvent {
  constructor() {
    super('ready');
  }
  async run (client) {
    console.log(`Bot prêt, connecté en tant qu'${client.user.username}!`);
    // 绑定事件到已登录的client实例,同时接收两个状态参数
    client.on('voiceStateUpdate', (oldState, newState) => {
      // 直接取newState的channelID,不需要加.voice
      const oldChannelId = oldState.channelID;
      const newChannelId = newState.channelID;
      const targetSupportChannelId = '815316796067414016';
      const notifyTextChannelId = '815316823275995139';
      const managerRoleId = '753367852299321404';

      // 仅当用户从其他频道进入目标支持频道时触发,避免重复提醒
      if (newChannelId === targetSupportChannelId && oldChannelId !== targetSupportChannelId) {
        const textChannel = client.channels.cache.get(notifyTextChannelId);
        // 加个容错,避免频道不存在导致崩溃
        if (!textChannel) return;
        textChannel.send(`Hey ! Le <@&${managerRoleId}>, ${newState.member.user.username} (${newState.id}) est en Attente de Support !`);
      }
    }); 
  }
}

额外注意点

  • 不需要在文件顶部重复创建client实例,也不需要额外引入未用到的DiscordAPIError、Discord变量,避免冗余代码。
  • 增加了状态对比逻辑,只有用户刚进入目标语音频道时才会发提醒,不会出现重复@的情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.17 15:54:00