Discord.js V14 Bot问题:AuditLogs无法返回特定事件正确数据
问题描述
开发Discord日志机器人时,处理channelDelete事件获取AuditLogs条目出现异常:当非机器人/消息作者的用户删除频道时,executor(执行者)和target(目标)信息指向之前删除操作的记录,但频道数据是正确的。
示例流程:
- 用户A发送消息→用户B删除;
- 用户B发送消息→用户A删除;
两次日志的执行者均显示为用户B,目标均为用户A。
尝试添加setTimeout(() => {...}, 2500);延迟获取日志,问题仍未解决。
相关代码:
const AuditLogFetch = await channel.guild.fetchAuditLogs({ limit: 1, type: auditType, }); if (!AuditLogFetch.entries.first()) return console.error(`No entries found.`); const entry = AuditLogFetch.entries.first(); let parentChannel = null; if (entry.channelParentId) parentChannel = channel.guild.channels.cache.get(channel.parentId).toString(); const chDeleteEmbed = { color: colors.DARK_RED, author: { name: `${entry.globalName != null ? entry.globalName : 'No nickname'} [${entry.username != null ? entry.username : 'No username'}]`, icon_url: entry.displayAvatarURL() }, description: `${channel.type} deleted by <@${entry.executor.id}> ${parentChannel != null ? `In category: ${parentChannel}` : '' }`, fields: [ { name: 'Nome canale', value: `${channel.name}` } ], } // send embed func ... })
问题原因与修复方案
核心问题
仅通过limit:1获取最新一条审计日志,这条日志未必对应当前触发的channelDelete事件——短时间内有多个同类型操作时,第一条日志可能是上一次的操作记录,导致执行者/目标信息错位。
修复步骤
- 筛选匹配当前频道的审计日志
获取审计日志后,不能直接取第一条,需筛选出target.id与被删除频道ID一致的条目,确保拿到当前事件对应的记录:
const AuditLogFetch = await channel.guild.fetchAuditLogs({ limit: 5, // 适当提高条数,覆盖短时间批量操作场景 type: auditType, }); // 筛选目标频道匹配的审计日志条目 const entry = AuditLogFetch.entries.find(entry => entry.target?.id === channel.id); if (!entry) return console.error(`No matching audit log entry found for channel ${channel.id}`);
- 优化延迟与重试机制(可选)
若日志存在写入延迟,可结合重试逻辑替代固定延迟,提升可靠性:
async function getMatchingAuditLog(guild, channelId, auditType, retries = 3, delay = 1000) { for (let i = 0; i < retries; i++) { const logs = await guild.fetchAuditLogs({ limit: 5, type: auditType }); const entry = logs.entries.find(e => e.target?.id === channelId); if (entry) return entry; await new Promise(resolve => setTimeout(resolve, delay)); } return null; } // 使用方式 const entry = await getMatchingAuditLog(channel.guild, channel.id, auditType); if (!entry) return console.error(`Failed to find audit log after retries`);
- 修复代码中的细节错误
- 分类频道获取逻辑错误:应使用
entry.channelParentId而非channel.parentId:if (entry.channelParentId) parentChannel = channel.guild.channels.cache.get(entry.channelParentId).toString(); - 用户信息获取错误:
globalName、username和头像应从entry.executor对象获取,而非直接从entry取:author: { name: `${entry.executor.globalName ?? 'No nickname'} [${entry.executor.username ?? 'No username'}]`, icon_url: entry.executor.displayAvatarURL() },
内容的提问来源于stack exchange,提问作者Mattia
相关产品推荐
相关产品推荐

