Discord.js机器人执行语音播放命令后提示‘应用未回复’求助
问题原因及修复方案
核心问题
- 未回复Slash命令交互:Discord要求Slash命令必须在3秒内对
interaction进行回复,你的代码完全没处理回复,直接触发超时提示。 - 错误注册
ready事件:机器人启动时ready事件就已经触发了,在命令执行函数里再注册这个事件,永远不会被触发,导致后续逻辑根本没跑。 - 缺少语音相关意图:当前的intents没有包含
GuildVoiceStates,无法正确获取用户的语音频道信息。 - 冗余的缓存获取逻辑:可以直接通过
interaction对象拿到guild和member,不用从cache手动查找。
修正后的代码
const { SlashCommandBuilder, Client, GatewayIntentBits } = require('discord.js'); // 补充语音状态意图,确保机器人能读取语音频道信息 const client = new Client({ intents: [ GatewayIntentBits.Guilds, GatewayIntentBits.GuildMembers, GatewayIntentBits.GuildVoiceStates // 新增:获取语音频道状态的必要意图 ] }); module.exports = { data: new SlashCommandBuilder() .setName('suono') .setDescription('fa un suono'), async execute(interaction) { // 先回复交互避免超时,用deferReply可以后续更新回复内容 await interaction.deferReply({ ephemeral: true }); // 直接从interaction获取用户所在的语音频道 const voiceChannel = interaction.member.voice.channel; if (!voiceChannel) { return interaction.editReply('你得先进入一个语音频道才能执行这个命令!'); } try { // 加入语音频道并播放音频 const connection = await voiceChannel.join(); const dispatcher = connection.play('./1.mp3'); // 播放结束后退出频道并告知用户 dispatcher.on('end', () => { voiceChannel.leave(); interaction.editReply('音频播放完毕,已退出语音频道'); }); // 捕获播放错误 dispatcher.on('error', (err) => { console.error(err); voiceChannel.leave(); interaction.editReply('播放音频时出错:' + err.message); }); } catch (err) { // 捕获加入频道的错误 console.error(err); interaction.editReply('无法加入语音频道:' + err.message); } }, };
关键修改说明
- 补充
GuildVoiceStates意图:没有这个意图,机器人无法读取用户的语音频道状态,会导致voiceChannel为undefined。 - 立即回复交互:用
deferReply先告知Discord正在处理,避免超时,后续通过editReply更新最终回复内容。 - 移除无效的
ready事件注册:直接在命令执行函数内处理逻辑,无需等待已触发过的ready事件。 - 简化频道获取逻辑:通过
interaction.member.voice.channel直接获取用户所在的语音频道,无需手动查询缓存。 - 完善错误处理:捕获加入频道、播放音频过程中的错误,及时给用户反馈,同时确保出错后机器人退出语音频道。
- 移除冗余的
isReady变量:该变量逻辑不合理,会导致多次执行命令时无法触发功能,直接移除即可。
内容的提问来源于stack exchange,提问作者Nick Picco
相关产品推荐
相关产品推荐

