/[sudobot]/branches/8.x/src/commands/moderation/SoftBanCommand.ts
ViewVC logotype

Annotation of /branches/8.x/src/commands/moderation/SoftBanCommand.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: 8210 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 { formatDistanceToNow } from "date-fns";
21     import {
22     GuildMember,
23     PermissionsBitField,
24     SlashCommandBuilder,
25     User,
26     escapeMarkdown
27     } from "discord.js";
28     import Command, {
29     ArgumentType,
30     BasicCommandContext,
31     CommandMessage,
32     CommandReturn,
33     ValidationRule
34     } from "../../core/Command";
35     import { logError } from "../../utils/Logger";
36     import { stringToTimeInterval } from "../../utils/datetime";
37     import { createModerationEmbed } from "../../utils/utils";
38    
39     export default class SoftBanCommand extends Command {
40     public readonly name = "softban";
41     public readonly validationRules: ValidationRule[] = [
42     {
43     types: [ArgumentType.User],
44     entity: true,
45     errors: {
46     required: "You must specify a user to ban!",
47     "type:invalid": "You have specified an invalid user mention or ID.",
48     "entity:null": "The given user does not exist!"
49     },
50     name: "user"
51     },
52     {
53     types: [ArgumentType.TimeInterval, ArgumentType.StringRest],
54     optional: true,
55     errors: {
56     "type:invalid":
57     "You have specified an invalid argument. The system expected you to provide a ban reason or the message deletion timeframe here.",
58     "time:range":
59     "The message deletion range must be a time interval from 0 second to 604800 seconds (7 days)."
60     },
61     string: {
62     maxLength: 3999
63     },
64     time: {
65     min: 0,
66     max: 604800
67     },
68     name: "timeframeOrReason",
69     default: 604800
70     },
71     {
72     types: [ArgumentType.StringRest],
73     optional: true,
74     errors: {
75     "type:invalid": "You have specified an invalid ban reason."
76     },
77     string: {
78     maxLength: 3999
79     },
80     name: "reason"
81     }
82     ];
83     public readonly permissions = [PermissionsBitField.Flags.BanMembers];
84    
85     public readonly description = "Softbans a user.";
86     public readonly detailedDescription =
87     "This command bans a user, then unbans immediately. This is helpful if you want to remove the recent messages by a user.";
88     public readonly argumentSyntaxes = [
89     "<UserID|UserMention> [Reason]",
90     "<UserID|UserMention> [MessageDeletionTime] [Reason]"
91     ];
92    
93     public readonly botRequiredPermissions = [PermissionsBitField.Flags.BanMembers];
94    
95     public readonly slashCommandBuilder = new SlashCommandBuilder()
96     .addUserOption(option =>
97     option.setName("user").setDescription("The user").setRequired(true)
98     )
99     .addStringOption(option =>
100     option.setName("reason").setDescription("The reason for softbanning this user")
101     )
102     .addStringOption(option =>
103     option
104     .setName("deletion_timeframe")
105     .setDescription(
106     "The message deletion timeframe, defaults to 7 days (must be in range 0-7 days)"
107     )
108     )
109     .addBooleanOption(option =>
110     option
111     .setName("silent")
112     .setDescription(
113     "Specify if the system should not notify the user about this action. Defaults to false"
114     )
115     );
116    
117     async execute(message: CommandMessage, context: BasicCommandContext): Promise<CommandReturn> {
118     await this.deferIfInteraction(message);
119    
120     const user: User = context.isLegacy
121     ? context.parsedNamedArgs.user
122     : context.options.getUser("user", true);
123    
124     let messageDeletionTimeframe = !context.isLegacy
125     ? undefined
126     : typeof context.parsedNamedArgs.timeframeOrReason === "number"
127     ? context.parsedNamedArgs.timeframeOrReason
128     : undefined;
129     const reason = !context.isLegacy
130     ? context.options.getString("reason") ?? undefined
131     : typeof context.parsedNamedArgs.timeframeOrReason === "string"
132     ? context.parsedNamedArgs.timeframeOrReason
133     : context.parsedNamedArgs.reason;
134    
135     ifContextIsNotLegacy: if (!context.isLegacy) {
136     const input = context.options.getString("deletion_timeframe");
137    
138     if (!input) break ifContextIsNotLegacy;
139    
140     const { result, error } = stringToTimeInterval(input);
141    
142     if (error) {
143     await this.deferredReply(message, {
144     content: `${this.emoji(
145     "error"
146     )} ${error} provided in the \`deletion_timeframe\` option`
147     });
148    
149     return;
150     }
151    
152     if (result < 0 || result > 604800) {
153     await this.deferredReply(
154     message,
155     `${this.emoji(
156     "error"
157     )} The message deletion range must be a time interval from 0 second to 604800 seconds (7 days).`
158     );
159     return;
160     }
161    
162     messageDeletionTimeframe = result;
163     }
164    
165     messageDeletionTimeframe ??= 604800;
166    
167     try {
168     const member =
169     message.guild!.members.cache.get(user.id) ??
170     (await message.guild!.members.fetch(user.id));
171    
172     if (
173     !(await this.client.permissionManager.shouldModerate(
174     member,
175     message.member! as GuildMember
176     ))
177     ) {
178     await this.error(message, "You don't have permission to softban this user!");
179     return;
180     }
181     } catch (e) {
182     logError(e);
183     }
184    
185     const infraction = await this.client.infractionManager.createUserSoftban(user, {
186     guild: message.guild!,
187     moderator: message.member!.user as User,
188     deleteMessageSeconds: messageDeletionTimeframe,
189     reason,
190     notifyUser: context.isLegacy ? true : !context.options.getBoolean("silent"),
191     sendLog: true,
192     abortOnTemplateNotFound: true
193     });
194    
195     if (!infraction) {
196     await this.error(message);
197     return;
198     }
199    
200     await this.deferredReply(
201     message,
202     {
203     embeds: [
204     await createModerationEmbed({
205     moderator: message.member!.user as User,
206     user,
207     actionDoneName: "softbanned",
208     description: `**${escapeMarkdown(user.tag)}** was softbanned.`,
209     fields: [
210     {
211     name: "Message Deletion",
212     value: messageDeletionTimeframe
213     ? `Timeframe: ${formatDistanceToNow(
214     new Date(Date.now() - messageDeletionTimeframe * 1000)
215     )}\nMessages in this timeframe by this user will be removed.`
216     : "*No message will be deleted*"
217     }
218     ],
219     id: `${infraction.id}`,
220     reason: infraction.reason
221     })
222     ]
223     },
224     "auto"
225     );
226     }
227     }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26