/[sudobot]/branches/7.x/src/commands/moderation/InfractionCommand.ts
ViewVC logotype

Annotation of /branches/7.x/src/commands/moderation/InfractionCommand.ts

Parent Directory Parent Directory | Revision Log Revision Log


Revision 577 - (hide annotations)
Mon Jul 29 18:52:37 2024 UTC (8 months ago) by rakinar2
File MIME type: application/typescript
File size: 8660 byte(s)
chore: add old version archive branches (2.x to 9.x-dev)
1 rakinar2 577 /**
2     * This file is part of SudoBot.
3     *
4     * Copyright (C) 2021-2023 OSN Developers.
5     *
6     * SudoBot is free software; you can redistribute it and/or modify it
7     * under the terms of the GNU Affero General Public License as published by
8     * the Free Software Foundation, either version 3 of the License, or
9     * (at your option) any later version.
10     *
11     * SudoBot is distributed in the hope that it will be useful, but
12     * WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU Affero General Public License for more details.
15     *
16     * You should have received a copy of the GNU Affero General Public License
17     * along with SudoBot. If not, see <https://www.gnu.org/licenses/>.
18     */
19    
20     import { InfractionType } from "@prisma/client";
21     import { MessageMentions, PermissionsBitField, SlashCommandBuilder } from "discord.js";
22     import Command, { ArgumentType, BasicCommandContext, CommandMessage, CommandReturn, ValidationRule } from "../../core/Command";
23     import { safeUserFetch } from "../../utils/fetch";
24     import { isSnowflake } from "../../utils/utils";
25    
26     const infractionTypes = [
27     {
28     name: "Ban",
29     value: InfractionType.BAN
30     },
31     {
32     name: "Kick",
33     value: InfractionType.KICK
34     },
35     {
36     name: "Mute",
37     value: InfractionType.MUTE
38     },
39     {
40     name: "Warning",
41     value: InfractionType.WARNING
42     },
43     {
44     name: "Unmute",
45     value: InfractionType.UNMUTE
46     },
47     {
48     name: "Unban",
49     value: InfractionType.UNBAN
50     },
51     {
52     name: "Bulk message delete",
53     value: InfractionType.BULK_DELETE_MESSAGE
54     },
55     {
56     name: "Temporary Ban",
57     value: InfractionType.TEMPBAN
58     },
59     {
60     name: "Softban",
61     value: InfractionType.SOFTBAN
62     },
63     {
64     name: "Timeout",
65     value: InfractionType.TIMEOUT
66     },
67     {
68     name: "Timeout remove",
69     value: InfractionType.TIMEOUT_REMOVE
70     }
71     ].map(o => ({ ...o, value: o.value.toLowerCase() }));
72    
73     export default class InfractionCommand extends Command {
74     public readonly name = "infraction";
75     public readonly subcommands = ["view", "create", "edit", "delete", "list", "clear"];
76     public readonly subCommandCheck = true;
77     public readonly validationRules: ValidationRule[] = [
78     {
79     types: [ArgumentType.String],
80     name: "subcommand",
81     errors: {
82     required: `Please provide a valid subcommand! The available subcommands are: \`${this.subcommands.join(
83     "`, `"
84     )}\`.`
85     }
86     }
87     ];
88     public readonly permissions = [PermissionsBitField.Flags.ModerateMembers, PermissionsBitField.Flags.ViewAuditLog];
89     public readonly permissionMode = "or";
90     public readonly description = "Manage infractions.";
91     public readonly detailedDescription = "Use this command to manage infractions.";
92     public readonly argumentSyntaxes = ["<subcommand> [...args]"];
93    
94     public readonly slashCommandBuilder = new SlashCommandBuilder()
95     .addSubcommand(subcommand =>
96     subcommand
97     .setName("view")
98     .setDescription("View information about an infraction")
99     .addIntegerOption(option => option.setName("id").setDescription("The infraction ID").setRequired(true))
100     )
101     .addSubcommand(subcommand =>
102     subcommand
103     .setName("edit")
104     .setDescription("Update reason/duration of an infraction")
105     .addIntegerOption(option => option.setName("id").setDescription("The infraction ID").setRequired(true))
106     .addStringOption(option => option.setName("new_reason").setDescription("New reason to set"))
107     .addStringOption(option => option.setName("new_duration").setDescription("New duration to set"))
108     .addBooleanOption(option =>
109     option
110     .setName("silent")
111     .setDescription("Specify if the bot should not let the user know about this, defaults to true")
112     )
113     )
114     .addSubcommand(subcommand =>
115     subcommand
116     .setName("delete")
117     .setDescription("Delete an infraction")
118     .addIntegerOption(option => option.setName("id").setDescription("The infraction ID").setRequired(true))
119     )
120     .addSubcommand(subcommand =>
121     subcommand
122     .setName("clear")
123     .setDescription("Clear infractions for a user")
124     .addUserOption(option => option.setName("user").setDescription("The target user").setRequired(true))
125     .addStringOption(option =>
126     option
127     .setName("type")
128     .setDescription("Specify infraction type")
129     .setChoices(...infractionTypes)
130     )
131     )
132     .addSubcommand(subcommand =>
133     subcommand
134     .setName("list")
135     .setDescription("List infractions for a user")
136     .addUserOption(option => option.setName("user").setDescription("The target user").setRequired(true))
137     )
138     .addSubcommand(subcommand =>
139     subcommand
140     .setName("create")
141     .setDescription("Add infractions to a user")
142     .addUserOption(option => option.setName("user").setDescription("The target user").setRequired(true))
143     .addStringOption(option =>
144     option
145     .setName("type")
146     .setDescription("Specify infraction type")
147     .setChoices(...infractionTypes)
148     .setRequired(true)
149     )
150     .addStringOption(option => option.setName("reason").setDescription("The reason for giving this infraction"))
151     .addStringOption(option =>
152     option.setName("duration").setDescription("The duration of this infraction (e.g. 45, 1h30m)")
153     )
154     );
155    
156     async execute(message: CommandMessage, context: BasicCommandContext): Promise<CommandReturn> {
157     const subcommand = context.isLegacy ? context.parsedNamedArgs.subcommand : context.options.getSubcommand(true);
158    
159     if ((subcommand === "edit" || subcommand === "create") && context.isLegacy) {
160     await message.reply(
161     `${this.emoji("error")} Please use the slash command \`/infraction ${subcommand}\` to perform this action.`
162     );
163     return;
164     }
165    
166     if (["clear", "list"].includes(subcommand)) {
167     if (context.isLegacy && !context.args[1]) {
168     await message.reply(`${this.emoji("error")} Please provide a user to perform this action!`);
169     return;
170     }
171    
172     if (context.isLegacy) {
173     let userId = "";
174    
175     if (isSnowflake(context.args[1])) {
176     userId = context.args[1];
177     } else if (MessageMentions.UsersPattern.test(context.args[1])) {
178     userId = context.args[1].substring(context.args[1].includes("!") ? 3 : 2, context.args[1].length - 1);
179     } else {
180     await message.reply(
181     `${this.emoji("error")} Please provide a valid user mention or ID to perform this action!`
182     );
183     return;
184     }
185    
186     const user = await safeUserFetch(this.client, userId);
187    
188     if (!user) {
189     await message.reply(`${this.emoji("error")} That user does not exist!`);
190     return;
191     }
192    
193     context.parsedNamedArgs.user = user;
194     }
195     } else {
196     if (context.isLegacy && !context.args[1]) {
197     await message.reply(`${this.emoji("error")} Please provide an infraction ID to perform this action!`);
198     return;
199     }
200    
201     if (context.isLegacy && isNaN(parseInt(context.args[1]))) {
202     await message.reply(`${this.emoji("error")} Please provide a __valid__ infraction ID to perform this action!`);
203     return;
204     }
205    
206     if (context.isLegacy) context.parsedNamedArgs.id = parseInt(context.args[1]);
207     }
208    
209     await this.deferIfInteraction(message);
210    
211     const command = this.client.commands.get(`infraction__${subcommand}`);
212    
213     if (command) {
214     return await command.execute(message, {
215     ...context
216     });
217     }
218     }
219     }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26