aboutsummaryrefslogtreecommitdiff
path: root/src/commands/moderation/mute.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/commands/moderation/mute.ts')
-rw-r--r--src/commands/moderation/mute.ts166
1 files changed, 166 insertions, 0 deletions
diff --git a/src/commands/moderation/mute.ts b/src/commands/moderation/mute.ts
new file mode 100644
index 0000000..9b6ad70
--- /dev/null
+++ b/src/commands/moderation/mute.ts
@@ -0,0 +1,166 @@
+import { Argument } from 'discord-akairo';
+import { CommandInteraction, Message, User } from 'discord.js';
+import moment from 'moment';
+import { BushCommand } from '../../lib/extensions/BushCommand';
+import { Guild, ModLog, ModLogType, Mute } from '../../lib/models';
+
+export default class MuteCommand extends BushCommand {
+ constructor() {
+ super('mute', {
+ aliases: ['mute'],
+ category: 'moderation',
+ args: [
+ {
+ id: 'user',
+ type: 'user',
+ prompt: {
+ start: 'What user would you like to mute?',
+ retry: '{error} Choose a valid user to mute.'
+ }
+ },
+ {
+ id: 'reason',
+ match: 'separate',
+ prompt: {
+ start: 'Why would you like to mute this user?',
+ retry: '{error} Choose a mute reason.',
+ optional: true
+ }
+ },
+ {
+ id: 'time',
+ type: 'duration',
+ match: 'option',
+ flag: '--time'
+ }
+ ],
+ clientPermissions: ['MANAGE_ROLES'],
+ userPermissions: ['MANAGE_MESSAGES'],
+ description: {
+ content: 'Mute a user.',
+ usage: 'mute <member> <reason> [--time]',
+ examples: ['mute @user bad boi --time 1h']
+ },
+ slashOptions: [
+ {
+ type: 'USER',
+ name: 'user',
+ description: 'The user to mute.',
+ required: true
+ },
+ {
+ type: 'STRING',
+ name: 'reason',
+ description: 'Why the user is getting muted.',
+ required: false
+ },
+ {
+ type: 'STRING',
+ name: 'time',
+ description: 'How long the user should be muted for.',
+ required: false
+ }
+ ],
+ slash: true
+ });
+ }
+ async *genResponses(
+ message: Message | CommandInteraction,
+ user: User,
+ reason?: string,
+ time?: number
+ ): AsyncIterable<string> {
+ const duration = moment.duration(time);
+ let modlogEnry: ModLog;
+ let muteEntry: Mute;
+ // Create guild entry so postgres doesn't get mad when I try and add a modlog entry
+ await Guild.findOrCreate({
+ where: {
+ id: message.guild.id
+ },
+ defaults: {
+ id: message.guild.id
+ }
+ });
+ try {
+ const muteRole = (await Guild.findByPk(message.guild.id)).get('muteRole');
+ try {
+ if (time) {
+ modlogEnry = ModLog.build({
+ user: user.id,
+ guild: message.guild.id,
+ reason,
+ type: ModLogType.TEMP_MUTE,
+ duration: duration.asMilliseconds(),
+ moderator: message instanceof CommandInteraction ? message.user.id : message.author.id
+ });
+ muteEntry = Mute.build({
+ user: user.id,
+ guild: message.guild.id,
+ reason,
+ expires: new Date(new Date().getTime() + duration.asMilliseconds()),
+ modlog: modlogEnry.id
+ });
+ } else {
+ modlogEnry = ModLog.build({
+ user: user.id,
+ guild: message.guild.id,
+ reason,
+ type: ModLogType.MUTE,
+ moderator: message instanceof CommandInteraction ? message.user.id : message.author.id
+ });
+ muteEntry = Mute.build({
+ user: user.id,
+ guild: message.guild.id,
+ reason,
+ modlog: modlogEnry.id
+ });
+ }
+ await modlogEnry.save();
+ await muteEntry.save();
+ } catch (e) {
+ this.client.console.error(`MuteCommand`, `Error saving to database. ${e?.stack}`);
+ yield `${this.client.util.emojis.error} Error saving to database. Please report this to a developer.`;
+ return;
+ }
+ try {
+ await user.send(
+ `You were muted in ${message.guild.name} ${time ? `for ${duration.humanize()}` : 'permanently'} with reason \`${
+ reason || 'No reason given'
+ }\``
+ );
+ } catch (e) {
+ yield `${this.client.util.emojis.warn} Unable to dm user`;
+ }
+ await (
+ await message.guild.members.fetch(user)
+ ).roles.add(
+ muteRole,
+ `Muted by ${message instanceof CommandInteraction ? message.user.tag : message.author.tag} with ${
+ reason ? `reason ${reason}` : 'no reason'
+ }`
+ );
+ yield `${this.client.util.emojis.success} muted <@!${user.id}> ${
+ time ? `for ${duration.humanize()}` : 'permanently'
+ } with reason \`${reason || 'No reason given'}\``;
+ } catch {
+ yield `${this.client.util.emojis.error} Error muting :/`;
+ await muteEntry.destroy();
+ await modlogEnry.destroy();
+ return;
+ }
+ }
+ async exec(
+ message: Message,
+ { user, reason, time }: { user: User; reason?: string[]; time?: string | number }
+ ): Promise<void> {
+ this.client.console.debug(reason);
+
+ if (typeof time === 'string') {
+ time = (await Argument.cast('duration', this.client.commandHandler.resolver, message, time)) as number;
+ }
+ for await (const response of this.genResponses(message, user, reason.join(' '), time)) {
+ await message.util.sendNew(response);
+ }
+ }
+}