Search code examples
javascriptdiscord.jscommando

How to make a bot know how to delete webhooks that it made and by channel mentions


Hi I want to make a Discord.JS-Commando command where if you select a channel, the bot removes a webhook it owns there and if it's named Marker and if it detects if there's no webhook there that it owns named Marker it just return message.channel.send("Hey! There's no webhook I own in this channel!")

The bot deletes a webhook even though it didn't make it, and it's not in the channel I mention. How do I fix this?

Searching it up on Google, there was nothing. There wasn't anything on deleting webhooks except discord.js docs.

const hooks1 = await message.guild.fetchWebhooks();
await hooks1.forEach(async webhook => {
    if (!watchChannel.id == webhook.channelID) return
    if (!webhook.owner.id == `595840576386236437`) return
    if (!webhook.name == `Marker`) return message.channel.send(`**${message.author.username}**, Nothing was found. You or someone else may have renamed the webhook. Please delete the webhook manually. Sorry for the inconvenience`);
    else
message.channel.send(`Deleted successfully.`).then(msg => {message.delete(4000)}).catch(error => console.log(error))
webhook.delete(`Requested per ${message.author.username}#${message.author.discriminator}`);
});

I expect the bot to know how to delete the webhook that it made, in a mentioned channel, but the bot doesn't know what webhook to delete.


Solution

  • if (!watchChannel.id == webhook.channelID) return
    if (!webhook.owner.id == `595840576386236437`) return
    if (!webhook.name == `Marker`) return
    

    None of these lines are working as you expect them to.

    const id = '189855563893571595';
    
    console.log(id === '189855563893571595');
    
    console.log(id !== '1234');  // id is not equal to '1234': true
    console.log(!id === '1234'); // false is equal to '1234' : false


    ! acts as the logical NOT operator.

    Returns false if its single operand can be converted to true; otherwise, returns true.

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators

    !watchChannel.id is a Boolean; it will never equal webhook.channelID unless the latter is false. The same goes for all three conditions in your code. Therefore, your bot is deleting Webhooks that aren't its own because the if statements are not true when you expected them to be.


    !== is known as the non-identity/strict inequality operator.

    ...[R]eturns true if the operands are not equal and/or not of the same type.

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators

    This (or the inequality operator != to go along with the twins) is the operator your want to be using. It will correctly compare the properties.


    Improving your current code, we can...

    • Fetch the Webhooks only from the specified channel.
    • Filter the Collection before looping through.
    • Use a modern for...of loop which will work correctly with asynchronous code.
    • Make sure to catch all rejected promises.
    • Get into the habit of using the identity operator === instead of the equality operator ==. See here for reasoning.
    const webhooks = await watchChannel.fetchWebhooks();
    const myWebhooks = webhooks.filter(webhook => webhook.owner.id === client.user.id && webhook.name === 'Marker');
    
    try {
      if (myWebhooks.size === 0) return await message.channel.send('I don\'t own any Webhooks there...');
    
      for (let [id, webhook] of myWebhooks) await webhook.delete(`Requested by ${message.author.tag}`);
    
      await message.channel.send('Successfully deleted all of my Webhooks from that channel.');
    } catch(err) {
      console.error(err);
    
      await message.channel.send('Something went wrong.')
        .catch(console.error);
    }