Skip to content

Commit

Permalink
fix(purge): make purge faster
Browse files Browse the repository at this point in the history
  • Loading branch information
dev-737 committed Sep 29, 2023
1 parent 5aca056 commit 99eb1b1
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 32 deletions.
5 changes: 4 additions & 1 deletion src/Commands/Apps/blacklist.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ActionRowBuilder, ApplicationCommandType, ButtonBuilder, ButtonStyle, ContextMenuCommandBuilder, EmbedBuilder, MessageContextMenuCommandInteraction, ModalBuilder, TextInputBuilder, TextInputStyle } from 'discord.js';
import { getDb } from '../../Utils/utils';
import { captureException } from '@sentry/node';
import { addServerBlacklist, addUserBlacklist, scheduleUnblacklist } from '../../Utils/blacklist';
import { addServerBlacklist, addUserBlacklist, notifyBlacklist, scheduleUnblacklist } from '../../Utils/blacklist';
import emojis from '../../Utils/JSON/emoji.json';

export default {
Expand Down Expand Up @@ -136,6 +136,7 @@ export default {
await addUserBlacklist(messageInDb.hubId, i.user, messageInDb.authorId, reason, expires);

if (expires) scheduleUnblacklist('user', i.client, messageInDb.authorId, messageInDb.hubId, expires);
if (user) notifyBlacklist(user, messageInDb.hubId, expires, reason).catch(() => null);

await modalResp.editReply({ embeds: [successEmbed], components: [] });
}
Expand All @@ -147,6 +148,8 @@ export default {

if (expires) scheduleUnblacklist('server', i.client, messageInDb.serverId, messageInDb.hubId, expires);

// TODO: Notify server of blacklist

await modalResp.editReply({ embeds: [successEmbed], components: [] });
}
});
Expand Down
48 changes: 26 additions & 22 deletions src/Commands/Staff/purge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { captureException } from '@sentry/node';
import { ChannelType, ChatInputCommandInteraction, EmbedBuilder, PermissionFlagsBits, SlashCommandBuilder } from 'discord.js';
import { getDb, toHuman } from '../../Utils/utils';
import emojis from '../../Utils/JSON/emoji.json';
import { messageData as messageDataCol } from '@prisma/client';
import { stripIndents } from 'common-tags';

export default {
staff: true,
Expand Down Expand Up @@ -110,7 +112,7 @@ export default {
});
}

let messagesInDb;
let messagesInDb: messageDataCol[] = [];

switch (subcommand) {
case 'server': {
Expand Down Expand Up @@ -171,19 +173,15 @@ export default {

if (!messagesInDb || messagesInDb.length < 1) {
return await interaction.reply({
content: 'Unable to locate messages to purge in database. Maybe they have expired?',
content: 'Unable to locate messages to purge. Maybe they have expired?',
ephemeral: true,
});
}
const initialReply = await interaction.reply(`${emoji.normal.loading} Purging...`);

let erroredMessageCount = 0;
let deletedMessageCount = 0;
const deletedMessagesArr: string[] = [];
await interaction.deferReply({ fetchReply: true });

const startTime = performance.now();
const allNetworks = await connectedList.findMany({ where: { hubId: channelInHub.hubId, connected: true } });
for (const network of allNetworks) {
const promiseResults = allNetworks.map(async network => {
try {
const channel = await interaction.client.channels.fetch(network.channelId);

Expand All @@ -194,37 +192,43 @@ export default {
.map(({ messageId }) => messageId),
);

if (messageIds.length < 1) continue;
if (messageIds.length < 1) return [];

await channel.bulkDelete(messageIds);
deletedMessagesArr.push(messageIds[0]);
deletedMessageCount += messageIds.length;
return messageIds;
}
}
catch (e) {
erroredMessageCount++;
captureException(e);
continue;
}
}

return [];
});

const results = await Promise.all(promiseResults);
const deletedMessages = results.reduce((acc, cur) => acc + cur.length, 0);
const failedMessages = results.reduce((acc, cur) => acc + cur.length > 0 ? 0 : 1, 0);
const messages = results.filter((i) => i.length > 0).flat();

const resultEmbed = new EmbedBuilder()
.setTitle(`${emoji.icons.delete} Purge Results`)
.setDescription(`Finished purging from **${allNetworks.length}** networks in \`${toHuman(performance.now() - startTime)}\`.`)
.setDescription(stripIndents`
### ${emoji.icons.delete} Purge Results
Finished purging from **${allNetworks.length}** networks in \`${toHuman(performance.now() - startTime)}\`.
`)
.addFields([
{ name: 'Total Purged', value: `\`\`\`js\n${deletedMessageCount}\`\`\``, inline: true },
{ name: 'Errored Purges', value: `\`\`\`js\n${erroredMessageCount}\`\`\``, inline: true },
{ name: 'Total Purged', value: `\`\`\`js\n${deletedMessages}\`\`\``, inline: true },
{ name: 'Errored Purges', value: `\`\`\`js\n${failedMessages}\`\`\``, inline: true },
{ name: 'Purge Limit', value: `\`\`\`js\n${limit || 'None'}\`\`\``, inline: true },
])
.setFooter({ text: `Purged By: ${interaction.user.username}`, iconURL: interaction.user.avatarURL() || undefined })
.setTimestamp()
.setColor('Orange');
.setColor('Green');

initialReply.edit({ content: '', embeds: [resultEmbed] }).catch(captureException);
await interaction.followUp({ embeds: [resultEmbed] }).catch(captureException);

// Remove the deleted messages from the database
await messageData.deleteMany({
where: { channelAndMessageIds: { some: { messageId: { in: deletedMessagesArr } } } },
where: { channelAndMessageIds: { some: { messageId: { in: messages } } } },
}).catch(captureException);
},
};
4 changes: 3 additions & 1 deletion src/Scripts/blacklist/user.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ChatInputCommandInteraction, EmbedBuilder } from 'discord.js';
import { getDb } from '../../Utils/utils';
import { modActions } from '../networkLogs/modActions';
import { addUserBlacklist, removeBlacklist, scheduleUnblacklist } from '../../Utils/blacklist';
import { addUserBlacklist, notifyBlacklist, removeBlacklist, scheduleUnblacklist } from '../../Utils/blacklist';
import emojis from '../../Utils/JSON/emoji.json';

