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

Contents of /branches/8.x/src/commands/moderation/MuteCommand.ts

Parent Directory Parent Directory | Revision Log Revision Log


Revision 577 - (show annotations)
Mon Jul 29 18:52:37 2024 UTC (8 months ago) by rakinar2
File MIME type: application/typescript
File size: 8551 byte(s)
chore: add old version archive branches (2.x to 9.x-dev)
1 /**
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 { formatDistanceToNowStrict } from "date-fns";
21 import {
22 ChatInputCommandInteraction,
23 GuildMember,
24 PermissionsBitField,
25 SlashCommandBuilder,
26 User,
27 escapeMarkdown
28 } from "discord.js";
29 import Command, {
30 ArgumentType,
31 BasicCommandContext,
32 CommandMessage,
33 CommandReturn,
34 ValidationRule
35 } from "../../core/Command";
36 import { stringToTimeInterval } from "../../utils/datetime";
37 import { createModerationEmbed } from "../../utils/utils";
38
39 export default class MuteCommand extends Command {
40 public readonly name = "mute";
41 public readonly validationRules: ValidationRule[] = [
42 {
43 types: [ArgumentType.Member],
44 entity: true,
45 errors: {
46 required: "You must specify a member to mute!",
47 "type:invalid": "You have specified an invalid user mention or ID.",
48 "entity:null": "The given member does not exist in the server!"
49 },
50 name: "member"
51 },
52 {
53 types: [ArgumentType.TimeInterval, ArgumentType.StringRest],
54 optional: true,
55 errors: {
56 "time:range": "The mute duration must be a valid time interval.",
57 "type:invalid":
58 "You have specified an invalid argument. The system expected you to provide a mute reason or the mute duration here."
59 },
60 string: {
61 maxLength: 3999
62 },
63 name: "durationOrReason"
64 },
65 {
66 types: [ArgumentType.StringRest],
67 optional: true,
68 errors: {
69 "type:invalid":
70 "You have specified an invalid argument. The system expected you to provide a mute reason or the mute duration here."
71 },
72 string: {
73 maxLength: 3999
74 },
75 name: "reason"
76 }
77 ];
78 public readonly permissions = [PermissionsBitField.Flags.ModerateMembers];
79
80 public readonly description = "Mutes a server member.";
81 public readonly detailedDescription =
82 "This command mutes a server member. You can specify a duration or make it indefinite. The muted role needs to be configured for this command to work!";
83 public readonly argumentSyntaxes = [
84 "<UserID|UserMention> [reason]",
85 "<UserID|UserMention> [duration] [reason]"
86 ];
87
88 public readonly botRequiredPermissions = [PermissionsBitField.Flags.ModerateMembers];
89
90 public readonly slashCommandBuilder = new SlashCommandBuilder()
91 .addUserOption(option =>
92 option.setName("member").setDescription("The member").setRequired(true)
93 )
94 .addStringOption(option =>
95 option.setName("reason").setDescription("The reason for muting this user")
96 )
97 .addStringOption(option => option.setName("time").setDescription("Mute duration"))
98 .addBooleanOption(option =>
99 option
100 .setName("hardmute")
101 .setDescription(
102 "Specify if the system should take out all roles of the user during the mute"
103 )
104 )
105 .addBooleanOption(option =>
106 option
107 .setName("silent")
108 .setDescription(
109 "Specify if the system should not notify the user about this action. Defaults to false"
110 )
111 );
112
113 async execute(message: CommandMessage, context: BasicCommandContext): Promise<CommandReturn> {
114 const member = context.isLegacy
115 ? context.parsedNamedArgs.member
116 : context.options.getMember("member");
117
118 if (!member) {
119 await message.reply({
120 ephemeral: true,
121 content: "The member is invalid or does not exist."
122 });
123
124 return;
125 }
126 let duration =
127 (!context.isLegacy
128 ? context.options.getString("time") ?? undefined
129 : typeof context.parsedNamedArgs.durationOrReason === "number"
130 ? context.parsedNamedArgs.durationOrReason
131 : undefined) ?? undefined;
132
133 if (typeof duration === "string") {
134 const { error, result } = stringToTimeInterval(duration);
135
136 if (error) {
137 await message.reply({
138 ephemeral: true,
139 content: error
140 });
141
142 return;
143 }
144
145 duration = result;
146 }
147
148 const reason =
149 (!context.isLegacy
150 ? context.options.getString("reason") ?? undefined
151 : typeof context.parsedNamedArgs.durationOrReason === "string"
152 ? context.parsedNamedArgs.durationOrReason
153 : typeof context.parsedNamedArgs.durationOrReason === "number"
154 ? (context.parsedNamedArgs.reason as string | undefined)
155 : undefined) ?? undefined;
156
157 if (message instanceof ChatInputCommandInteraction) {
158 await message.deferReply();
159 }
160
161 if (
162 !(await this.client.permissionManager.shouldModerate(
163 member,
164 message.member! as GuildMember
165 ))
166 ) {
167 await this.error(message, "You don't have permission to mute this user!");
168 return;
169 }
170
171 const {
172 id,
173 result,
174 error,
175 reason: finalReason
176 } = await this.client.infractionManager.createMemberMute(member, {
177 guild: message.guild!,
178 moderator: message.member!.user as User,
179 notifyUser: !context.isLegacy ? !context.options.getBoolean("silent") ?? true : true,
180 reason,
181 sendLog: true,
182 duration: duration
183 ? duration * 1000
184 : undefined /* Convert the duration from seconds to milliseconds */,
185 autoRemoveQueue: true,
186 abortOnTemplateNotFound: true
187 });
188
189 if (error || !id) {
190 await this.deferredReply(message, {
191 content:
192 error ??
193 "An error has occurred during role assignment. Please double check the bot permissions."
194 });
195
196 return;
197 }
198
199 await this.deferredReply(
200 message,
201 {
202 embeds: [
203 await createModerationEmbed({
204 moderator: message.member!.user as User,
205 user: member.user,
206 description: `**${escapeMarkdown(member.user.tag)}** has been muted.${
207 result === false
208 ? "\nFailed to deliver a DM to the user, and the fallback channel could not be created. The user will not know about this mute."
209 : result === null
210 ? "\nCould not deliver a DM since the user is not in the server. They will not know about this mute"
211 : ""
212 }`,
213 actionDoneName: "muted",
214 id,
215 reason: finalReason,
216 fields: [
217 {
218 name: "Duration",
219 value: duration
220 ? formatDistanceToNowStrict(
221 new Date(Date.now() - duration * 1000)
222 )
223 : "*No duration set*"
224 }
225 ]
226 })
227 ]
228 },
229 "auto"
230 );
231 }
232 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26