/[sudobot]/trunk/src/automod/Logger.ts
ViewVC logotype

Annotation of /trunk/src/automod/Logger.ts

Parent Directory Parent Directory | Revision Log Revision Log


Revision 428 - (hide annotations)
Mon Jul 29 17:30:11 2024 UTC (8 months, 1 week ago) by rakin
File MIME type: application/typescript
File size: 16689 byte(s)
refactor: use new queue handler
1 rakin 393 /**
2     * This file is part of SudoBot.
3     *
4     * Copyright (C) 2021-2022 OSN Inc.
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 rakin 54 import { roleMention } from '@discordjs/builders';
21 rakin 338 import { formatDuration, intervalToDuration } from 'date-fns';
22 rakin 227 import { BanOptions, CommandInteraction, FileOptions, Guild, GuildBan, GuildMember, Message, MessageEmbed, MessageOptions, MessagePayload, TextChannel, User } from 'discord.js';
23 rakin 106 import ms from 'ms';
24 rakin 51 import DiscordClient from '../client/Client';
25 rakin 344 import { IPunishment } from '../models/Punishment';
26     import { timeSince } from '../utils/util';
27 rakin 5
28     class Logger {
29 rakin 51 client: DiscordClient;
30 rakin 428 pause = false;
31     pauseBan = false;
32 rakin 51
33 rakin 428 pauseAll(p = true) {
34     this.pause = p;
35     }
36    
37 rakin 51 constructor(client: DiscordClient) {
38     this.client = client;
39 rakin 5 }
40    
41 rakin 85 channel(callback: (channel: TextChannel) => any, msg: any) {
42 rakin 428 if (this.pause) {
43     return;
44     }
45    
46 rakin 51 let channelID = this.client.config.props[msg.guild!.id].logging_channel;
47 rakin 85 let channel = msg.guild!.channels.cache.find((c: any) => c.id === channelID) as TextChannel;
48 rakin 5
49     if (channel) {
50     return callback(channel);
51     }
52     }
53    
54 rakin 65 channelJoinLeft(callback: (channel: TextChannel) => any, msg: any) {
55 rakin 51 let channelID = this.client.config.props[msg.guild!.id].logging_channel_join_leave;
56 rakin 65 let channel = msg.guild!.channels.cache.find((c: any) => c.id === channelID) as TextChannel;
57 rakin 46
58     if (channel) {
59     return callback(channel);
60     }
61     }
62    
63 rakin 227 async send(guild: Guild, messageOptions: MessageOptions | MessagePayload | string) {
64     let channelID = this.client.config.props[guild!.id].logging_channel;
65     let channel = guild!.channels.cache.find((c: any) => c.id === channelID) as TextChannel;
66    
67     if (channel) {
68     return await channel.send(messageOptions);
69     }
70     }
71    
72 rakin 214 log(guild: Guild, callback: (channel: TextChannel) => any) {
73     this.channel(callback, { guild });
74     }
75    
76 rakin 51 logEdit(oldMsg: Message, newMsg: Message) {
77 rakin 5 this.channel(async (channel) => {
78     await channel.send({
79     embeds: [
80     new MessageEmbed()
81     .setColor('#007bff')
82 rakin 51 .setTitle('Message Edited in #' + (newMsg.channel as TextChannel).name + " (" + newMsg.channel.id + ")")
83 rakin 25 .setDescription('**-+-+Before**\n' + oldMsg.content + '\n\n**-+-+After**\n' + newMsg.content)
84 rakin 5 .addField('ID', newMsg.id)
85     .setAuthor({
86     name: newMsg.author.tag,
87     iconURL: newMsg.author.displayAvatarURL(),
88     })
89     .setFooter({
90     text: "Edited",
91     })
92     .setTimestamp()
93     ]
94     });
95     }, newMsg);
96     }
97    
98 rakin 51 logDelete(msg: Message) {
99 rakin 5 this.channel(async (channel) => {
100 rakin 25 const embed = new MessageEmbed()
101     .setColor('#f14a60')
102 rakin 51 .setTitle('Message Deleted in #' + (msg.channel as TextChannel).name + " (" + msg.channel.id + ")")
103 rakin 25 .setDescription(msg.content)
104     .setAuthor({
105     name: msg.author.tag,
106     iconURL: msg.author.displayAvatarURL(),
107     })
108     .addField('ID', msg.id)
109     .setFooter({
110     text: "Deleted",
111     })
112     .setTimestamp();
113 rakin 58
114     const files: FileOptions[] = [];
115 rakin 25
116     if (msg.attachments.size > 0) {
117     let str = '';
118    
119     msg.attachments.forEach(a => {
120 rakin 58 str += `${a.name}\n`;
121     files.push({
122     name: a.name!,
123     attachment: a.proxyURL
124     });
125 rakin 25 });
126    
127 rakin 58 embed.addField('Attachments (top)', str);
128 rakin 25 }
129    
130 rakin 5 await channel.send({
131     embeds: [
132 rakin 25 embed
133 rakin 58 ],
134     files
135 rakin 25 });
136     }, msg);
137     }
138    
139 rakin 51 logBanned(ban: GuildBan) {
140 rakin 25 this.channel(async (channel) => {
141     let r = '*No reason provided*';
142    
143 rakin 61 const auditLog = (await ban.guild.fetchAuditLogs({
144     limit: 1,
145     type: 'MEMBER_BAN_ADD',
146     })).entries.first();
147    
148 rakin 25 if (ban.reason) {
149     r = ban.reason;
150     }
151 rakin 61 else if (auditLog) {
152     console.log(auditLog);
153     const { target, reason } = await auditLog;
154 rakin 25
155 rakin 61 if (target!.id === ban.user.id && reason) {
156 rakin 428 r = reason.replace(/^\[BAN\]/, '');
157 rakin 61 }
158 rakin 428
159     if (auditLog.executor?.id === this.client.user!.id && (r.startsWith("[TEMPBAN]") || r.startsWith("[SOFTBAN]"))) {
160     return;
161     }
162 rakin 61 }
163    
164 rakin 25 await channel.send({
165     embeds: [
166 rakin 5 new MessageEmbed()
167     .setColor('#f14a60')
168 rakin 25 .setTitle("A user was banned")
169 rakin 5 .setAuthor({
170 rakin 25 name: ban.user.tag,
171     iconURL: ban.user.displayAvatarURL(),
172 rakin 5 })
173 rakin 25 .addField('Reason', r)
174     .addField('User ID', ban.user.id)
175 rakin 5 .setFooter({
176 rakin 25 text: "Banned",
177 rakin 5 })
178     .setTimestamp()
179     ]
180     });
181 rakin 25 }, ban);
182     }
183    
184 rakin 336 logSoftBan(banOptions: BanOptions, guild: Guild, user: User, model: IPunishment) {
185 rakin 106 this.channel(async (channel) => {
186     let r = '*No reason provided*';
187    
188     const auditLog = (await guild.fetchAuditLogs({
189     limit: 1,
190     type: 'MEMBER_BAN_ADD',
191     })).entries.first();
192    
193     if (banOptions.reason) {
194     r = banOptions.reason;
195     }
196     else if (auditLog) {
197     console.log(auditLog);
198     const { target, reason } = await auditLog;
199    
200     if (target!.id === user.id && reason) {
201 rakin 428 r = reason.replace(/^\[SOFTBAN\]/, '');
202 rakin 106 }
203     }
204    
205     await channel.send({
206     embeds: [
207     new MessageEmbed()
208     .setColor('#f14a60')
209     .setTitle("A user was softbanned")
210     .setAuthor({
211     name: user.tag,
212     iconURL: user.displayAvatarURL(),
213     })
214     .addField('Reason', r)
215 rakin 336 .addField('Softbanned by', model.mod_tag)
216 rakin 106 .addField('User ID', user.id)
217     .setFooter({
218     text: "Softbanned",
219     })
220     .setTimestamp()
221     ]
222     });
223     }, {
224     guild
225     });
226     }
227    
228 rakin 336 logTempBan(banOptions: BanOptions, guild: Guild, user: User, model: IPunishment) {
229 rakin 106 this.channel(async (channel) => {
230     let r = '*No reason provided*';
231    
232     const auditLog = (await guild.fetchAuditLogs({
233     limit: 1,
234     type: 'MEMBER_BAN_ADD',
235     })).entries.first();
236    
237     if (banOptions.reason) {
238     r = banOptions.reason;
239     }
240     else if (auditLog) {
241     console.log(auditLog);
242     const { target, reason } = await auditLog;
243    
244     if (target!.id === user.id && reason) {
245 rakin 428 r = reason.replace(/^\[TEMPBAN\]/, '');
246 rakin 106 }
247     }
248    
249     await channel.send({
250     embeds: [
251     new MessageEmbed()
252     .setColor('#f14a60')
253     .setTitle("A user was temporarily banned")
254     .setAuthor({
255     name: user.tag,
256     iconURL: user.displayAvatarURL(),
257     })
258     .addField('Reason', r)
259 rakin 336 .addField('Banned by', model.mod_tag)
260 rakin 106 .addField('User ID', user.id)
261 rakin 336 .addField('Duration', ms((model.meta as any).time))
262 rakin 106 .setFooter({
263     text: "Temporarily banned",
264     })
265     .setTimestamp()
266     ]
267     });
268     }, {
269     guild
270     });
271     }
272    
273 rakin 51 logUnbanned(ban: GuildBan) {
274 rakin 25 this.channel(async (channel) => {
275     await channel.send({
276     embeds: [
277     new MessageEmbed()
278     .setColor('#f14a60')
279     .setTitle("A user was unbanned")
280     .setAuthor({
281     name: ban.user.tag,
282     iconURL: ban.user.displayAvatarURL(),
283     })
284     .addField('User ID', ban.user.id)
285     .setFooter({
286     text: "Unbanned",
287     })
288     .setTimestamp()
289     ]
290     });
291     }, ban);
292     }
293    
294 rakin 51 logJoined(member: GuildMember) {
295 rakin 46 this.channelJoinLeft(async (channel) => {
296 rakin 25 await channel.send({
297     embeds: [
298     new MessageEmbed()
299     .setColor('#007bff')
300     .setTitle("New member joined")
301     .setAuthor({
302     name: member.user.tag,
303     iconURL: member.user.displayAvatarURL(),
304     })
305     .setDescription(`<@${member.user.id}> just joined the server!`)
306 rakin 51 .addField('Account Created', `${member.user.createdAt.toLocaleString()} (${timeSince(member.user.createdAt.getTime())})`)
307 rakin 37 .addField('New Account?', (new Date().getTime() - member.user.createdAt.getTime()) <= 3 * 24 * 60 * 60 * 1000 ? ":warning: Yes :warning:" : "No")
308     .addField('Bot?', member.user.bot === true ? 'Yes' : 'No')
309 rakin 25 .addField('User ID', member.user.id)
310     .setFooter({
311     text: "Joined",
312     })
313     .setTimestamp()
314     ]
315     });
316     }, member);
317     }
318    
319 rakin 51 logLeft(member: GuildMember) {
320 rakin 46 this.channelJoinLeft(async (channel) => {
321 rakin 54 const roles = await member.roles.cache.filter(role => role.id !== member.guild.id).reduce((acc, val) => ` ${acc} ${roleMention(val.id)}`, '');
322    
323 rakin 25 await channel.send({
324     embeds: [
325     new MessageEmbed()
326     .setColor('#f14a60')
327     .setTitle("Member left")
328     .setAuthor({
329     name: member.user.tag,
330     iconURL: member.user.displayAvatarURL(),
331     })
332 rakin 54 .setDescription(`**Roles**\n${roles}`)
333 rakin 51 .addField('Joined at', `${member.joinedAt!.toLocaleString()} (${timeSince(member.joinedAt!.getTime())})`)
334 rakin 25 .addField('User ID', member.user.id)
335 rakin 37 .addField('Bot?', member.user.bot === true ? 'Yes' : 'No')
336 rakin 25 .setFooter({
337     text: "Left",
338     })
339     .setTimestamp()
340     ]
341     });
342     }, member);
343     }
344    
345 rakin 51 logBeaned(member: GuildMember, r: string, d: User) {
346 rakin 25 this.channel(async (channel) => {
347     await channel.send({
348     embeds: [
349     new MessageEmbed()
350     .setColor('#007bff')
351     .setTitle("Member beaned")
352     .setAuthor({
353     name: member.user.tag,
354     iconURL: member.user.displayAvatarURL(),
355     })
356     .addField('Reason', r)
357     .addField('Beaned by', d.tag)
358     .addField('User ID', member.user.id)
359     .setFooter({
360     text: "Beaned",
361     })
362     .setTimestamp()
363     ]
364     });
365     }, member);
366     }
367    
368 rakin 338 logMute(member: GuildMember, reason: string, duration: number | null | undefined, d: User, hard: boolean = true) {
369 rakin 25 this.channel(async (channel) => {
370     await channel.send({
371     embeds: [
372     new MessageEmbed()
373     .setColor('#f14a60')
374     .setTitle("Member muted")
375     .setAuthor({
376     name: member.user.tag,
377     iconURL: member.user.displayAvatarURL(),
378     })
379     .addField('Reason', reason)
380     .addField('Muted by', d.tag)
381 rakin 338 .addField('Duration Until', duration ? `${(new Date(Date.now() + duration)).toLocaleString()} (${formatDuration(intervalToDuration({ start: 0, end: duration }))})` : "*No duration set*")
382 rakin 25 .addField('User ID', member.user.id)
383 rakin 124 .addField('Hardmute', hard ? 'Yes' : 'No')
384 rakin 25 .setFooter({
385     text: "Muted",
386     })
387     .setTimestamp()
388     ]
389     });
390     }, member);
391     }
392    
393 rakin 51 logUnmute(member: GuildMember, d: User) {
394 rakin 25 this.channel(async (channel) => {
395     await channel.send({
396     embeds: [
397     new MessageEmbed()
398     .setColor('#007bff')
399     .setTitle("Member unmuted")
400     .setAuthor({
401     name: member.user.tag,
402     iconURL: member.user.displayAvatarURL(),
403     })
404     .addField('Unmuted by', d.tag)
405     .addField('User ID', member.user.id)
406     .setFooter({
407     text: "Unmuted",
408     })
409     .setTimestamp()
410     ]
411     });
412     }, member);
413     }
414    
415 rakin 85 logWarn(msg: Message | CommandInteraction, member: GuildMember | User, d: User, reason: string | undefined, id: number | string) {
416 rakin 51 if ((member as GuildMember).user)
417     member = (member as GuildMember).user;
418 rakin 25
419 rakin 51 this.channel(async (channel) => {
420 rakin 25 await channel.send({
421     embeds: [
422     new MessageEmbed()
423     .setColor('GOLD')
424     .setTitle("Member warned")
425     .setAuthor({
426 rakin 51 name: (member as User).tag,
427 rakin 25 iconURL: member.displayAvatarURL(),
428     })
429 rakin 85 .addField('Reason', reason ?? '*No reason provided*')
430 rakin 25 .addField('Warned by', d.tag)
431     .addField('User ID', member.id)
432 rakin 85 .addField('Case ID', id + '')
433 rakin 25 .setFooter({
434     text: "Warned",
435     })
436     .setTimestamp()
437     ]
438     });
439 rakin 5 }, msg);
440     }
441 rakin 25
442 rakin 51 logWarndel(msg: Message, member: GuildMember, warn: any, d: User) {
443 rakin 25 this.channel(async (channel) => {
444     await channel.send({
445     embeds: [
446     new MessageEmbed()
447     .setColor('GOLD')
448     .setTitle("Warning deleted")
449     .setAuthor({
450     name: member.user.tag,
451     iconURL: member.user.displayAvatarURL(),
452     })
453     .addField('Warned by', d.tag + '')
454     .addField('Warning ID', warn.id + '')
455     .addField('User ID', member.user.id)
456     .setFooter({
457     text: "Warning Deleted",
458     })
459     .setTimestamp()
460     ]
461     });
462     }, msg);
463     }
464 rakin 5 }
465    
466 rakin 51 export default Logger;

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26