discord.js v13封禁成员日志重复发送,踢人正常问题求助
解决Discord封禁日志重复发送两条消息的问题
问题根源
封禁成员时会同时触发两个Discord事件:
guildBanAdd:成员被封禁的专属事件,你的代码已正确处理并发送封禁日志guildMemberRemove:成员离开服务器(封禁操作会强制成员离开,因此也会触发该事件)
你的旧代码中,guildMemberRemove存在两个关键问题:
- 错误引用了未定义的
ban.user.id(应为member.user.id) - 未区分成员离开的原因,导致封禁触发的
guildMemberRemove也尝试发送日志,最终造成重复
修正后的代码
封禁检测代码(优化版)
const { AuditLogEvent } = require('discord.js'); client.on('guildBanAdd', async (ban) => { const fetchedLogs = await ban.guild.fetchAuditLogs({ limit: 1, type: AuditLogEvent.MemberBanAdd, // 使用官方枚举更规范 }); const banLog = fetchedLogs.entries.first(); if (!banLog) return; const { executor, target } = banLog; if (target.id === ban.user.id) { const channel = client.channels.cache.get("954475961234116719"); if (!channel) return; // 避免频道不存在时抛出错误 channel.send(`<@${ban.user.id}> was Banned by <@${executor.id}>`); } });
踢出检测代码(修复重复问题)
client.on('guildMemberRemove', async (member) => { const fetchedLogs = await member.guild.fetchAuditLogs({ limit: 1 }); const latestLog = fetchedLogs.entries.first(); if (!latestLog) return; // 如果是封禁导致的成员离开,直接跳过(guildBanAdd已处理) if (latestLog.action === AuditLogEvent.MemberBanAdd) return; // 仅处理踢人事件 if (latestLog.action === AuditLogEvent.MemberKick) { const { executor, target } = latestLog; if (target.id === member.user.id) { const channel = client.channels.cache.get("954475961234116719"); if (!channel) return; channel.send(`<@${member.user.id}> was kicked by <@${executor.id}>`); } } });
修复逻辑说明
- 在
guildMemberRemove事件中,先获取最新的一条审计日志,判断事件类型 - 如果是
MemberBanAdd(封禁事件),直接跳过处理,避免和guildBanAdd的日志重复 - 仅当事件类型为
MemberKick(踢人事件)时,才发送踢人日志 - 增加了频道存在性判断,避免因频道被删除等情况抛出错误
内容的提问来源于stack exchange,提问作者Pooyan
相关产品推荐
相关产品推荐

