Skip to content

Commit

Permalink
feat: global ban/unban command
Browse files Browse the repository at this point in the history
  • Loading branch information
dev-737 committed Jun 4, 2024
1 parent 75b2ee7 commit 0b0e02b
Show file tree
Hide file tree
Showing 8 changed files with 185 additions and 69 deletions.
3 changes: 2 additions & 1 deletion prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -156,11 +156,12 @@ model blacklistedUsers {
model userData {
id String @id @default(auto()) @map("_id") @db.ObjectId
userId String @unique
voteCount Int @default(0)
// username is only guarenteed to be set and/or used for blacklisted users
username String?
locale String?
lastVoted DateTime?
voteCount Int @default(0)
banned Boolean? @default(false)
blacklistedFrom hubBlacklist[]
// if user has seen the welcome message when they first use the network
viewedNetworkWelcome Boolean @default(false)
Expand Down
58 changes: 58 additions & 0 deletions src/commands/slash/Staff/ban.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import {
ApplicationCommandOptionType,
ChatInputCommandInteraction,
RESTPostAPIChatInputApplicationCommandsJSONBody,
} from 'discord.js';
import BaseCommand from '../../../core/BaseCommand.js';
import db from '../../../utils/Db.js';
import { simpleEmbed } from '../../../utils/Utils.js';
import { emojis } from '../../../utils/Constants.js';

export default class Ban extends BaseCommand {
readonly staffOnly = true;
data: RESTPostAPIChatInputApplicationCommandsJSONBody = {
name: 'ban',
description: '🔨 Ban a user from using the bot. (Dev Only)',
options: [
{
type: ApplicationCommandOptionType.User,
name: 'user',
description: '🔨 The user to ban.',
required: true,
},
],
};
override async execute(interaction: ChatInputCommandInteraction): Promise<unknown> {
const user = interaction.options.getUser('user', true);
const alreadyBanned = await db.userData.findFirst({
where: { userId: user.id, banned: true },
});

if (alreadyBanned) {
await interaction.reply({
embeds: [simpleEmbed(`${emojis.slash} User **${user.username}** is already banned.`)],
});
return;
}

await db.userData.upsert({
where: { userId: user.id },
create: {
userId: user.id,
username: user.username,
viewedNetworkWelcome: false,
voteCount: 0,
banned: true,
},
update: {
banned: true,
},
});

await interaction.reply({
embeds: [
simpleEmbed(`${emojis.tick} Successfully banned **${user.username}**. They can no longer use the bot.`),
],
});
}
}
58 changes: 58 additions & 0 deletions src/commands/slash/Staff/unban.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import {
ApplicationCommandOptionType,
ChatInputCommandInteraction,
RESTPostAPIChatInputApplicationCommandsJSONBody,
} from 'discord.js';
import BaseCommand from '../../../core/BaseCommand.js';
import db from '../../../utils/Db.js';
import { simpleEmbed } from '../../../utils/Utils.js';
import { emojis } from '../../../utils/Constants.js';

export default class Unban extends BaseCommand {
readonly staffOnly = true;
data: RESTPostAPIChatInputApplicationCommandsJSONBody = {
name: 'unban',
description: '🔨 Unban a user from using the bot. (Dev Only)',
options: [
{
type: ApplicationCommandOptionType.User,
name: 'user',
description: '🔨 The user to unban.',
required: true,
},
],
};
override async execute(interaction: ChatInputCommandInteraction): Promise<unknown> {
const user = interaction.options.getUser('user', true);
const alreadyBanned = await db.userData.findFirst({
where: { userId: user.id, banned: true },
});

if (!alreadyBanned) {
await interaction.reply({
embeds: [simpleEmbed(`${emojis.slash} User **${user.username}** is not banned.`)],
});
return;
}

await db.userData.upsert({
where: { userId: user.id },
create: {
userId: user.id,
username: user.username,
viewedNetworkWelcome: false,
voteCount: 0,
banned: false,
},
update: {
banned: false,
},
});

await interaction.reply({
embeds: [
simpleEmbed(`${emojis.tick} Successfully banned **${user.username}**. They can no longer use the bot.`),
],
});
}
}
62 changes: 35 additions & 27 deletions src/managers/EventManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import { getAttachmentURL, getUserLocale, handleError, simpleEmbed, wait } from
import { addReaction, updateReactions } from '../scripts/reaction/actions.js';
import { checkBlacklists } from '../scripts/reaction/helpers.js';
import { CustomID } from '../utils/CustomID.js';
import { logServerLeave } from '../utils/HubLogger/JoinLeave.js';
import { logGuildLeaveToHub } from '../utils/HubLogger/JoinLeave.js';
import { deleteConnections, modifyConnection } from '../utils/ConnectedList.js';

export default abstract class EventManager {
Expand Down Expand Up @@ -218,20 +218,17 @@ export default abstract class EventManager {

Logger.info(`Left ${guild.name} (${guild.id})`);

// find all connections that belong to this guild
const connections = await db.connectedList.findMany({ where: { serverId: guild.id } });
// delete them from the database
await deleteConnections({ serverId: guild.id });

// send server leave log to hubs
connections.forEach((connection) => logServerLeave(connection.hubId, guild));
connections.forEach(async (connection) => await logGuildLeaveToHub(connection.hubId, guild));

await logGuildLeave(guild, channels.goal);
}

@GatewayEvent('messageCreate')
static async onMessageCreate(message: Message): Promise<void> {
if (message.author?.bot || message.system || message.webhookId || !message.inGuild()) return;
if (message.author.bot || message.system || message.webhookId || !message.inGuild()) return;

const { connectionCache, cachePopulated } = message.client;

Expand All @@ -243,14 +240,11 @@ export default abstract class EventManager {
return;
}

const locale = await getUserLocale(message.author.id);
message.author.locale = locale;

// check if the message was sent in a network channel
const connection = connectionCache.get(message.channel.id);
if (!connection?.connected) return;

const hub = await db.hubs.findFirst({ where: { id: connection?.hubId } });
const hub = await db.hubs.findFirst({ where: { id: connection.hubId } });
if (!hub) return;

const settings = new HubSettingsBitField(hub.settings);
Expand All @@ -259,11 +253,35 @@ export default abstract class EventManager {
con.hubId === connection.hubId && con.connected && con.channelId !== message.channel.id,
);

const attachment = message.attachments.first();
const attachmentURL = attachment ? attachment.url : await getAttachmentURL(message.content);
let userData = await db.userData.findFirst({ where: { userId: message.author.id } });
if (!userData?.viewedNetworkWelcome) {
userData = await db.userData.upsert({
where: { userId: message.author.id },
create: {
userId: message.author.id,
username: message.author.username,
viewedNetworkWelcome: true,
},
update: { viewedNetworkWelcome: true },
});

await sendWelcomeMsg(message, hubConnections.size.toString(), hub.name);
}

// set locale for the user
message.author.locale = getUserLocale(userData);

const attachmentURL =
message.attachments.first()?.url ?? (await getAttachmentURL(message.content));

// run checks on the message to determine if it can be sent in the network
if (!(await runChecks(message, settings, connection.hubId, { attachmentURL }))) return;
const passingChecks = await runChecks(message, connection.hubId, {
settings,
userData,
attachmentURL,
});

if (passingChecks === false) return;

message.channel.sendTyping().catch(() => null);

Expand All @@ -273,7 +291,6 @@ export default abstract class EventManager {
: null;

const { dbReferrence, referredAuthor } = await getReferredMsgData(referredMessage);

const sendResult = sendBroadcast(message, hub, hubConnections, settings, {
attachmentURL,
dbReferrence,
Expand All @@ -286,12 +303,6 @@ export default abstract class EventManager {
// deleting attachments will make the image not show up in the embed (discord removes it from its cdn)
// if (!attachment) message.delete().catch(() => null);

const userData = await db.userData.findFirst({
where: { userId: message.author.id, viewedNetworkWelcome: true },
});

if (!userData) await sendWelcomeMsg(message, hubConnections.size.toString(), hub.name);

// store the message in the db
await storeMessageData(message, await Promise.all(sendResult), connection.hubId, dbReferrence);
}
Expand All @@ -300,7 +311,8 @@ export default abstract class EventManager {
static async onInteractionCreate(interaction: Interaction): Promise<void> {
try {
const { commands, interactions } = interaction.client;
interaction.user.locale = await getUserLocale(interaction.user.id);
const userData = await db.userData.findFirst({ where: { userId: interaction.user.id } });
interaction.user.locale = getUserLocale(userData);

if (interaction.isMessageComponent() || interaction.isModalSubmit()) {
const ignoreList = ['page_', 'onboarding_'];
Expand Down Expand Up @@ -334,12 +346,8 @@ export default abstract class EventManager {
}

const command = commands.get(interaction.commandName);
if (!interaction.isAutocomplete()) {
await command?.execute(interaction);
} // normal slashie/context menu
else if (command?.autocomplete) {
await command.autocomplete(interaction);
} // autocomplete options
if (!interaction.isAutocomplete()) await command?.execute(interaction); // slash commands
else if (command?.autocomplete) await command.autocomplete(interaction); // autocomplete
}
catch (e) {
handleError(e, interaction);
Expand Down
20 changes: 5 additions & 15 deletions src/scripts/network/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,26 +33,26 @@ export const getReferredContent = (referredMessage: Message) => {
};

export const getReferredMsgData = async (referredMessage: Message | null) => {
if (!referredMessage) return { dbReferrence: undefined, referredAuthor: undefined };
if (!referredMessage) return { dbReferrence: null, referredAuthor: null };

const { client } = referredMessage;

// check if it was sent in the network
const dbReferrence = referredMessage
? (
await db.broadcastedMessages.findFirst({
where: { messageId: referredMessage?.id },
where: { messageId: referredMessage.id },
include: { originalMsg: { include: { broadcastMsgs: true } } },
})
)?.originalMsg
: undefined;
: null;

if (!dbReferrence) return { dbReferrence: undefined, referredAuthor: undefined };
if (!dbReferrence) return { dbReferrence: null, referredAuthor: null };

const referredAuthor =
referredMessage.author.id === client.user.id
? client.user
: await client.users.fetch(dbReferrence.authorId).catch(() => undefined);
: await client.users.fetch(dbReferrence.authorId).catch(() => null); // fetch the acttual user ("referredMessage" is a webhook message)

return { dbReferrence, referredAuthor };
};
Expand Down Expand Up @@ -137,16 +137,6 @@ export const generateJumpButton = (
};

export const sendWelcomeMsg = async (message: Message, totalServers: string, hub: string) => {
await db.userData.upsert({
where: { userId: message.author.id },
create: {
userId: message.author.id,
username: message.author.username,
viewedNetworkWelcome: true,
},
update: { viewedNetworkWelcome: true },
});

const linkButtons = new ActionRowBuilder<ButtonBuilder>().addComponents(
new ButtonBuilder()
.setStyle(ButtonStyle.Link)
Expand Down
Loading

0 comments on commit 0b0e02b

Please sign in to comment.