You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Discord机器人封禁/踢出日志重复发送问题的修复需求

Discord机器人封禁与踢出日志区分修复

问题描述

我编写了Discord机器人的封禁(ban)、解封(unban)和踢出(kick)日志脚本,目前脚本可正常运行,但存在异常:当用户被封禁时,机器人会同时发送封禁日志和踢出日志。需要实现:仅在用户被封禁时发送封禁日志,仅在用户被踢出时发送踢出日志。当前相关代码如下:

client.on(Events.GuildBanRemove, async (ban) => {
    const fetchedLogs = await ban.guild.fetchAuditLogs({
        limit: 1,
        type: AuditLogEvent.MemberBanRemove,
    });
    const unbanLog = fetchedLogs.entries.first();
    const { executor, target } = unbanLog;

    if (target.id === ban.user.id) {
        const channel2 = client.channels.cache.get("1026979529387950132");
        const embed2 = new Discord.EmbedBuilder()
            .setColor("#10fee4")
            .setThumbnail(`${client.user.displayAvatarURL({ size: 2048 })}`)
            .setTitle(`Log | Usuario Desbanido.`)
            .setDescription(`**Informações do usuario:**\n > Membro:${ban.user}\n > ID:\`${ban.user.id}\`\n\n**Informações do unban**:\n > Desbanido por: ${executor}\n> ID:\`${executor.id}\``)
            .setFooter({ text: `© ${client.user.username} 2023` })
            .setTimestamp(new Date());
        channel2.send({ embeds: [embed2] });
    }
});

client.on(Events.GuildMemberRemove, async (member) => {
    const fetchedLogs2 = await member.guild.fetchAuditLogs({
        limit: 1,
        type: AuditLogEvent.MemberKick,
    });
    const kickLog = fetchedLogs2.entries.first();
    const { executor, target } = kickLog;

    if (target.id === member.id) {
        const channel3 = client.channels.cache.get("1026979529387950132");
        const embed3 = new Discord.EmbedBuilder()
            .setColor("#10fee4")
            .setThumbnail(`${client.user.displayAvatarURL({ size: 2048 })}`)
            .setTitle(`Log | Usuario Expulso.`)
            .setDescription(`**Informações do usuario:**\n > Membro:${member.user}\n > ID:\`${member.user.id}\`\n\n**Informações da expulsão:**\n > Expulso por: ${executor}\n> ID:\`${executor.id}\``)
            .setFooter({ text: `© ${client.user.username} 2023` })
            .setTimestamp(new Date());
        channel3.send({ embeds: [embed3] });
    }
});

问题原因

用户被封禁时,Discord会先将用户从服务器移除(触发GuildMemberRemove事件),再添加封禁记录。当前的GuildMemberRemove事件直接查询踢出类型的审计日志,会误把封禁导致的成员离开判定为踢出,从而重复发送日志。

解决方案

在GuildMemberRemove事件中,先检查该用户是否已被服务器封禁。如果用户处于封禁状态,说明是封禁操作导致的离开,不发送踢出日志;只有当用户未被封禁时,才判定为踢出操作,发送对应日志。

修改后的完整代码

client.on(Events.GuildBanRemove, async (ban) => {
    const fetchedLogs = await ban.guild.fetchAuditLogs({
        limit: 1,
        type: AuditLogEvent.MemberBanRemove,
    });
    const unbanLog = fetchedLogs.entries.first();
    const { executor, target } = unbanLog;

    if (target.id === ban.user.id) {
        const channel2 = client.channels.cache.get("1026979529387950132");
        const embed2 = new Discord.EmbedBuilder()
            .setColor("#10fee4")
            .setThumbnail(`${client.user.displayAvatarURL({ size: 2048 })}`)
            .setTitle(`Log | Usuario Desbanido.`)
            .setDescription(`**Informações do usuario:**\n > Membro:${ban.user}\n > ID:\`${ban.user.id}\`\n\n**Informações do unban**:\n > Desbanido por: ${executor}\n> ID:\`${executor.id}\``)
            .setFooter({ text: `© ${client.user.username} 2023` })
            .setTimestamp(new Date());
        channel2.send({ embeds: [embed2] });
    }
});

client.on(Events.GuildMemberRemove, async (member) => {
    // 检查用户是否被封禁,区分封禁/踢出导致的离开
    const isBanned = await member.guild.bans.fetch(member.id).catch(() => false);
    if (isBanned) return; // 封禁导致的离开,直接返回不发踢出日志

    const fetchedLogs2 = await member.guild.fetchAuditLogs({
        limit: 1,
        type: AuditLogEvent.MemberKick,
    });
    const kickLog = fetchedLogs2.entries.first();
    if (!kickLog) return; // 无踢出审计日志,直接返回

    const { executor, target } = kickLog;
    if (target.id === member.id) {
        const channel3 = client.channels.cache.get("1026979529387950132");
        const embed3 = new Discord.EmbedBuilder()
            .setColor("#10fee4")
            .setThumbnail(`${client.user.displayAvatarURL({ size: 2048 })}`)
            .setTitle(`Log | Usuario Expulso.`)
            .setDescription(`**Informações do usuario:**\n > Membro:${member.user}\n > ID:\`${member.user.id}\`\n\n**Informações da expulsão:**\n > Expulso por: ${executor}\n> ID:\`${executor.id}\``)
            .setFooter({ text: `© ${client.user.username} 2023` })
            .setTimestamp(new Date());
        channel3.send({ embeds: [embed3] });
    }
});

关键修改说明

  • 在GuildMemberRemove事件开头添加member.guild.bans.fetch(member.id)判断,若用户已被封禁则直接退出函数,跳过踢出日志发送逻辑
  • 增加if (!kickLog) return判断,避免因无有效审计日志导致的报错

内容的提问来源于stack exchange,提问作者zxszin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 05:55:16