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

Contents of /trunk/src/commands/moderation/ClearCommand.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: 8085 byte(s)
feat: add proper permission checking and error messages
1 import { BanOptions, CommandInteraction, Emoji, GuildChannel, GuildMember, Interaction, Message, TextChannel, 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 getMember from '../../utils/getMember';
9 import History from '../../automod/History';
10 import { fetchEmoji } from '../../utils/Emoji';
11 import { hasPermission, shouldNotModerate } from '../../utils/util';
12
13 export default class ClearCommand extends BaseCommand {
14 supportsInteractions: boolean = true;
15
16 constructor() {
17 super('clear', 'moderation', []);
18 }
19
20 async run(client: DiscordClient, msg: Message | CommandInteraction, options: CommandOptions | InteractionOptions) {
21 if (!options.isInteraction && options.args[0] === undefined) {
22 await msg.reply({
23 embeds: [
24 new MessageEmbed()
25 .setColor('#f14a60')
26 .setDescription('This command requires at least one argument.')
27 ]
28 });
29
30 return;
31 }
32
33 let user: User | undefined | null;
34 let msgCount = 0, channel: GuildChannel = msg.channel! as GuildChannel;
35
36 if (options.isInteraction) {
37 if (options.options.getUser('user'))
38 user = <User> options.options.getUser('user');
39
40 console.log(user?.tag);
41
42 if (options.options.getChannel('channel')) {
43 channel = <GuildChannel> options.options.getChannel('channel');
44
45 if (channel.type !== 'GUILD_TEXT' && channel.type !== 'GUILD_NEWS' && channel.type !== 'GUILD_PUBLIC_THREAD' && channel.type !== 'GUILD_PRIVATE_THREAD') {
46 await msg.reply({
47 content: 'Invalid channel given.'
48 });
49
50 return;
51 }
52 }
53
54 if (options.options.getInteger('count')) {
55 msgCount = <number> options.options.getInteger('count');
56 }
57 }
58 else {
59 try {
60 user = await getUser(client, msg as Message, options);
61
62 if (!user) {
63 throw new Error();
64 }
65 }
66 catch (e) {
67 console.log(e);
68
69 await msg.reply({
70 embeds: [
71 new MessageEmbed()
72 .setColor('#f14a60')
73 .setDescription('Invalid user given.')
74 ]
75 });
76
77 return;
78 }
79 }
80
81 if (msgCount === 0 && !user) {
82 await msg.reply({
83 embeds: [
84 new MessageEmbed()
85 .setColor('#f14a60')
86 .setDescription('You have to specify either the message count or the user.')
87 ]
88 });
89
90 return;
91 }
92
93 if (user) {
94 try {
95 const member = await msg.guild?.members.fetch(user.id);
96
97 if (member && !(await hasPermissions(client, member, msg, null, "You don't have permission to clear messages from this user.")))
98 return;
99
100 if (member && shouldNotModerate(client, member)) {
101 await msg.reply({
102 embeds: [
103 { description: "Cannot clear messages from this user: Operation not permitted" }
104 ]
105 });
106
107 return;
108 }
109 }
110 catch (e) {
111 console.log(e);
112 }
113 }
114
115 let count = 0;
116 (global as any).deletingMessages = true;
117
118 let message = await msg.reply({
119 embeds: [
120 new MessageEmbed()
121 .setColor('GOLD')
122 .setDescription((await fetchEmoji('loading'))?.toString() + ' Deleting messages...')
123 ]
124 });
125
126 if (msg instanceof CommandInteraction)
127 message = <Message> await msg.fetchReply();
128
129 if (msgCount === 0 && user) {
130 console.log(user?.tag);
131
132 let fetched;
133
134 do {
135 fetched = await (channel as TextChannel).messages.fetch({ limit: 100 });
136 fetched = await fetched.filter(m => m.author.id === user!.id && m.id !== message!.id && (Date.now() - m.createdTimestamp) <= (2 * 7 * 24 * 60 * 60 * 1000));
137 await (channel as TextChannel).bulkDelete(fetched);
138 count += fetched.size;
139
140 /*for await (const [id, m] of fetched.entries()) {
141 try {
142 await m.delete();
143 count++;
144 }
145 catch (e) {
146 console.log('Error deleting message', e);
147 }
148 }
149 */
150
151 await new Promise(r => setTimeout(r, 900));
152 }
153 while (fetched.size >= 2);
154 }
155 else {
156 let fetched = 0;
157 let safeLimit = 0, safeLimit2 = 0;
158
159 do {
160 if (count >= msgCount || safeLimit >= 50) {
161 break;
162 }
163
164 try {
165 const data = await (channel as TextChannel).messages.fetch({ limit: 100 });
166
167 fetched = 0;
168
169 for await (const [id, m] of data.entries()) {
170 try {
171 if (count >= msgCount || safeLimit2 > 200) {
172 break;
173 }
174
175 if (user && m.author?.id !== user?.id) {
176 continue;
177 }
178
179 if (message!.id === m.id || (Date.now() - m.createdTimestamp) > (2 * 7 * 24 * 60 * 60 * 1000))
180 continue;
181
182 if (m.deletable) {
183 console.log('here', user?.tag);
184
185 await m.delete();
186
187 fetched++;
188 count++;
189 safeLimit2++;
190 }
191
192 if (count % 10 === 0) {
193 await new Promise(r => setTimeout(r, 1100));
194 }
195 }
196 catch(e) {
197 console.log(e);
198 safeLimit2 += 100;
199 }
200 }
201 }
202 catch(e) {
203 console.log(e);
204
205 break;
206 }
207
208 safeLimit++;
209 }
210 while (fetched >= 2);
211 }
212
213 const messageOptions = {
214 embeds: [
215 new MessageEmbed()
216 .setColor('GREEN')
217 .setDescription((await fetchEmoji('check') as Emoji).toString() + " Deleted " + count + " message(s)" + (user ? " from user " + user.tag : ''))
218 ]
219 };
220
221 if (msg instanceof CommandInteraction) {
222 await msg.editReply(messageOptions);
223 }
224 else {
225 await message!.edit(messageOptions);
226 }
227
228 setTimeout(async () => {
229 try {
230 if (msg instanceof Message)
231 await msg.delete();
232 }
233 catch (e) {
234 console.log(e);
235 }
236
237 try {
238 await message!.delete();
239 }
240 catch (e) {
241 console.log(e);
242 }
243 }, 5500);
244
245 (global as any).deletingMessages = false;
246 }
247 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26