百色市网站建设_网站建设公司_前端工程师_seo优化
2026/1/16 16:00:40 网站建设 项目流程

在 discord.js 里想“追踪是谁删了消息”,本质要把两条线合并:
1)messageDelete告诉你“哪条消息没了”;2)审计日志(Audit Log)告诉你“谁执行了删除”。但必须先讲清边界:用户自己删除自己的消息,审计日志通常不会记录执行者;某些机器人/系统删除也可能不进审计日志,所以你要接受“有时只能判定为自删/未知”。(GitHub)


一、可落地的方案(企业审计思路)🙂

flowchart TD A[messageCreate 记录快照<br/>内容/作者/频道/附件] --> B[messageDelete 触发] B --> C{是否是服务器消息?} C -->|是| D[等待 1~2 秒<br/>审计日志异步落地] D --> E[fetchAuditLogs(MESSAGE_DELETE)] E --> F{是否匹配同频道+同作者+时间窗口} F -->|匹配| G[executor = 删除者] F -->|不匹配| H[标记:自删或未知] C -->|否| I[DM 无审计日志<br/>只能未知]

二、关键点对齐表(先定规则,后面才稳定)

你想拿到的字段来源是否稳定备注
被删消息的 作者、频道、IDmessageDelete(需缓存/partials)消息若不在缓存里,会拿不到完整内容(discordjs.guide)
被删消息的 内容只能靠你“事前缓存快照”低(不做缓存=拿不到)消息删了就无法再从 API 拉回内容(discordjs.guide)
真正执行删除的 操作者Audit LogMESSAGE_DELETEexecutor中-高需要ViewAuditLog权限;并处理“时间差/误匹配”(discordjs.guide)
自删判定Audit Log 不匹配 + 作者=删除主体自删常常无审计记录(GitHub)

三、discord.js v14 参考实现(含缓存 + 审计匹配)✅

前提:Bot 需要服务器权限 ViewAuditLog;若你要直接接收审计事件,还需GuildModerationintent。(discordjs.guide)

1)Client 初始化(意图 + Partials)

const { Client, GatewayIntentBits, Partials, AuditLogEvent, Events } = require('discord.js'); const client = new Client({ intents: [ GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.MessageContent, // 需要记录内容时才开(受限意图) GatewayIntentBits.GuildModeration, // 想用审计事件/更稳的审计链路时开 ], partials: [Partials.Message, Partials.Channel], });

解释:

  • GuildMessages:才能收到频道消息相关事件。

  • MessageContent:你要“记录内容快照”才有意义;不开就只能记录作者/ID/附件等。

  • partials:保证删消息事件在部分情况下仍能触发并拿到基本字段;但注意:删后不可再 fetch 回消息内容。(discordjs.guide)

2)建立“消息快照缓存”(解决删后无法取内容)

const cache = new Map(); // messageId -> snapshot const TTL_MS = 10 * 60 * 1000; // 10分钟窗口(按你需求调) client.on(Events.MessageCreate, (msg) => { if (!msg.guild || msg.author?.bot) return; cache.set(msg.id, { id: msg.id, guildId: msg.guild.id, channelId: msg.channel.id, authorId: msg.author.id, authorTag: msg.author.tag, content: msg.content ?? '', createdAt: msg.createdTimestamp, }); // 简单 TTL 清理(务实版) setTimeout(() => cache.delete(msg.id), TTL_MS).unref?.(); });

解释:

  • 这一步是“取证前置”:不提前存,删了就没内容可追。(discordjs.guide)

  • TTL 让内存可控,避免缓存无限增长。

3)删除事件里追踪“执行删除的人”(审计日志匹配)

client.on(Events.MessageDelete, async (msg) => { if (!msg.guild) return; const snap = cache.get(msg.id); // 可能为空:机器人重启/未缓存 const channelId = msg.channel?.id || snap?.channelId; // 审计日志写入有延迟,等一下更稳 await new Promise(r => setTimeout(r, 1200)); // 拉最近几条 MESSAGE_DELETE 记录 const logs = await msg.guild.fetchAuditLogs({ type: AuditLogEvent.MessageDelete, limit: 6 }); const now = Date.now(); // 注意:审计日志的 target 往往是“被删消息的作者用户”,不是 messageId const entry = logs.entries.find(e => { const within = now - e.createdTimestamp < 5000; // 5秒窗口,避免误匹配 const sameChannel = (e.extra?.channel?.id === channelId); const sameTarget = (snap?.authorId ? e.target?.id === snap.authorId : true); return within && sameChannel && sameTarget; }); const executor = entry?.executor; // 真正点了删除的人(若存在) const result = { messageId: msg.id, channelId, author: snap?.authorTag || msg.author?.tag || 'unknown', deleter: executor ? `${executor.tag}` : 'self/unknown', content: snap?.content || '(not cached)', }; console.log(result); });

解释:

  • fetchAuditLogs需要 ViewAuditLog 权限,否则拿不到审计链路。(Discord)

  • 用 “时间窗口 + 同频道 + 同作者” 三条件匹配,解决常见的“误把上一条删除记录当成这条”的问题。

  • deleter = self/unknown并不敷衍,是现实约束:自删通常没有审计记录,你只能给出合规的结论。(GitHub)


四、实战建议(降低误判与投诉成本)🙂

  1. 把 窗口 做成可配置:高频删帖群可用 3 秒;低频可 8 秒。

  2. 记录时输出“证据三件套”:频道、作者、执行者(以及内容是否缓存)。

  3. 如果你要“更实时更稳”,可以同时监听guildAuditLogEntryCreate做审计事件驱动(同样要求权限与 intent)。(discordjs.guide)

如果你告诉我你用的是 discord.js 的具体大版本(v14.x 还是更早)以及你想记录到哪里(文件/数据库/指定日志频道),我可以把上面代码收敛成一份“可直接上线”的模块化实现(含并发控制、去重、防刷与日志格式标准)。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询