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

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26