export default {
Expand Down Expand Up @@ -61,6 +61,8 @@ export default {
await addUserBlacklist(hubInDb.id, interaction.user, user, String(reason), expires);
if (expires) scheduleUnblacklist('user', interaction.client, user.id, hubInDb.id, expires);

await notifyBlacklist(user, hubInDb.id, expires, String(reason));

const successEmbed = new EmbedBuilder()
.setDescription(`${emojis.normal.tick} **${user.username}** has been successfully blacklisted!`)
.setColor('Green')
Expand Down
4 changes: 3 additions & 1 deletion src/Scripts/message/checks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { slurs } from '../../Utils/JSON/badwords.json';
import { replaceLinks } from '../../Utils/utils';
import { connectedList } from '@prisma/client';
import { HubSettingsBitField } from '../../Utils/hubSettingsBitfield';
import { addUserBlacklist, findBlacklistedServer, findBlacklistedUser, scheduleUnblacklist } from '../../Utils/blacklist';
import { addUserBlacklist, findBlacklistedServer, findBlacklistedUser, notifyBlacklist, scheduleUnblacklist } from '../../Utils/blacklist';
export default {
async execute(message: Message, networkData: connectedList, settings: HubSettingsBitField) {
// true = pass, false = fail (checks)
Expand All @@ -21,6 +21,8 @@ export default {
if (antiSpamResult.infractions >= 3) {
await addUserBlacklist(networkData.hubId, message.client.user, message.author, 'Auto-blacklisted for spamming.', 60 * 5000);
scheduleUnblacklist('user', message.client, message.author.id, networkData.hubId, 60 * 5000);

notifyBlacklist(message.author, networkData.hubId, new Date(Date.now() + 60 * 5000), 'Auto-blacklisted for spamming.').catch(() => null);
}
message.react(emojis.icons.timeout).catch(() => null);
return false;
Expand Down
10 changes: 3 additions & 7 deletions src/Utils/blacklist.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,11 +120,9 @@ export async function removeBlacklist(type: string, hubId: string, userOrServerI
}


export function scheduleUnblacklist(type: 'server', client: Client<true>, serverId: string, hubId: string, expires: Date | number): void
export function scheduleUnblacklist(type: 'user', client: Client<true>, userId: string, hubId: string, expires: Date | number): void
export function scheduleUnblacklist(type: string, client: Client<true>, userOrServerId: string, hubId: string, expires: Date | number) {
export function scheduleUnblacklist(type: 'user' | 'server', client: Client<true>, userOrServerId: string, hubId: string, expires: Date | number) {
if (type === 'server') {
scheduleJob(`blacklist_server-${userOrServerId}`, expires, async function() {
return scheduleJob(`blacklist_server-${userOrServerId}`, expires, async function() {
const db = getDb();
const dbServer = await db.blacklistedServers.findFirst({
where: { serverId: userOrServerId, hubs: { some: { hubId } } },
Expand All @@ -146,7 +144,7 @@ export function scheduleUnblacklist(type: string, client: Client<true>, userOrSe
}

if (type === 'user') {
scheduleJob(`blacklist_user-${userOrServerId}`, expires, async () => {
return scheduleJob(`blacklist_user-${userOrServerId}`, expires, async () => {
const db = getDb();
const dbUser = await db.blacklistedUsers.findFirst({
where: { userId: userOrServerId, hubs: { some: { hubId } } },
Expand All @@ -165,10 +163,8 @@ export function scheduleUnblacklist(type: string, client: Client<true>, userOrSe
}).catch(() => null);
});
}
return false;
}

export async function notifyBlacklist(channel: TextBasedChannel, hubId: string, expires?: Date, reason?: string): Promise<void>
export async function notifyBlacklist(userOrChannel: User | TextBasedChannel, hubId: string, expires?: Date, reason: string = 'No reason provided.') {
const db = getDb();
const hub = await db.hubs.findUnique({ where: { id: hubId } });
Expand Down

0 comments on commit 99eb1b1

Please sign in to comment.