Discord.js开发snipe命令时如何清除旧Discord.MessageEmbed数据
Discord.js 开发snipe命令时MessageEmbed无法重置问题解决方案
问题现象
- 实现snipe(查询已删除消息)命令过程中,
Discord.MessageEmbed实例数据无法正常重置 - 尝试在代码不同位置将embed变量赋值为空对象
{}后,命令触发时会尝试发送空消息,直接抛出程序错误 - 测试阶段分别使用
const、let声明embed变量,均未解决重置失效问题
后续补充:在逻辑节点增加消息合法性校验后问题已解决,这类校验本应在初始开发阶段就完成配置。
问题复现代码
bot.on('messageDelete', message => { let embed = new Discord.MessageEmbed() .setAuthor(`${message.author.username} (${message.author.id})`, message.author.avatarURL()) .setDescription(message.content || "None") bot.on('message', message => { const args = message.content.slice(PREFIX.length).split(/ +/); const cmd = args.shift().toLowerCase(); if (cmd === 'msg'){ message.channel.send(embed) } }) })
核心问题原因
这个问题和变量声明方式无关,本质是事件监听器嵌套注册导致的逻辑错误:
- 每次触发
messageDelete(消息删除)事件时,代码除了新建embed实例,还会额外注册一个新的message(消息接收)事件监听器 - 这些重复注册的监听器不会自动销毁,会一直驻留内存,后续每次收到新消息,所有历史注册的监听器都会依次执行,分别发送对应历史删除消息生成的embed,逻辑完全混乱
- 直接将embed赋值为空对象
{}的操作本身不符合Discord.js API规范:message.channel.send()接收的embed参数必须是合法的MessageEmbed实例,或是符合官方embed结构的配置对象,空对象不满足发送要求,必然抛出发送空消息的错误。
修复方案
- 禁止嵌套注册事件监听器,将
message事件的监听逻辑移到messageDelete事件外层,单独用变量存储待发送的snipe embed - 所有事件入口、命令发送前都增加合法性校验,过滤机器人消息、无效结构消息、空数据场景,从源头避免异常
- 每次snipe命令执行完成后,清空存储的embed数据,实现单次查询的效果
修复后参考代码
// 外层单独定义snipe内容存储变量,不要嵌套在事件回调内部 let snipeEmbed = null; bot.on('messageDelete', message => { // 源头过滤无效删除消息:作者不存在、发送者是机器人的消息直接跳过 if (!message.author || message.author.bot) return; snipeEmbed = new Discord.MessageEmbed() .setAuthor(`${message.author.username} (${message.author.id})`, message.author.avatarURL()) .setDescription(message.content || "无文本内容") .setTimestamp(message.createdAt); }); bot.on('message', message => { // 提前过滤无效命令触发场景:机器人发的消息、前缀不匹配的消息直接跳过 if (message.author.bot || !message.content.startsWith(PREFIX)) return; const args = message.content.slice(PREFIX.length).split(/\s+/); const cmd = args.shift().toLowerCase(); if (cmd === 'msg'){ // 发送前校验是否存在有效snipe数据,没有则直接返回提示,不执行发送逻辑 if (!snipeEmbed) { return message.channel.send("当前没有可查询的已删除消息"); } message.channel.send(snipeEmbed); // 发送完成后清空存储的embed,避免重复发送旧数据 snipeEmbed = null; } });
内容的提问来源于stack exchange,提问作者kohi
相关产品推荐
相关产品推荐

