Discord Bot JS:触发stop子命令时如何编辑play斜杠命令发送的embed回复
解决方案
核心原因:play和stop是两个独立触发的斜杠子命令,对应两个完全独立的interaction实例,stop的interaction.editReply只会修改stop命令自身的回复,和之前play命令的回复没有关联。
你可以通过内存存储(或持久化存储)绑定对应服务器/语音频道的播放消息ID,实现跨命令修改,具体实现如下:
具体实现步骤
- 第一步:在全局作用域声明存储对象,用来保存每个服务器对应的播放消息实例
// 全局声明,键为服务器ID(guildId),值为play命令发送的embed消息对象 const guildPlayMessages = new Map();
- 第二步:修改play子命令逻辑,发送embed后把返回的消息存入存储对象
注意要给异步方法加await,否则无法拿到发送完成的消息对象:
//PLAY COMMAND if (options === 'play') { const PlayEmbed = new MessageEmbed() PlayEmbed.setColor('#007DD1') PlayEmbed.setDescription(`${track.title}`) // 等待消息发送完成,拿到返回的消息对象 const playMsg = await interaction.editReply({embeds: [PlayEmbed]}) // 将消息存入全局Map,用当前服务器ID当键 guildPlayMessages.set(interaction.guild.id, playMsg) }
- 第三步:修改stop子命令逻辑,取出存储的play消息进行编辑
//STOP COMMAND if (options === 'stop') { const EndEmbed = new MessageEmbed() EndEmbed.setColor('#007DD1') EndEmbed.setDescription(`The music stopped!`) // 从全局Map取出当前服务器对应的play消息 const targetPlayMsg = guildPlayMessages.get(interaction.guild.id) if (targetPlayMsg) { try { // 编辑原有play embed await targetPlayMsg.edit({embeds: [EndEmbed]}) // 编辑完成后删除对应存储记录 guildPlayMessages.delete(interaction.guild.id) } catch (err) { // 消息被删除/无编辑权限时的错误处理,可自行打印日志或忽略 console.error('无法编辑播放消息', err) } } // 按需给stop命令自身返回提示,也可以直接结束逻辑 await interaction.editReply({content: '已停止播放'}) }
补充说明
- 如果你的bot支持同一个服务器多个语音频道同时播放,可以把Map的键改为
${interaction.guild.id}-${interaction.member.voice.channel.id},用服务器ID+语音频道ID的组合区分不同频道的播放消息 - 内存存储的Map会在bot重启后清空,如果你需要持久化保存可以将消息ID存入本地JSON文件或者数据库,调用时先通过ID fetch到消息再编辑即可
- 所有涉及消息发送、编辑的异步方法都要配套
async/await使用,避免出现未捕获的Promise报错
内容的提问来源于stack exchange,提问作者lucasrvimieiro
相关产品推荐
相关产品推荐

