Skip to content

Commit

Permalink
Finish /purge
Browse files Browse the repository at this point in the history
  • Loading branch information
TheMonDon committed Oct 9, 2023
1 parent 493cebd commit d921ff7
Showing 1 changed file with 211 additions and 45 deletions.
256 changes: 211 additions & 45 deletions slash_commands/Moderator/purge.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
/* eslint-disable no-undef */
/* eslint-disable no-unused-vars */
const { SlashCommandBuilder } = require('discord.js');
const amountText = 'The amount of messages to delete';
const delText = 'The text to delete';
Expand All @@ -26,6 +24,9 @@ exports.commandData = new SlashCommandBuilder()
.setDescription('Delete messages from a user')
.addIntegerOption((option) =>
option.setName('amount').setDescription(amountText).setMinValue(1).setMaxValue(100).setRequired(true),
)
.addUserOption((option) =>
option.setName('user').setDescription('The user to delete messages from').setRequired(true),
),
)
.addSubcommand((subcommand) =>
Expand Down Expand Up @@ -86,35 +87,23 @@ exports.commandData = new SlashCommandBuilder()
.setDescription('Delete messages from bots')
.addIntegerOption((option) =>
option.setName('amount').setDescription(amountText).setMinValue(1).setMaxValue(100).setRequired(true),
)
.addStringOption((option) => option.setName('text').setDescription(delText).setRequired(true)),
),
)
.addSubcommand((subcommand) =>
subcommand
.setName('humans')
.setDescription('Delete messages from humans')
.addIntegerOption((option) =>
option.setName('amount').setDescription(amountText).setMinValue(1).setMaxValue(100).setRequired(true),
)
.addStringOption((option) => option.setName('text').setDescription(delText).setRequired(true)),
),
)
.addSubcommand((subcommand) =>
subcommand
.setName('images')
.setDescription('Delete messages containing images')
.addIntegerOption((option) =>
option.setName('amount').setDescription(amountText).setMinValue(1).setMaxValue(100).setRequired(true),
)
.addStringOption((option) => option.setName('text').setDescription(delText).setRequired(true)),
)
.addSubcommand((subcommand) =>
subcommand
.setName('mentions')
.setDescription('Delete messages containing mentions')
.addIntegerOption((option) =>
option.setName('amount').setDescription(amountText).setMinValue(1).setMaxValue(100).setRequired(true),
)
.addStringOption((option) => option.setName('text').setDescription(delText).setRequired(true)),
),
)
.addSubcommand((subcommand) =>
subcommand
Expand All @@ -125,8 +114,7 @@ exports.commandData = new SlashCommandBuilder()
)
.addIntegerOption((option) =>
option.setName('message_id').setDescription(amountText).setMinValue(1).setMaxValue(30).setRequired(true),
)
.addStringOption((option) => option.setName('text').setDescription(delText).setRequired(true)),
),
)
.addSubcommand((subcommand) =>
subcommand
Expand All @@ -137,16 +125,25 @@ exports.commandData = new SlashCommandBuilder()
)
.addIntegerOption((option) =>
option.setName('message_id').setDescription(amountText).setMinValue(1).setMaxValue(30).setRequired(true),
)
.addStringOption((option) => option.setName('text').setDescription(delText).setRequired(true)),
),
)
.addSubcommand((subcommand) =>
subcommand
.setName('mentions')
.setDescription('Delete messages containing mentions')
.addIntegerOption((option) =>
option.setName('amount').setDescription(amountText).setMinValue(1).setMaxValue(100).setRequired(true),
),
);

