Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.4k views
in Technique[技术] by (71.8m points)

TypeError: Cannot read property 'id' of undefined | Discord.js

Aim: To ban every time a user is caught on the audit log attempting to create a channel

Code:

// 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} 
**Channel ID:** ${channel.id} 
**Time:** ${createdAt.toDateString()} 
**Sentence:** Ban.`)).catch();
    }
});

Result:

It bans the user successfully but still throws an error.

Error:

TypeError: Cannot read property 'id' of undefined

Code: Error Specified | Referring to channel.guild.id

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

I'm guessing the reason for this is that the parameter ,channel, type is DMChannel and not GuildChannel

Is there any way to fix this or be able to change the parameter type to GuildChannel??? I've checked the Docs and I can't seem to find anything that indicates this is possible. Any help is appreciated ;)

question from:https://stackoverflow.com/questions/65648995/typeerror-cannot-read-property-id-of-undefined-discord-js

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Your assumption of why this error is occurring is correct. The channelCreate event does indeed handle the creation of both GuildChannel and DMChannel, and your code sends the guild owner a DM after banning the user. That's why the ban works but you get an error afterwards; because the DM creates a DMChannel with the owner, triggering the event handler again but with channel.guild being undefined since DMs do not have guilds.

So let me state the problem again. You are getting the error Cannot read property 'id' of undefined which you've figured out means channel.guild is undefined. You don't want the error to occur, so you don't want channel.guild to be undefined. But in your question you're asking:

Is there any way to fix this or be able to change the parameter type to GuildChannel???

That's not the approach you want to take. Doing that would mean users would get banned for DMing your bot because it would trigger your channelCreate event handler; plus, the bot would try to ban the guild owner since it sends the owner a DM. And you only want to ban users for creating channels in the guild.

When we put the problem that way, the solution is simple: check if the channel is a DMChannel, and discontinue if it is. Only allow users to get banned for creating a GuildChannel. So how do you do that? Well, as you've seen from your error already, channel.guild is undefined when the channel is a DMChannel. So simply check for this condition, and return if it is the case. Here's an example:

// 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} 
**Channel ID:** ${channel.id} 
**Time:** ${createdAt.toDateString()} 
**Sentence:** Ban.`)).catch();
    }
});

This prevents the error from occurring, prevents users from getting banned for DMing the bot, and prevents the guild owner from being infinitely DM'd (if the DMChannel were to be somehow converted into a GuildChannel, the bot would DM the owner after banning the user that created the channel, which would trigger the event again and ban the user again, and DM the owner again, in an infinite loop).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...