You need to enable JavaScript to run this app. Discord.js中检测指定提及用户语音状态变化并触发音频播放的问题
优惠活动
大模型
产品
解决方案
定价
更多

Discord.js中检测指定提及用户语音状态变化并触发音频播放的问题

问题原因与修复方案

问题根源

  • 变量名冲突:外层message事件中定义的被@目标用户变量名为user,与speaking事件回调的入参user重名,回调作用域内会优先读取当前触发事件的发言用户,覆盖了外层的指定目标用户,无法做匹配校验
  • 缺少目标用户过滤逻辑:speaking事件的触发判断仅检查了用户存在、用户正在发言两个条件,没有校验触发用户是否为你之前@指定的用户,导致所有频道内发言用户都会触发音频播放

修复后的代码

client.on('message', async message => {
    const voiceChannel = message.member.voice.channel;
    // 变量改名避免和speaking回调的入参冲突
    let targetUser = message.mentions.users.first();
    let cleanMessage = message.content.toLowerCase();

    // 先检查消息是否包含有效指令
    if (!cleanMessage.match(start) && !cleanMessage.startsWith('quit') && !targetUser) return;

    // 加入频道的逻辑
    if (cleanMessage.match(start) && targetUser && voiceChannel) {
        console.log('已连接!');
        
        voiceChannel.join()
        .then(connection => {
            connection.on('speaking', (currentUser, speaking) => {
                // 新增判断:当前发言用户是指定的目标用户再触发播放
                if(currentUser && speaking && currentUser.id === targetUser.id) {
                    // 给dispatch加声明避免变成全局变量
                    const dispatch = connection.play(fs.createReadStream(require("path").join(__dirname, './shush.webm')), { type: 'webm/opus'});
                    console.log(currentUser);
                }
            })

            console.log(`${targetUser.username} 已被禁言提醒!`);
            setTimeout(() => { voiceChannel.leave() }, 10000);
        }).catch(err => console.log(err));

        message.channel.send(`${targetUser.username} 安静点。`);
    }
})

改动点说明

  • 将外层被@的目标用户变量从user改名为targetUser,避免和speaking回调的入参currentUser重名冲突
  • speaking事件的触发判断中新增currentUser.id === targetUser.id的匹配逻辑,仅当指定用户发言时才会播放音频
  • 给dispatch变量添加const声明,避免意外泄漏为全局变量

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.18 15:27:03