aboutsummaryrefslogtreecommitdiff
path: root/src/commands/moderation/timeout.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/commands/moderation/timeout.ts')
-rw-r--r--src/commands/moderation/timeout.ts100
1 files changed, 100 insertions, 0 deletions
diff --git a/src/commands/moderation/timeout.ts b/src/commands/moderation/timeout.ts
new file mode 100644
index 0000000..f187a58
--- /dev/null
+++ b/src/commands/moderation/timeout.ts
@@ -0,0 +1,100 @@
+import { AllowedMentions, BushCommand, Moderation, type ArgType, type BushMessage, type BushSlashMessage } from '#lib';
+import assert from 'assert';
+
+export default class TimeoutCommand extends BushCommand {
+ public constructor() {
+ super('timeout', {
+ aliases: ['timeout'],
+ category: 'moderation',
+ description: 'Timeout a user.',
+ usage: ['timeout <user> <reasonAndDuration>'],
+ examples: ['timeout IRONM00N 2h'],
+ args: [
+ {
+ id: 'user',
+ description: 'The user to timeout.',
+ type: 'user',
+ prompt: 'What user would you like to timeout?',
+ retry: '{error} Choose a valid user to timeout.',
+ slashType: 'USER'
+ },
+ {
+ id: 'reason_and_duration',
+ description: 'The reason and duration of the timeout.',
+ type: 'contentWithDuration',
+ match: 'rest',
+ prompt: 'Why should this user be timed out and for how long?',
+ retry: '{error} Choose a valid timeout reason and duration.',
+ slashType: 'STRING'
+ },
+ {
+ id: 'force',
+ description: 'Override permission checks.',
+ flag: '--force',
+ match: 'flag',
+ optional: true,
+ slashType: false,
+ only: 'text',
+ ownerOnly: true
+ }
+ ],
+ slash: true,
+ channel: 'guild',
+ clientPermissions: (m) => util.clientSendAndPermCheck(m, ['MODERATE_MEMBERS']),
+ userPermissions: ['MODERATE_MEMBERS']
+ });
+ }
+
+ public override async exec(
+ message: BushMessage | BushSlashMessage,
+ args: { user: ArgType<'user'>; reason_and_duration: ArgType<'contentWithDuration'> | string; force?: ArgType<'boolean'> }
+ ) {
+ const reason = args.reason_and_duration
+ ? typeof args.reason_and_duration === 'string'
+ ? await util.arg.cast('contentWithDuration', message, args.reason_and_duration)
+ : args.reason_and_duration
+ : { duration: null, contentWithoutTime: '' };
+
+ if (reason.duration === null || reason.duration < 1)
+ return await message.util.reply(`${util.emojis.error} You must specify a duration for timeouts.`);
+ const member = await message.guild!.members.fetch(args.user.id).catch(() => null);
+ if (!member)
+ return await message.util.reply(`${util.emojis.error} The user you selected is not in the server or is not a valid user.`);
+
+ assert(message.member);
+ const useForce = args.force && message.author.isOwner();
+ const canModerateResponse = await Moderation.permissionCheck(message.member, member, 'timeout', true, useForce);
+
+ if (canModerateResponse !== true) {
+ return message.util.reply(canModerateResponse);
+ }
+
+ const time = reason.duration;
+ const parsedReason = reason.contentWithoutTime ?? '';
+
+ const responseCode = await member.bushTimeout({
+ reason: parsedReason,
+ moderator: message.member,
+ duration: time
+ });
+
+ const responseMessage = (): string => {
+ const victim = util.format.input(member.user.tag);
+ switch (responseCode) {
+ case 'missing permissions':
+ return `${util.emojis.error} Could not timeout ${victim} because I am missing the **Timeout Members** permission.`;
+ case 'duration too long':
+ return `${util.emojis.error} The duration you specified is too long, the longest you can timeout someone for is 28 days.`;
+ case 'error timing out':
+ return `${util.emojis.error} An unknown error occurred while trying to timeout ${victim}.`;
+ case 'error creating modlog entry':
+ return `${util.emojis.error} There was an error creating a modlog entry, please report this to my developers.`;
+ case 'failed to dm':
+ return `${util.emojis.warn} Timed out ${victim} however I could not send them a dm.`;
+ case 'success':
+ return `${util.emojis.success} Successfully timed out ${victim}.`;
+ }
+ };
+ return await message.util.reply({ content: responseMessage(), allowedMentions: AllowedMentions.none() });
+ }
+}