From dc4863dc208b3fede4d4def323306ab58daffe04 Mon Sep 17 00:00:00 2001 From: PalmDevs Date: Mon, 24 Jun 2024 18:46:27 +0700 Subject: [PATCH] feat(bots/discord/commands): add `ban` and `unban` commands --- bots/discord/src/commands/moderation/ban.ts | 49 +++++++++++++++++++ bots/discord/src/commands/moderation/unban.ts | 41 ++++++++++++++++ 2 files changed, 90 insertions(+) create mode 100644 bots/discord/src/commands/moderation/ban.ts create mode 100644 bots/discord/src/commands/moderation/unban.ts diff --git a/bots/discord/src/commands/moderation/ban.ts b/bots/discord/src/commands/moderation/ban.ts new file mode 100644 index 0000000..ee5ec14 --- /dev/null +++ b/bots/discord/src/commands/moderation/ban.ts @@ -0,0 +1,49 @@ +import { SlashCommandBuilder } from 'discord.js' + +import type { Command } from '..' + +import { config } from '$/context' +import { applyReferenceToModerationActionEmbed, createModerationActionEmbed } from '$/utils/discord/embeds' +import { parseDuration } from '$/utils/duration' + +export default { + data: new SlashCommandBuilder() + .setName('ban') + .setDescription('Ban a user') + .addUserOption(option => option.setName('user').setRequired(true).setDescription('The user to ban')) + .addStringOption(option => option.setName('reason').setDescription('The reason for banning the user')) + .addStringOption(option => + option.setName('dmd').setDescription('Duration to delete messages (must be from 0 to 7 days)'), + ) + .toJSON(), + + memberRequirements: { + roles: config.moderation?.roles ?? [], + }, + + global: false, + + async execute({ config, logger }, interaction) { + const user = interaction.options.getUser('member', true) + const reason = interaction.options.getString('reason') ?? undefined + const dmd = interaction.options.getString('dmd') + + const dms = Math.floor(dmd ? parseDuration(dmd) : 0 / 1000) + await interaction.guild!.members.ban(user, { + reason: `Banned by moderator ${interaction.user.tag} (${interaction.user.id}): ${reason}`, + deleteMessageSeconds: dms, + }) + + const embed = createModerationActionEmbed('Banned', user, interaction.user, reason ?? 'No reason provided') + const reply = await interaction.reply({ embeds: [embed] }).then(it => it.fetch()) + + const logConfig = config.moderation?.log + if (logConfig) { + const channel = await interaction.guild!.channels.fetch(logConfig.thread ?? logConfig.channel) + if (!channel || !channel.isTextBased()) + return void logger.warn('The moderation log channel does not exist, skipping logging') + + await channel.send({ embeds: [applyReferenceToModerationActionEmbed(embed, reply.url)] }) + } + }, +} satisfies Command diff --git a/bots/discord/src/commands/moderation/unban.ts b/bots/discord/src/commands/moderation/unban.ts new file mode 100644 index 0000000..0e9946f --- /dev/null +++ b/bots/discord/src/commands/moderation/unban.ts @@ -0,0 +1,41 @@ +import { SlashCommandBuilder } from 'discord.js' + +import type { Command } from '..' + +import { config } from '$/context' +import { applyReferenceToModerationActionEmbed, createModerationActionEmbed } from '$/utils/discord/embeds' + +export default { + data: new SlashCommandBuilder() + .setName('unban') + .setDescription('Unban a user') + .addUserOption(option => option.setName('user').setRequired(true).setDescription('The user to unban')) + .toJSON(), + + memberRequirements: { + roles: config.moderation?.roles ?? [], + }, + + global: false, + + async execute({ config, logger }, interaction) { + const user = interaction.options.getUser('member', true) + + await interaction.guild!.members.unban( + user, + `Unbanned by moderator ${interaction.user.tag} (${interaction.user.id})`, + ) + + const embed = createModerationActionEmbed('Unbanned', user, interaction.user) + const reply = await interaction.reply({ embeds: [embed] }).then(it => it.fetch()) + + const logConfig = config.moderation?.log + if (logConfig) { + const channel = await interaction.guild!.channels.fetch(logConfig.thread ?? logConfig.channel) + if (!channel || !channel.isTextBased()) + return void logger.warn('The moderation log channel does not exist, skipping logging') + + await channel.send({ embeds: [applyReferenceToModerationActionEmbed(embed, reply.url)] }) + } + }, +} satisfies Command