类型错误:无法读取未定义的属性“id” | Discord.js

时间:2021-01-10 00:24:12

标签: discord discord.js

目标: 禁止每次尝试创建频道的审核日志中发现用户

代码:

// Channel Create
client.on("channelCreate", async (channel) => {

    const FetchingLogs = await client.guilds.cache.get(channel.guild.id).fetchAuditLogs({
        limit: 1,
        type: "CHANNEL_CREATE",
    })

    const ChannelLog = FetchingLogs.entries.first();

    if (!ChannelLog) {
        return console.log(red(`CHANNEL: ${channel.id} was created.`));
    }

    const { executor, target, createdAt } = ChannelLog;

    if (target.id === channel.id) {
        console.log(greenBright(`${channel.id} got created, by ${executor.tag}`));
    } else if (target.id === executor.id) {
        return
    }

    if (executor.id !== client.user.id) {
        channel.guild.member(executor.id).ban({
            reason: `Unauthorised Channel Created`
        }).then(channel.guild.owner.send(`**Unauthorised Channel Created By:** ${executor.tag} \n**Channel ID:** ${channel.id} \n**Time:** ${createdAt.toDateString()} \n**Sentence:** Ban.`)).catch();
    }
});

结果:

它成功禁止用户,但仍然抛出错误。

错误:

TypeError: Cannot read property 'id' of undefined

代码:错误指定 |参考channel.guild.id

    const FetchingLogs = await client.guilds.cache.get(channel.guild.id).fetchAuditLogs({
        limit: 1,
        type: "CHANNEL_CREATE",
    })

我猜这是因为参数 channel 的类型是 DMChannel 而不是 GuildChannel

有什么办法可以解决这个问题,或者可以将参数类型更改为 GuildChannel???我已经检查了 Docs,但似乎找不到任何表明这是可能的。任何帮助表示赞赏;)

1 个答案:

答案 0 :(得分:1)

您对发生此错误的原因的假设是正确的。 channelCreate 事件确实处理 GuildChannelDMChannel 的创建,并且您的代码在禁止用户后向公会所有者发送 DM。这就是禁令有效但之后你会得到错误的原因;因为 DM 与所有者创建了一个 DMChannel,再次触发事件处理程序但 channel.guild 未定义,因为 DM 没有公会。

让我再次说明问题。您收到错误 Cannot read property 'id' of undefined,您已经发现这意味着 channel.guildundefined。您不希望发生错误,因此您不希望 channel.guildundefined。但在您的问题中,您要问的是:

<块引用>

有什么办法可以解决这个问题,或者可以将参数类型更改为 GuildChannel???

这不是您想要采取的方法。这样做意味着用户会因为 DM 发送您的机器人而被禁止,因为它会触发您的 channelCreate 事件处理程序;此外,机器人会尝试禁止公会所有者,因为它会向所有者发送 DM。而且你只想禁止用户在公会中创建频道

当我们这样提出问题时,解决方案很简单:检查通道是否为 DMChannel,如果是,则停止。仅允许用户因创建 GuildChannel 而被禁止。那你怎么做呢?好吧,正如您已经从错误中看到的那样,当频道是 channel.guild 时,undefinedDMChannel。所以只需检查这个条件,如果是这种情况,return。举个例子:

// Channel Create
client.on("channelCreate", async (channel) => {

    if (!channel.guild) return; //<- added this

    const FetchingLogs = await client.guilds.cache.get(channel.guild.id).fetchAuditLogs({
        limit: 1,
        type: "CHANNEL_CREATE",
    })

    const ChannelLog = FetchingLogs.entries.first();

    if (!ChannelLog) {
        return console.log(red(`CHANNEL: ${channel.id} was created.`));
    }

    const { executor, target, createdAt } = ChannelLog;

    if (target.id === channel.id) {
        console.log(greenBright(`${channel.id} got created, by ${executor.tag}`));
    } else if (target.id === executor.id) {
        return
    }

    if (executor.id !== client.user.id) {
        channel.guild.member(executor.id).ban({
            reason: `Unauthorised Channel Created`
        }).then(channel.guild.owner.send(`**Unauthorised Channel Created By:** ${executor.tag} \n**Channel ID:** ${channel.id} \n**Time:** ${createdAt.toDateString()} \n**Sentence:** Ban.`)).catch();
    }
});

这可以防止错误发生,防止用户因 DM 机器人而被禁止,并防止公会所有者被无限 DM(如果 DMChannel 以某种方式转换为 {{1} }, bot 会在禁止创建频道的用户后发送 DM 所有者,这将再次触发事件并再次禁止该用户,并再次 DM 所有者,在无限循环中)。