exports.run = async (interaction) => {
await interaction.deferReply();

const amount = interaction.options.getInteger('amount');
const subcommand = interaction.options.getSubcommand();
const linkRegex = /https?:\/\/[\w\d-_]/gi;
const text = interaction.options.getString('text');
const inviteRegex = /discord.(gg|me)\s?\//gi;
let count;
const linkRegex = /https?:\/\/[\w\d-_]/gi;

if (!interaction.guild.members.me.permissions.has('ManageMessages'))
return this.client.util.errorEmbed(
Expand Down Expand Up @@ -176,73 +173,242 @@ exports.run = async (interaction) => {
// msg: Message object
// messages: Collection of messages to delete
async function deleteMessages(channel, messages) {
if (!messages || messages.size < 1) return msg.channel.send('No messages found.');
if (!messages || messages.size < 1) return interaction.editReply('No messages found.');

return await channel
.bulkDelete(messages, true)
.then(async (messages) => {
return messages.size;
})
.catch((err) => {
return this.client.util.errorEmbed(msg, err);
return this.client.util.errorEmbed(interaction, err);
});
}

function checkCount(count) {
if (!count) return 1;
if (isNaN(count)) return 1;
if (count > 100) return 100;
if (count < 1) return 1;
return count;
}

switch (subcommand) {
case 'any': {
return interaction.editReply('This will delete up to 1k messages!');
const total = interaction.options.getInteger('amount');
let purged = 0;
let count;
const progress = count > 100;

if (count < 100) {
const filter = function (element) {
return !element.pinned;
};
const messages = await getMessages(interaction.channel, count, filter);
const size = await deleteMessages(interaction.channel, messages);
return interaction.editReply(`Successfully deleted ${size} messages in current channel.`);
}

const purgeText = progress ? 'Purging messages... 0%' : 'Purging messages...';
const purgeMsg = await interaction.channel.send(purgeText);

while (count > 0) {
let messages = [];

try {
messages = await getMessages(interaction.channel, Math.min(count, 100), (m) => !m.pinned);
} catch (e) {
return this.error('Unable to get messages.');
}

await deleteMessages(interaction.channel, messages);

purged += messages.size;

if (progress) purgeMsg.edit(`Purging messages... ${Math.ceil((purged / total) * 100)}%`).catch(() => false);
if (!messages.size) count = 0;

await this.client.util.wait(1100);
count -= Math.min(count, 100);
}

purgeMsg.edit(`Purged ${purged} messages.`).catch(() => false);
setTimeout(() => purgeMsg.delete().catch(() => false), 9000);
break;
}

case 'user': {
return interaction.editReply('This will delete messages from a user');
const user = interaction.options.getUser('user');
const filter = function (element) {
return element.author.id === user.id;
};
const messages = await getMessages(interaction.channel, amount, filter);

if (!messages || messages.size < 1) return interaction.editReply('No messages found from that member.');

const size = await deleteMessages(interaction.channel, messages);
const authorName = user.user.discriminator === '0' ? user.user.username : user.user.tag;
return interaction.editReply(`Successfully deleted ${size} messages from ${authorName}.`);
}

case 'links': {
return interaction.editReply('This will delete messages containing links');
const filter = function (element) {
return element.content.match(linkRegex);
};
const messages = await getMessages(interaction.channel, amount, filter);

if (!messages || messages.size < 1) return interaction.editReply('No messages found containing links.');

const size = await deleteMessages(interaction.channel, messages);
return interaction.editReply(`Successfully deleted ${size} messages containing links.`);
}

case 'invites': {
return interaction.editReply('This will delete messages containing invites');
const filter = function (element) {
return element.content.match(inviteRegex);
};
const messages = await getMessages(interaction.channel, amount, filter);

if (!messages || messages.size < 1) return interaction.editReply('No messages found containing invites.');

const size = await deleteMessages(interaction.channel, messages);
return interaction.editReply(`Successfully deleted ${size} messages containing invites.`);
}

case 'match': {
return interaction.editReply('This will delete messages matching text');
const filter = function (m) {
const content = m.content.toLowerCase();
for (const match of text) {
if (content.includes(match.toLowerCase())) return true;
}
return false;
};

const messages = await getMessages(interaction.channel, amount, filter);
console.log('Messages stuff', messages.first(2));

if (!messages || messages.size < 1) return interaction.editReply(`No messages found containing \`${text}\`.`);

const size = await deleteMessages(interaction.channel, messages);
return interaction.editReply(`Successfully deleted ${size} messages containing \`${text}\`.`);
}

case 'not': {
return interaction.editReply('This will delete messages not matching text');
const filter = function (m) {
const content = m.content.toLowerCase();
for (const match of text) {
if (!content.includes(match.toLowerCase())) return true;
}
return false;
};

const messages = await getMessages(interaction.channel, amount, filter);
if (!messages || messages.size < 1)
return interaction.channel.send(`No messages found not containing \`${text}\`.`);

const size = await deleteMessages(interaction.channel, messages);
return interaction.editReply(`Successfully deleted ${size} messages not containing \`${text}\`.`);
}

case 'startswith': {
return interaction.editReply('This will delete messages starting with text');
const filter = function (m) {
const content = m.content.toLowerCase();
for (const match of text) {
if (content.startsWith(match.toLowerCase())) return true;
}
return false;
};

const messages = await getMessages(interaction.channel, amount, filter);
if (!messages || messages.size < 1) return interaction.editReply(`No messages found starting with \`${text}\`.`);

const size = await deleteMessages(interaction.channel, messages);
return interaction.editReply(`Successfully deleted ${size} messages starting with \`${text}\`.`);
}

case 'endswith': {
return interaction.editReply('This will delete messages ending with text');
const filter = function (m) {
const content = m.content.toLowerCase();
for (const match of text) {
if (content.endsWith(match.toLowerCase())) return true;
}
return false;
};

const messages = await getMessages(interaction.channel, amount, filter);
if (!messages || messages.size < 1) return interaction.editReply(`No messages found ending with \`${text}\`.`);

const size = await deleteMessages(interaction.channel, messages);
return interaction.editReply(`Successfully deleted ${size} messages ending with \`${text}\`.`);
}

case 'bot': {
return interaction.editReply('This will delete messages from bots');
const filter = function (element) {
return element.author.bot;
};
const messages = await getMessages(interaction.channel, amount, filter);
if (!messages || messages.size < 1) return interaction.editReply('No messages found from bots.');

const size = await deleteMessages(interaction.channel, messages);
return interaction.editReply(`Successfully deleted ${size} messages from bots.`);
}

case 'humans': {
return interaction.editReply('This will delete messages from humans');
const filter = function (element) {
return !element.author.bot;
};
const messages = await getMessages(interaction.channel, amount, filter);
if (!messages || messages.size < 1) return interaction.editReply('No messages found from humans.');

const size = await deleteMessages(interaction.channel, messages);
return interaction.editReply(`Successfully deleted ${size} messages from humans.`);
}

case 'images': {
const filter = function (element) {
return element.attachments?.size || element.embeds?.size;
};
const messages = await getMessages(interaction.channel, amount, filter);

if (!messages || messages.size < 1) return interaction.editReply('No messages found with images.');

const size = await deleteMessages(interaction.channel, messages);
return interaction.editReply(`Successfully deleted ${size} messages with images.`);
}

case 'before': {
return interaction.editReply('This will delete messages before a message ID');
const messageId = interaction.options.getInteger('message_id');
const message = await interaction.channel.messages.fetch(messageId);
if (!message) return interaction.editReply('Message not found.');

const filter = function (element) {
return element.createdTimestamp < message.createdTimestamp;
};
const messages = await getMessages(interaction.channel, amount, filter);

if (!messages || messages.size < 1) return interaction.editReply('No messages found before the message.');

const size = await deleteMessages(interaction.channel, messages);
return interaction.editReply(`Successfully deleted ${size} messages before the message.`);
}

case 'after': {
return interaction.editReply('This will delete messages after a message ID');
const messageId = interaction.options.getInteger('message_id');
const message = await interaction.channel.messages.fetch(messageId);
if (!message) return interaction.editReply('No message with that ID was found.');

const filter = function (element) {
return element.createdTimestamp > message.createdTimestamp;
};
const messages = await getMessages(interaction.channel, amount, filter);

if (!messages || messages.size < 1) return interaction.editReply('No messages found after the message.');

const size = await deleteMessages(interaction.channel, messages);
return interaction.editReply(`Successfully deleted ${size} messages after the message.`);
}

case 'mentions': {
const filter = function (element) {
return element.mentions.members.size || element.mentions.roles.size;
};
const messages = await getMessages(interaction.channel, amount, filter);
if (!messages || messages.size < 1) return interaction.editReply('No messages found with mentions.');

const size = await deleteMessages(interaction.channel, messages);
return interaction.editReply(`Successfully deleted ${size} messages with mentions.`);
}
}
};

0 comments on commit d921ff7

Please sign in to comment.