Discord.js身份组日志系统如何获取操作身份组的执行人员信息
解决方案
guildMemberUpdate事件本身不会直接返回操作人信息,你需要拉取服务器审计日志中最近的MEMBER_ROLE_UPDATE类型记录,匹配到本次身份组变动对应的操作人。
前置要求:必须给机器人授予
VIEW_AUDIT_LOG(查看审计日志)权限,否则无法拉取审计日志数据。
修改后的完整代码如下:
client.on("guildMemberUpdate", async (oldMember, newMember) => { const guild = oldMember.guild; const oldRoles = oldMember.roles.cache; const newRoles = newMember.roles.cache; // 非身份组变动直接跳过 if (oldRoles.size === newRoles.size) return; // 等待50ms避免审计日志延迟导致查不到记录 await new Promise(resolve => setTimeout(resolve, 50)); // 拉取最近的成员身份组更新审计日志 const auditLogs = await guild.fetchAuditLogs({ type: 'MEMBER_ROLE_UPDATE', limit: 1 }); const logEntry = auditLogs.entries.first(); // 校验日志是否匹配本次操作:目标用户为当前更新成员、操作时间在1秒内 const executor = logEntry && logEntry.target.id === newMember.id && Date.now() - logEntry.createdTimestamp < 1000 ? logEntry.executor : null; // 身份组移除逻辑 if (oldRoles.size > newRoles.size) { const Embed = new Discord.MessageEmbed(); Embed.setColor("RED"); Embed.setAuthor(newMember.user.tag, newMember.user.avatarURL()); // 录入操作人信息 Embed.addField("操作人", executor ? `${executor.tag} (ID: ${executor.id})` : "无法获取"); oldRoles.forEach(role => { if (!newRoles.has(role.id)) { Embed.addField("身份组移除", role); } }); client.channels.cache.get("872558074290896908").send(Embed); // 身份组新增逻辑 } else if (oldRoles.size < newRoles.size) { const Embed = new Discord.MessageEmbed(); Embed.setColor("GREEN"); Embed.setAuthor(newMember.user.tag, newMember.user.avatarURL()); // 录入操作人信息 Embed.addField("操作人", executor ? `${executor.tag} (ID: ${executor.id})` : "无法获取"); newRoles.forEach(role => { if (!oldRoles.has(role.id)) { Embed.addField("身份组新增", role); } }); client.channels.cache.get("872558074290896908").send(Embed); } });
注意事项
- 部分自动化插件/脚本触发的身份组变动如果没有录入审计日志,会返回无法获取操作人,属于正常情况
- 如果你使用discord.js v14及以上版本,将
MessageEmbed替换为EmbedBuilder、审计日志类型枚举替换为AuditLogEvent.MemberRoleUpdate即可适配
内容的提问来源于stack exchange,提问作者musicas e fabulas
相关产品推荐
相关产品推荐

