Discord机器人Radio命令报错:InteractionNotReplied问题求助
解决Discord机器人Radio斜杠命令的InteractionNotReplied错误
错误原因
报错核心问题有两个:
- 组件收集器的
collect事件中,你直接调用interaction.editReply(),但这里的interaction是SelectMenuInteraction(用户选择菜单触发的新交互),而非最初的斜杠命令交互。组件交互必须先被回复/延迟,才能执行编辑操作。 - 当用户不在语音频道时,你先执行了
deferReply,之后又调用reply,这会触发冲突——延迟回复后必须用editReply来更新内容,不能再用reply。
修复步骤
- 区分交互对象:将collect事件的参数重命名(比如改成
selectInteraction),避免和外层的斜杠命令交互变量重名,防止逻辑混淆。 - 修正语音频道检查逻辑:延迟回复后,用
editReply替代reply来更新提示内容。 - 正确处理组件交互:对于菜单选择的交互,直接用
update()替换原消息(包含移除选择菜单),无需额外延迟操作,更符合组件交互的响应规范。
修改后的完整代码
const { ActionRowBuilder, SelectMenuBuilder, SlashCommandBuilder, } = require("discord.js"); const { joinVoiceChannel, createAudioResource, createAudioPlayer, } = require("@discordjs/voice"); const radioAssets = require("../../../Util/radioChannels.json"); module.exports = { data: new SlashCommandBuilder() .setName("radio") .setDescription("📻 | Listen to the radio!"), async execute(interaction) { await interaction.deferReply({ ephemeral: true }); const channel = interaction.member.voice.channel; if (!channel) { // 修正:defer后使用editReply更新内容 return interaction.editReply({ content: "You need to join a voice channel to do this!", }); } const getRadioChannel = radioAssets.channel.map((rad) => ({ label: rad.nativeName, value: rad.name, })); const radioMenu = new ActionRowBuilder().addComponents( new SelectMenuBuilder() .setCustomId("radioList") .setPlaceholder("Select a radio channel!") .addOptions(getRadioChannel) ); const msg = await interaction.editReply({ content: "Please select one of the Radio channel that are listed below!", components: [radioMenu], fetchReply: true, }); const filter = (i) => { if (interaction.user.id !== i.user.id || i.customId !== "radioList") { i.followUp({ content: "This menu is not for you!", ephemeral: true, }); return false; } else { return true; } }; const collector = msg.createMessageComponentCollector({ filter, time: 30000, }); // 重命名参数避免和外层交互混淆 collector.on("collect", async (selectInteraction) => { const findRadio = radioAssets.channel.find( (rad) => rad.name === selectInteraction.values.toString() ); const player = createAudioPlayer(); const resource = createAudioResource(findRadio.uri); let connection = joinVoiceChannel({ guildId: selectInteraction.guild.id, channelId: channel.id, adapterCreator: selectInteraction.guild.voiceAdapterCreator, selfDeaf: true, selfMute: false, }); player.play(resource); connection.subscribe(player); // 修正:用update直接更新原组件消息,同时移除菜单防止重复触发 await selectInteraction.update({ content: "Radio has started successfully! Please do not undeafen me so I cannot hear your conversations while playing my music.", components: [], ephemeral: true, }); await selectInteraction.channel .send({ content: `Started playing **${findRadio.nativeName}** in <#${channel.id}>`, }) .then((msg) => msg.guild.me.voice.setSuppressed(false)) .catch((err) => console.error(err)); // 修正笔误:console.err → console.error }); }, };
额外说明
- 修复了代码中的笔误:
console.err改为console.error,避免控制台报错。 - 在
update()中添加components: [],移除选择菜单,防止用户重复选择触发多次操作。
内容的提问来源于stack exchange,提问作者Fawnino
相关产品推荐
相关产品推荐

