Discord.js messageDelete/Update事件未缓存消息报错咨询
报错原因
你写的取值代码本身存在两处API调用错误,和缓存逻辑无关:
- 消息对象上获取所属频道的属性是单数
message.channel,你写的复数message.channels本身就是undefined,自然无法读取后续的cache属性 - 文本频道对象上管理消息的管理器属性是复数
messages,你写的单数message同样是undefined,就算修正了前一个错误,这里依然会抛出相同的报错
你写的错误代码修正拼写后,正确的取值写法应该是:
message.channel.messages.cache.get(message.id)
但即便修正拼写,这个写法也解决不了未缓存消息触发事件的报错问题。
事件内能否主动补全消息缓存
不能。messageDelete事件触发时,对应消息已经在Discord服务端被删除,此时再调用接口拉取消息只会返回404错误,根本拿不到消息内容,自然无法补全缓存。messageUpdate事件触发时,如果是机器人启动前发送的旧消息,回调拿到的oldMessage参数本身是只包含消息ID、频道ID的部分结构(partial),Discord不会推送更新前的旧消息内容,你也无法通过接口拉取到历史的旧消息数据,同样没法补全缓存。
正确解决方案
按照以下两步配置即可避免未缓存消息导致的报错:
- 初始化Discord.js客户端时开启部分结构(Partials)接收权限,让机器人可以正常收到未缓存结构触发的事件,不会因为拿不到完整对象直接抛出异常:
const { Client, Partials } = require('discord.js'); const client = new Client({ intents: [ // 保留你原有配置的intents,必须包含Guilds、GuildMessages、MessageContent等消息相关权限 ], // 关键配置:开启消息、频道、服务器成员的部分结构接收 partials: [Partials.Message, Partials.Channel, Partials.GuildMember] }); - 在
messageDelete、messageUpdate事件回调开头增加partial判断,仅当消息是完整缓存对象时,再访问content、author这类需要完整数据的属性:// messageDelete事件示例 client.on('messageDelete', (message) => { // 未缓存的partial消息直接返回,或仅基于消息ID执行不需要内容的逻辑 if (message.partial) return; // 此处编写你的业务逻辑,比如删除日志记录、清理关联的机器人回复等 }); // messageUpdate事件示例 client.on('messageUpdate', async (oldMessage, newMessage) => { // 旧消息为partial说明没有缓存更新前的内容,不要访问oldMessage.content等字段 if (oldMessage.partial) { // 如果需要用到更新后的新消息内容,可以先拉取新消息的完整结构 if (newMessage.partial) await newMessage.fetch(); // 此处仅能获取更新后的新消息内容,无法拿到更新前的旧内容 return; } // 新旧消息均为完整缓存对象时,再执行内容对比、更新日志等需要旧数据的业务逻辑 });
补充:如果你需要留存所有消息的删除前、更新前内容,只能在机器人在线运行时,把所有收到的新消息主动存储到本地内存或数据库中,事件触发时用消息ID匹配你自己存储的历史数据。没有任何官方接口可以拉取到机器人离线期间发送的消息原始内容,或是已经被删除的消息内容。
内容的提问来源于stack exchange,提问作者user18793506
相关产品推荐
相关产品推荐

