PoXoS
PoXoS

Reputation: 69

Discord.js v12 clear command

I have a clear command which deletes the amount of messages you would like to. But whenever I say clear 3, it'll clear only 2 messages instead.

client.on('message', async (message) => {
  if (
    message.content.toLowerCase().startsWith(prefix + 'clear') ||
    message.content.toLowerCase().startsWith(prefix + 'c ')
  ) {
    if (!message.member.hasPermission('MANAGE_MESSAGES'))
      return message.channel.send("You cant use this command since you're missing `manage_messages` perm");
    if (!isNaN(message.content.split(' ')[1])) {
      let amount = 0;
      if (message.content.split(' ')[1] === '1' || message.content.split(' ')[1] === '0') {
        amount = 1;
      } else {
        amount = message.content.split(' ')[1];
        if (amount > 100) {
          amount = 100;
        }
      }
      await message.channel.bulkDelete(amount, true).then((_message) => {
        message.channel.send(`Bot cleared \`${_message.size}\` messages :broom:`).then((sent) => {
          setTimeout(function () {
            sent.delete();
          }, 2500);
        });
      });
    } else {
      message.channel.send('enter the amount of messages that you would like to clear').then((sent) => {
        setTimeout(function () {
          sent.delete();
        }, 2500);
      });
    }
  } else {
    if (message.content.toLowerCase() === prefix + 'help clear') {
      const newEmbed = new Discord.MessageEmbed().setColor('#00B2B2').setTitle('**Clear Help**');
      newEmbed
        .setDescription('This command clears messages for example `.clear 5` or `.c 5`.')
        .setFooter(`Requested by ${message.author.tag}`, message.author.displayAvatarURL())
        .setTimestamp();
      message.channel.send(newEmbed);
    }
  }
});

Upvotes: 4

Views: 23789

Answers (3)

Xandrrrr
Xandrrrr

Reputation: 118

The triggering message (command message) is also getting fetched.

There are multiple solutions:

  1. Delete the command message before you fetch/bulk delete the other messages
  2. Only fetch messages which got sent before the command message
  3. Increment the amount of deleting messages by 1

I marked all 3 solutions in the following code

client.on('message', async (message) => {
  if (
    message.content.toLowerCase().startsWith(prefix + 'clear') ||
    message.content.toLowerCase().startsWith(prefix + 'c ')
  ) {
    if (!message.member.hasPermission('MANAGE_MESSAGES'))
      return message.channel.send("You cant use this command since you're missing `manage_messages` perm");
    if (!isNaN(message.content.split(' ')[1])) {
      let amount = 0;
      if (message.content.split(' ')[1] === '1' || message.content.split(' ')[1] === '0') {
        amount = 1;
      } else {
        amount = message.content.split(' ')[1];
        if (amount > 100) {
          amount = 100;
        }
      }

/* 1. Solution */

      await message.delete().catch(e => { amount++; });

      await message.channel.bulkDelete(amount, true).then((_message) => {
        message.channel.send(`Bot cleared \`${_message.size}\` messages :broom:`).then((sent) => {
          setTimeout(function () {
            sent.delete();
          }, 2500);
        });
      });

/* 2. Solution */
      const messagesToDelete = await message.channel.messages.fetch({ before: message.id, limit: amount });

      await message.channel.bulkDelete(messagesToDelete, true).then((_message) => {
        message.channel.send(`Bot cleared \`${_message.size}\` messages :broom:`).then((sent) => {
          setTimeout(function () {
            sent.delete();
          }, 2500);
        });
      });

/* 3. Solution */

      amount >= 100 ? await message.delete() /* You can only bulk delete 100 messages */ : amount++;

      await message.channel.bulkDelete(amount, true).then((_message) => {
        message.channel.send(`Bot cleared \`${_message.size}\` messages :broom:`).then((sent) => {
          setTimeout(function () {
            sent.delete();
          }, 2500);
        });
      });

/* The following code is your old code */

    } else {
      message.channel.send('enter the amount of messages that you would like to clear').then((sent) => {
        setTimeout(function () {
          sent.delete();
        }, 2500);
      });
    }
  } else {
    if (message.content.toLowerCase() === prefix + 'help clear') {
      const newEmbed = new Discord.MessageEmbed().setColor('#00B2B2').setTitle('**Clear Help**');
      newEmbed
        .setDescription('This command clears messages for example `.clear 5` or `.c 5`.')
        .setFooter(`Requested by ${message.author.tag}`, message.author.displayAvatarURL())
        .setTimestamp();
      message.channel.send(newEmbed);
    }
  }
});

Upvotes: 1

Noah Calland
Noah Calland

Reputation: 137

That's because it's deleting the message triggering it too. Simple fix, just take the number given, and add one to it.

await message.channel.bulkDelete(parseInt(amount) + 1, true).then((_message) => {

Upvotes: 1

Zsolt Meszaros
Zsolt Meszaros

Reputation: 23161

Your code works fine, it deletes the correct number of messages. What you forgot is that your current message with the comment is also a message, and will also count towards the amount deleted. So you can increase this number by one.

I would probably make some changes to your code:

  1. Instead of splitting your message by a single space, I'd use a regex to catch more than one spaces. The current one wouldn't work with .clear 5. If you check, isNaN(' ') is false.
  2. Check if the amount is positive.
  3. Remove hardcoded prefixes.
  4. Remove unnecessary await.
  5. Add an early check for the prefix.
client.on('message', (message) => {
  if (!message.content.startsWith(prefix) || message.author.bot) return;

  const args = message.content
    .toLowerCase()
    .slice(prefix.length)
    .trim()
    .split(/\s+/);
  const [command, input] = args;

  if (command === 'clear' || command === 'c') {
    if (!message.member.hasPermission('MANAGE_MESSAGES')) {
      return message.channel
        .send(
          "You cant use this command since you're missing `manage_messages` perm",
        );
    }

    if (isNaN(input)) {
      return message.channel
        .send('enter the amount of messages that you would like to clear')
        .then((sent) => {
          setTimeout(() => {
            sent.delete();
          }, 2500);
        });
    }

    if (Number(input) < 0) {
      return message.channel
        .send('enter a positive number')
        .then((sent) => {
          setTimeout(() => {
            sent.delete();
          }, 2500);
        });
    }

    // add an extra to delete the current message too
    const amount = Number(input) > 100
      ? 101
      : Number(input) + 1;

    message.channel.bulkDelete(amount, true)
    .then((_message) => {
      message.channel
        // do you want to include the current message here?
        // if not it should be ${_message.size - 1}
        .send(`Bot cleared \`${_message.size}\` messages :broom:`)
        .then((sent) => {
          setTimeout(() => {
            sent.delete();
          }, 2500);
        });
    });
  }

  if (command === 'help' && input === 'clear') {
    const newEmbed = new MessageEmbed()
      .setColor('#00B2B2')
      .setTitle('**Clear Help**')
      .setDescription(
        `This command clears messages for example \`${prefix}clear 5\` or \`${prefix}c 5\`.`,
      )
      .setFooter(
        `Requested by ${message.author.tag}`,
        message.author.displayAvatarURL(),
      )
      .setTimestamp();

    message.channel.send(newEmbed);
  }
});

Upvotes: 5

Related Questions