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

Discord语音机器人报错修复及个性化音效实现咨询

Discord语音机器人报错修复与多用户专属音效实现

问题场景

开发Discord语音机器人时,触发voiceStateUpdate事件时报错,机器人无法正常加入频道播放指定intro音效,终端输出如下:

运行命令

cd "C:\javacode\Discord Audio Bot"
node Audio.js

报错信息

On
C:\javacode\Discord Audio Bot\Audio.js:29
  } else if (newState.channel.members.size = 1) {
                              ^

TypeError: Cannot read properties of null (reading 'members')
    at Client.<anonymous> (C:\javacode\Discord Audio Bot\Audio.js:29:31)
    at Client.emit (node:events:513:28)
    at VoiceStateUpdate.handle (C:\javacode\Discord Audio Bot\node_modules\discord.js\src\client\actions\VoiceStateUpdate.js:38:14)
    at module.exports [as VOICE_STATE_UPDATE] (C:\javacode\Discord Audio Bot\node_modules\discord.js\src\client\websocket\handlers\VOICE_STATE_UPDATE.js:4:35)
    at WebSocketManager.handlePacket (C:\javacode\Discord Audio Bot\node_modules\discord.js\src\client\websocket\WebSocketManager.js:352:31)
    at WebSocketShard.onPacket (C:\javacode\Discord Audio Bot\node_modules\discord.js\src\client\websocket\WebSocketShard.js:489:22)
    at WebSocketShard.onMessage (C:\javacode\Discord Audio Bot\node_modules\discord.js\src\client\websocket\WebSocketShard.js:328:10)
    at callListener (C:\javacode\Discord Audio Bot\node_modules\ws\lib\event-target.js:290:14)
    at WebSocket.onMessage (C:\javacode\Discord Audio Bot\node_modules\ws\lib\event-target.js:209:9)
    at WebSocket.emit (node:events:513:28)

原代码

console.log('On');
const { Client, GatewayIntentBits } = require('discord.js');
const client = new Client({
  intents: [
    GatewayIntentBits.GuildVoiceStates,
    GatewayIntentBits.GuildMembers
  ]

});

client.on('voiceStateUpdate', (_oldState, newState) => {
  // Check if the user who joined is the specific user we want
  if (newState.member.id === 'STtheGamer') {
      // Check if the user joined a voice channel
      if (newState.channel) {
          // Join the voice channel and play the specific sound
          newState.channel.join()
              .then(connection => {
                  // Replace 'song.mp3' with the path to the audio file you want to play
                  const dispatcher = connection.play('C:\Users\storr\Music\botsounds\swtheme.mp3');

                  // Leave the voice channel after the sound is played
                  dispatcher.on('finish', () => {
                      newState.channel.leave();
                  });
              })
              .catch(console.error);
      }
  } else if (newState.channel.members.size = 1) {
      if (newState.channel) {
          newState.channel.leave()
              .catch(console.error);
      }
  }

});

client.login('botkey here');

报错原因与修复

核心错误点

  1. 赋值运算符误用:else if条件中用=赋值而非===比较,逻辑错误且触发无效操作
  2. 空值未校验:用户离开频道时newState.channel为null,直接访问members会抛出类型错误
  3. 路径转义问题:Windows路径的\需转义为\\,否则会被解析为转义字符导致音频文件找不到
  4. 用户ID判断错误:newState.member.id对应用户数字ID,而非用户名STtheGamer
  5. 缺失必要意图:未添加Guilds意图,可能导致频道数据无法正常获取

修复后代码(含多用户音效实现)

console.log('On');
const { Client, GatewayIntentBits } = require('discord.js');
const client = new Client({
  intents: [
    GatewayIntentBits.GuildVoiceStates,
    GatewayIntentBits.GuildMembers,
    GatewayIntentBits.Guilds // 新增必要意图
  ]
});

// 多用户专属音效映射:用户数字ID -> 音效文件路径
const userIntroSounds = {
  '用户1的数字ID': 'C:\\Users\\storr\\Music\\botsounds\\user1.mp3',
  '用户2的数字ID': 'C:\\Users\\storr\\Music\\botsounds\\user2.mp3',
  'STtheGamer的数字ID': 'C:\\Users\\storr\\Music\\botsounds\\swtheme.mp3'
};

client.on('voiceStateUpdate', (_oldState, newState) => {
  // 判断用户是加入还是离开频道
  const isJoining = !_oldState.channel && newState.channel;
  const isLeaving = _oldState.channel && !newState.channel;

  if (isJoining) {
    const userId = newState.member.id;
    // 检查当前用户是否有专属音效
    if (userIntroSounds[userId]) {
      newState.channel.join()
        .then(connection => {
          const dispatcher = connection.play(userIntroSounds[userId]);
          // 播放完成后,仅频道只剩机器人时离开
          dispatcher.on('finish', () => {
            if (newState.channel.members.size === 1) {
              newState.channel.leave();
            }
          });
          dispatcher.on('error', console.error);
        })
        .catch(console.error);
    }
  } else if (isLeaving) {
    // 用户离开后,检查原频道是否只剩机器人,是则离开
    if (_oldState.channel.members.size === 1) {
      _oldState.channel.leave().catch(console.error);
    }
  }
});

client.login('你的机器人Token');

多用户专属音效实现说明

  1. 音效映射表:用对象userIntroSounds存储用户ID与对应音效路径的映射,新增/修改用户音效只需更新该对象
  2. 精准状态判断:通过对比新旧状态的频道信息,避免无效逻辑触发,只在用户真正加入/离开时执行对应操作
  3. 智能离开逻辑:播放完成或用户离开后,仅当频道内只剩机器人时才退出,避免影响其他用户

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 05:20:29