/[sudobot]/trunk/src/commands/moderation/TempBanCommand.ts
ViewVC logotype

Contents of /trunk/src/commands/moderation/TempBanCommand.ts

Parent Directory Parent Directory | Revision Log Revision Log


Revision 194 - (show annotations)
Mon Jul 29 17:28:58 2024 UTC (8 months, 1 week ago) by rakin
File MIME type: application/typescript
File size: 7643 byte(s)
feat: add proper permission checking and error messages
1 import { BanOptions, CommandInteraction, GuildMember, Interaction, Message, User } from 'discord.js';
2 import BaseCommand from '../../utils/structures/BaseCommand';
3 import DiscordClient from '../../client/Client';
4 import CommandOptions from '../../types/CommandOptions';
5 import InteractionOptions from '../../types/InteractionOptions';
6 import MessageEmbed from '../../client/MessageEmbed';
7 import getUser from '../../utils/getUser';
8 import History from '../../automod/History';
9 import Punishment from '../../models/Punishment';
10 import PunishmentType from '../../types/PunishmentType';
11 import { fetchEmojiStr } from '../../utils/Emoji';
12 import ms from 'ms';
13 import { clearTimeoutv2, getTimeouts, setTimeoutv2 } from '../../utils/setTimeout';
14 import { hasPermission, shouldNotModerate } from '../../utils/util';
15
16 export default class TempBanCommand extends BaseCommand {
17 supportsInteractions: boolean = true;
18
19 constructor() {
20 super('tempban', 'moderation', []);
21 }
22
23 async run(client: DiscordClient, msg: Message | CommandInteraction, options: CommandOptions | InteractionOptions) {
24 if (!options.isInteraction && typeof options.args[1] === 'undefined') {
25 await msg.reply({
26 embeds: [
27 new MessageEmbed()
28 .setColor('#f14a60')
29 .setDescription(`This command requires at least two arguments.`)
30 ]
31 });
32
33 return;
34 }
35
36 let user: User;
37 let banOptions: BanOptions = {
38 days: 7
39 };
40 let time;
41
42 if (options.isInteraction) {
43 user = await <User> options.options.getUser('user');
44 time = await <string> options.options.getString('time');
45
46 if (options.options.getString('reason')) {
47 banOptions.reason = await <string> options.options.getString('reason');
48 }
49
50 if (options.options.getInteger('days')) {
51 banOptions.days = await <number> options.options.getInteger('days');
52 }
53 }
54 else {
55 const user2 = await getUser(client, (msg as Message), options);
56
57 if (!user2) {
58 await msg.reply({
59 embeds: [
60 new MessageEmbed()
61 .setColor('#f14a60')
62 .setDescription(`Invalid user given.`)
63 ]
64 });
65
66 return;
67 }
68
69 user = user2;
70
71 options.args.shift();
72
73 time = options.args[0];
74
75 const index = await options.args.indexOf('-d');
76
77 if (options.args[1]) {
78 const args = [...options.args];
79 args.shift();
80
81 if (index !== -1) {
82 args.splice(index - 1, 2)
83 }
84
85 banOptions.reason = await args.join(' ');
86 }
87
88 if (index !== -1) {
89 const days = await options.args[index + 1];
90
91 if (days === undefined) {
92 await msg.reply({
93 embeds: [
94 new MessageEmbed()
95 .setColor('#f14a60')
96 .setDescription(`Option \`-d\` (days) requires an argument.`)
97 ]
98 });
99
100 return;
101 }
102
103 if (!parseInt(days) || parseInt(days) < 0 || parseInt(days) > 7) {
104 await msg.reply({
105 embeds: [
106 new MessageEmbed()
107 .setColor('#f14a60')
108 .setDescription(`Option \`-d\` (days) requires an argument which must be a valid number and in range of 0-7.`)
109 ]
110 });
111
112 return;
113 }
114
115 banOptions.days = await parseInt(days);
116 }
117 }
118
119 console.log(time);
120
121 if (!time || !ms(time)) {
122 await msg.reply({
123 embeds: [
124 new MessageEmbed()
125 .setColor('#f14a60')
126 .setDescription(`The time must be a valid time identifier.`)
127 ]
128 });
129
130 return;
131 }
132
133 time = ms(time);
134
135 try {
136 try {
137 const member = await msg.guild?.members.fetch(user.id);
138
139 if (member && !(await hasPermission(client, member, msg, null, "You don't have permission to tempban this user."))) {
140 return;
141 }
142
143 if (member && shouldNotModerate(client, member)) {
144 await msg.reply({
145 embeds: [
146 new MessageEmbed()
147 .setColor('#f14a60')
148 .setDescription(`This user cannot be tempbanned.`)
149 ]
150 });
151
152 return;
153 }
154 }
155 catch (e) {
156 console.log(e);
157 }
158
159 await msg.guild?.bans.create(user, banOptions);
160
161 const punishment = await Punishment.create({
162 type: PunishmentType.TEMPBAN,
163 user_id: user.id,
164 guild_id: msg.guild!.id,
165 mod_id: msg.member!.user.id,
166 mod_tag: (msg.member!.user as User).tag,
167 reason: banOptions.reason ?? undefined,
168 meta: {
169 days: banOptions.days,
170 time
171 }
172 });
173
174 const timeouts = getTimeouts();
175
176 for (const timeout of timeouts.values()) {
177 if (timeout.row.params) {
178 try {
179 const json = JSON.parse(timeout.row.params);
180
181 if (json) {
182 if (json[1] === user.id && timeout.row.filePath.endsWith('tempban-remove')) {
183 await clearTimeoutv2(timeout);
184 }
185 }
186 }
187 catch (e) {
188 console.log(e);
189 }
190 }
191 }
192
193 await setTimeoutv2('tempban-remove', time, msg.guild!.id, 'unban ' + user.id, user.id, msg.guild!.id);
194
195 await client.logger.logTempBan(banOptions, msg.guild!, user, punishment);
196
197 await msg.reply({
198 embeds: [
199 new MessageEmbed({
200 author: {
201 name: user.tag,
202 iconURL: user.displayAvatarURL()
203 },
204 description: `${await fetchEmojiStr('check')} Temporarily banned user ${user.tag}`,
205 fields: [
206 {
207 name: 'Banned by',
208 value: (<User> msg.member?.user).tag
209 },
210 {
211 name: 'Reason',
212 value: banOptions.reason ?? '*No reason provided*'
213 }
214 ]
215 })
216 ]
217 });
218 }
219 catch (e) {
220 await msg.reply({
221 embeds: [
222 new MessageEmbed()
223 .setColor('#f14a60')
224 .setDescription("Failed to ban this user. Maybe missing permisions or I'm not allowed to ban this user?")
225 ]
226 });
227
228 return;
229 }
230 }
231 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26