0
votes

I'm wondering how I could delete messages using a command like !clear [number] and have those messages fetched back to a channel including:

  • The user ID who used the command to delete the message
  • The user ID of who said the deleted message(s)
  • The content of the message(s)
  • The channel it has been deleted from
  • The timestamp of the message

All this stuff in a discord embed.
I'm relatively new to coding, and I'm developing this bot for a server with 40,000 people and we need to keep logs of all deleted messages.

Please, someone, help me out. I would greatly appreciate it :D. If needed I can explain in further detail if you still aren't sure of what I'm looking to do with this bot :D

1

1 Answers

0
votes

To delete messages with a command, you have to use TextChannel.bulkDelete(), in this case maybe after fetching the messages via TextChannel.fetchMessages().
To "log" them, you may want to build a RichEmbed and put your info in the fields.
I would try something like this:

// ASSUMPTIONS:
// logs = the TextChannel in wich you want the embed to be sent
// trigger = the Messages that triggered the command
// 
// This is just a sample implementation, it could contain errors or might not be the fastest
// Its aim is not to make it for you, but to give you a model

async function clear(n = 1, logs, trigger) {
  let {channel: source, author} = trigger;
  if (n < 1 || !logs || !source) throw new Error("One of the arguments was wrong.");

  let coll = await source.fetchMessages({ limit: n }), // get the messages
    arr = coll.array(),
    collected = [],
    embeds = [];

  // create groups of 25 messages, the field limit for a RichEmbed
  let index = 0;
  for (let i = 0; i < arr.length; i += 25) {
    collected.push([]);
    for (let m = i; m < i + 25; m++)
      if (arr[m]) collected[index].push(arr[m]);
    index++;
  }

  // for every group of messages, create an embed
  // I used some sample titles that you can obviously modify
  for (let i = 0; i < collected.length; i++) {
    let embed = new Discord.RichEmbed()
      .setTitle(`Channel cleaning${collected.length > 1 ? ` - Part ${i+1}` : ""}`)
      .setDescription(`Deleted from ${source}`)
      .setAuthor(`${author.tag} (${author.id})`, author.displayAvatarURL)
      .setTimestamp(trigger.editedAt ? trigger.editedAt : trigger.createdAt),
      group = collected[i];
    for (let msg of group) {
      let a = `${msg.author.tag} (${msg.author.id}) at ${msg.editedAt ? msg.editedAt : msg.createdAt}`,
        c = msg.content.length > 1024 ? msg.content.substring(0, msg.content.length - 3) + '...' : msg.content;
      embed.addField(a, c);
    }
    embeds.push(embed);
  }

  // once the embeds are ready, you can send them
  source.bulkDelete(coll).then(async () => {
    for (let embed of embeds) await source.send({embed});
  }).catch(console.error);
}

// this is a REALLY basic command implementation, please DO NOT use this as yours
client.on('message', async msg => {
  let command = 'clear ';
  if (msg.content.startsWith(command)) {
    let args = msg.content.substring(command.length).split(' ');
    if (isNaN(args[0]) || parseInt(args[0]) < 1) msg.reply(`\`${args[0]}\` is not a valid number.`);
    else {
      await msg.delete(); // delete your message first
      let logs; // store your channel here
      clear(parseInt(args[0]), logs, msg);
    }
  }
});

Note: the highlighting for this kind of stuff, with a lot of backtick strings and objects, is pretty bad. I suggest reading the code in another editor or you might end up not understanding anything