如何使用quick.db搭建discord.js日志系统并解决重启后历史日志丢失问题
问题原因
- 你用到的quick.db存储日志频道ID的逻辑本身是持久化的,本次问题和quick.db无关,是discord.js的缓存机制导致的。
- discord.js的
messageUpdate事件默认仅当被编辑的消息已经存在于客户端本地缓存中时才会触发,机器人重启后所有历史消息缓存会被清空,因此编辑重启前发送的消息时,客户端无法获取到旧消息内容,事件不会正常触发。 - 你当前的代码没有开启消息Partial配置,也没有做缺失缓存的兜底处理,这也是事件不触发的核心原因。
修复方案
步骤1:调整客户端初始化配置
开启必要的意图与Partial配置,确保无缓存的消息编辑也能触发事件:
const Discord = require("discord.js") // 初始化客户端时添加intents和partials配置(discord.js v13+适用) const client = new Discord.Client({ intents: [ Discord.Intents.FLAGS.GUILDS, Discord.Intents.FLAGS.GUILD_MESSAGES ], partials: ['MESSAGE'] }) const db = require("quick.db")
步骤2:修改messageUpdate事件逻辑,添加缓存兜底
如果旧消息不在缓存中,主动调用接口拉取历史消息内容,同时补充异常捕获避免代码报错:
client.on('messageUpdate', async (oldmessage, newmessage) => { // 忽略机器人自身发送的消息,不需要记录 if (newmessage.author.bot) return // 如果旧消息是Partial状态(无本地缓存),主动拉取完整消息内容 if (oldmessage.partial) { try { await oldmessage.fetch() } catch (err) { // 拉取失败说明消息已被删除,直接结束逻辑 return } } // 修复原代码的拼写错误eddited→edited const Embed = new Discord.MessageEmbed() .setTitle("消息已编辑") .setDescription(`频道 ${newmessage.channel} 中有消息被编辑\n\n原消息内容:\`${oldmessage.content}\`\n新消息内容:\`${newmessage.content}\`\n消息发送者:\`${newmessage.author.tag}\``) .setFooter("日志系统") const channelID = db.fetch(`${newmessage.guild.id}-logChannel`) if (!channelID) return // 按ID查找频道直接用get方法,比find效率更高 const channel = newmessage.guild.channels.cache.get(channelID) // 增加频道存在判断,避免找不到频道时报错 if (channel) channel.send({embeds: [Embed]}) })
补充说明
- 如果你使用的是discord.js v12版本,不需要配置intents,仅在客户端初始化时添加
partials: ['MESSAGE']即可。 - 如果需要监控所有服务器所有频道的历史消息编辑,可以在客户端启动完成后,遍历所有有权限访问的频道拉取最近的历史消息存入缓存,注意不要一次性拉取过多消息避免触发Discord的接口限流。
- 已被删除的消息无法拉取到原内容,这种场景下不会生成编辑日志属于正常情况。
内容的提问来源于stack exchange,提问作者Cmb
相关产品推荐
相关产品推荐

