discord.js通过msg.reference获取引用消息embeds报TypeError排查
问题根因
- 属性名拼写错误:discord.js 里消息引用的ID字段是小驼峰格式的
messageId,你代码里写的messageID(ID全大写)本身就是undefined,你还给这个值加了多余的await,虽然不会直接抛语法错误,但会导致fetch接口拿到的参数异常,根本没拉到你要的目标消息。 - 控制台日志误导:
console.log打印对象时是懒解析的,你在控制台展开看到的embeds: [ [MessageEmbed] ]是日志打印后对象被更新的状态,不是你执行到取embeds那行时的真实数据,当时拿到的消息对象本身就不完整。 - 缺失边界判断:你没做任何校验就直接取
embeds[0],只要被回复的消息没有embed、或者消息拉取失败,就会触发你看到的类型错误。
修复步骤
- 把错误的属性名
messageID改成正确的messageId,去掉前面多余的await - 调用fetch接口时传入
{ force: true }参数,跳过本地缓存直接从Discord接口拉取完整的消息数据,避免拿到缓存里的残缺对象 - 取embed前先判断embeds数组是否存在、长度是否大于0,兼容被回复消息无embed的场景
- 非强制优化:把discord.js相关依赖的require语句移到文件顶部,不要在每次命令执行时重复加载模块
修复后代码
// 以下依赖声明放到文件最顶部,不要写在run函数内部 const { MessageActionRow, MessageButton, MessageEmbed } = require('discord.js'); module.exports.run = async (client, msg, args) => { if (args.length === 5) { // 先判断是否存在有效消息引用 if (msg.reference?.messageId) { // 跳过缓存拉取完整的被回复消息 const fetchedMsg = await msg.channel.messages.fetch(msg.reference.messageId, { force: true }); // 校验消息是否包含embed if (fetchedMsg.embeds?.length) { const targetEmbed = fetchedMsg.embeds[0]; console.log(targetEmbed); // 这里写你处理embed的业务逻辑 } else { msg.reply('当前回复的消息没有包含Embed内容,无法执行操作'); } } else { msg.reply('请先回复需要读取的目标消息,再执行此命令'); } // 其余原有逻辑 } }
补充说明:如果你用的是discord.js v13及以上版本,必须去Discord开发者后台对应机器人的设置页,开启「Message Content Intent」权限,否则机器人无法获取到消息的完整内容,包括embed数据。
内容的提问来源于stack exchange,提问作者gabegad123
相关产品推荐
相关产品推荐

