From ecf9c5e4fc805be2db21510fa77ed5cf2d0958ad Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Mon, 29 Nov 2021 11:27:44 +0000 Subject: [PATCH] Migrate ban command --- .env.template | 13 +++-- commands/ban.js | 93 ---------------------------------- src/commands/ban.ts | 61 ++++++++++++++++++++++ src/constants/ErrorMessages.ts | 4 ++ src/helpers/ErrorEmbed.ts | 19 +++++++ src/helpers/LogEmbed.ts | 60 ++++++++++++++++++++++ src/helpers/PublicEmbed.ts | 21 ++++++++ src/vylbot.ts | 8 +++ 8 files changed, 183 insertions(+), 96 deletions(-) delete mode 100644 commands/ban.js create mode 100644 src/commands/ban.ts create mode 100644 src/constants/ErrorMessages.ts create mode 100644 src/helpers/ErrorEmbed.ts create mode 100644 src/helpers/LogEmbed.ts create mode 100644 src/helpers/PublicEmbed.ts diff --git a/.env.template b/.env.template index 351704b..bfbe4a3 100644 --- a/.env.template +++ b/.env.template @@ -14,10 +14,17 @@ BOT_DATE=28 Nov 2021 CORE_VER=2.0.2 -FOLDERS_COMMANDS=commands -FOLDERS_EVENTS=events +FOLDERS_COMMANDS=src/commands +FOLDERS_EVENTS=src/events COMMANDS_DISABLED= COMMANDS_DISABLED_MESSAGE=This command is disabled. -EMBED_COLOUR=0x3050ba \ No newline at end of file +EMBED_COLOUR=0x3050ba +EMBED_COLOUR_ERROR=0xD52803 + +ROLES_MODERATOR=Moderator + +CHANNELS_LOGS_MESSAGE=message-logs +CHANNELS_LOGS_MEMBER=member-logs +CHANNELS_LOGS_MOD=mod-logs \ No newline at end of file diff --git a/commands/ban.js b/commands/ban.js deleted file mode 100644 index c8acbb9..0000000 --- a/commands/ban.js +++ /dev/null @@ -1,93 +0,0 @@ -// Required components -const { command } = require('vylbot-core'); -const { MessageEmbed } = require('discord.js'); - -const embedColor = "0x3050ba"; - -// Command Class -class ban extends command { - constructor() { - // Set execution method, description, category, and usage - super("ban"); - super.description = "Bans the mentioned user with an optional reason"; - super.category = "Moderation"; - super.usage = "<@user> [reason]"; - - // Set required configs in the config.ban json string - super.requiredConfigs = "modrole"; - super.requiredCofigs = "logchannel"; - } - - // Command execution method - ban(context) { - // If the user has the modrole (set in config.ban.modrole) - if (context.message.guild.roles.cache.find(role => role.name == context.client.config.ban.modrole)) { - // Gets the user pinged in the command - const user = context.message.mentions.users.first(); - - // If the user pinged is a valid user - if (user) { - // Get the guild member object from the pinged user - const member = context.message.guild.member(user); - - // If the member object exists, i.e. if they are in the server - if (member) { - // Get the arguments and remove what isn't the reason - const reasonArgs = context.arguments; - reasonArgs.splice(0, 1); - - // Join the array into a string - const reason = reasonArgs.join(" "); - - // If the guild is available to work with - if (context.message.guild.available) { - // If the bot client is able to ban the member - if (member.bannable) { - // The Message Embed which goes into the bot log - const embedLog = new MessageEmbed() - .setTitle("Member Banned") - .setColor(embedColor) - .addField("User", `${user} \`${user.tag}\``, true) - .addField("Moderator", `${context.message.author} \`${context.message.author.tag}\``, true) - .addField("Reason", reason || "*none*") - .setThumbnail(user.displayAvatarURL); - - // The Message Embed which goes into the public channel the message was sent in - const embedPublic = new MessageEmbed() - .setColor(embedColor) - .setDescription(`${user} has been banned`); - - // Ban the member and send the embeds into the appropriate channel, then delete the initial message - member.ban({ reason: reason }).then(() => { - context.message.guild.channels.cache.find(channel => channel.name == context.client.config.ban.logchannel).send(embedLog); - context.message.channel.send(embedPublic); - - context.message.delete(); - }).catch(err => { // If the bot couldn't ban the member, say so and log the error to the console - errorEmbed(context, "An error occurred"); - console.log(err); - }); - } - } - } else { // If the member object doesn't exist - errorEmbed(context, "User is not in this server"); - } - } else { // If the user object doesn't exist - errorEmbed(context, "User does not exist"); - } - } else { // If the user doesn't have the mod role - errorEmbed(context, `You require the \`${context.client.config.ban.modrole}\` role to run this command`); - } - } -} - -// Post an error embed -function errorEmbed(context, message) { - const embed = new MessageEmbed() - .setColor(embedColor) - .setDescription(message); - - context.message.channel.send(embed); -} - -module.exports = ban; diff --git a/src/commands/ban.ts b/src/commands/ban.ts new file mode 100644 index 0000000..b0a1371 --- /dev/null +++ b/src/commands/ban.ts @@ -0,0 +1,61 @@ +import { Command, ICommandContext } from "vylbot-core"; +import ErrorEmbed from "../helpers/ErrorEmbed"; +import ErrorMessages from "../constants/ErrorMessages"; +import LogEmbed from "../helpers/LogEmbed"; +import PublicEmbed from "../helpers/PublicEmbed"; + +export default class Bane extends Command { + constructor() { + super(); + + super._category = "Moderation"; + super._roles = [ + process.env.ROLES_MODERATOR! + ]; + } + + public override async execute(context: ICommandContext) { + const targetUser = context.message.mentions.users.first(); + + if (!targetUser) { + const embed = new ErrorEmbed(context, "User does not exist"); + embed.SendToCurrentChannel(); + return; + } + + const targetMember = context.message.guild?.member(targetUser); + + if (!targetMember) { + const embed = new ErrorEmbed(context, "User is not in this server"); + embed.SendToCurrentChannel(); + return; + } + + const reasonArgs = context.args; + reasonArgs.splice(0, 1) + + const reason = reasonArgs.join(" "); + + if (!context.message.guild?.available) { + return; + } + + if (!targetMember.bannable) { + const embed = new ErrorEmbed(context, ErrorMessages.InsufficientBotPermissions); + embed.SendToCurrentChannel(); + return; + } + + const logEmbed = new LogEmbed(context, "Member Banned"); + logEmbed.AddUser("User", targetUser, true); + logEmbed.AddUser("Moderator", context.message.author); + logEmbed.AddReason(reason); + + const publicEmbed = new PublicEmbed(context, "", `${targetUser} has been banned`); + + await targetMember.ban({ reason: reason }); + + logEmbed.SendToModLogsChannel(); + publicEmbed.SendToCurrentChannel(); + } +} \ No newline at end of file diff --git a/src/constants/ErrorMessages.ts b/src/constants/ErrorMessages.ts new file mode 100644 index 0000000..d3c1fe1 --- /dev/null +++ b/src/constants/ErrorMessages.ts @@ -0,0 +1,4 @@ +export default class ErrorMessages { + public static readonly InsufficientBotPermissions = "Unable to do this action, am I missing permissions?"; + public static readonly CantFindChannel = "Unable to find channel"; +} \ No newline at end of file diff --git a/src/helpers/ErrorEmbed.ts b/src/helpers/ErrorEmbed.ts new file mode 100644 index 0000000..9964369 --- /dev/null +++ b/src/helpers/ErrorEmbed.ts @@ -0,0 +1,19 @@ +import { MessageEmbed } from "discord.js"; +import { ICommandContext } from "vylbot-core"; + +export default class ErrorEmbed extends MessageEmbed { + private _context: ICommandContext; + + constructor(context: ICommandContext, message: String) { + super(); + + super.setColor(process.env.EMBED_COLOUR_ERROR!); + super.setDescription(message); + + this._context = context; + } + + public SendToCurrentChannel() { + this._context.message.channel.send(this); + } +} \ No newline at end of file diff --git a/src/helpers/LogEmbed.ts b/src/helpers/LogEmbed.ts new file mode 100644 index 0000000..5a801d1 --- /dev/null +++ b/src/helpers/LogEmbed.ts @@ -0,0 +1,60 @@ +import { MessageEmbed, TextChannel, User } from "discord.js"; +import { ICommandContext } from "vylbot-core"; +import ErrorMessages from "../constants/ErrorMessages"; +import ErrorEmbed from "./ErrorEmbed"; + +export default class LogEmbed extends MessageEmbed { + private _context: ICommandContext; + + constructor(context: ICommandContext, title: string) { + super(); + + super.setColor(process.env.ERROR_EMBED!); + super.setTitle(title); + + this._context = context; + } + + // Detail methods + public AddUser(title: string, user: User, setThumbnail: boolean = false) { + super.addField(title, `${user} \`${user.tag}\``, true); + + if (setThumbnail) { + super.setThumbnail(user.displayAvatarURL()); + } + } + + public AddReason(message: String) { + super.addField("Reason", message || "*none*"); + } + + // Send methods + public SendToCurrentChannel() { + this._context.message.channel.send(this); + } + + public SendToChannel(name: string) { + const channel = this._context.message.guild?.channels.cache + .find(channel => channel.name == name) as TextChannel; + + if (!channel) { + const errorEmbed = new ErrorEmbed(this._context, ErrorMessages.CantFindChannel); + errorEmbed.SendToCurrentChannel(); + return; + } + + channel.send(this); + } + + public SendToMessageLogsChannel() { + this.SendToChannel(process.env.CHANNELS_LOGS_MESSAGE!) + } + + public SendToMemberLogsChannel() { + this.SendToChannel(process.env.CHANNELS_LOGS_MEMBER!) + } + + public SendToModLogsChannel() { + this.SendToChannel(process.env.CHANNELS_LOGS_MOD!) + } +} \ No newline at end of file diff --git a/src/helpers/PublicEmbed.ts b/src/helpers/PublicEmbed.ts new file mode 100644 index 0000000..75d99fe --- /dev/null +++ b/src/helpers/PublicEmbed.ts @@ -0,0 +1,21 @@ +import { MessageEmbed } from "discord.js"; +import { ICommandContext } from "vylbot-core"; + +export default class PublicEmbed extends MessageEmbed { + private _context: ICommandContext; + + constructor(context: ICommandContext, title: string, description: string) { + super(); + + super.setColor(process.env.ERROR_EMBED!); + super.setTitle(title); + super.setDescription(description); + + this._context = context; + } + + // Send methods + public SendToCurrentChannel() { + this._context.message.channel.send(this); + } +} \ No newline at end of file diff --git a/src/vylbot.ts b/src/vylbot.ts index 73bd1df..c9b0eee 100644 --- a/src/vylbot.ts +++ b/src/vylbot.ts @@ -3,7 +3,15 @@ import * as dotenv from "dotenv"; dotenv.config(); +// Ensure required data is in dotenv if (!process.env.EMBED_COLOUR) throw "EMBED_COLOUR is required in .env"; +if (!process.env.EMBED_COLOUR_ERROR) throw "EMBED_COLOUR_ERROR is required in .env"; + +if (!process.env.ROLES_MODERATOR) throw "ROLES_MODERATOR is required in .env"; + +if (!process.env.CHANNELS_LOGS_MESSAGE) throw "CHANNELS_LOGS_MESSAGE is required in .env"; +if (!process.env.CHANNELS_LOGS_MEMBER) throw "CHANNELS_LOGS_MEMBER is required in .env"; +if (!process.env.CHANNELS_LOGS_MOD) throw "CHANNELS_LOGS_MOD is required in .env"; const client = new CoreClient(); client.start(); \ No newline at end of file