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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 559 - (hide annotations)
Mon Jul 29 17:30:49 2024 UTC (8 months, 1 week ago) by rakin
File MIME type: application/typescript
File size: 16905 byte(s)
feat(logging): show who banned a user
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 rakin 559 if (auditLog.executor?.id === this.client.user!.id || (r.startsWith("[TEMPBAN]") || r.startsWith("[SOFTBAN]"))) {
160 rakin 428 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 559 .addFields({
176     name: 'Banned by',
177     value: auditLog?.executor ? `${auditLog.executor.tag} (${auditLog.executor.id})` : 'Unknown'
178     })
179 rakin 5 .setFooter({
180 rakin 25 text: "Banned",
181 rakin 5 })
182     .setTimestamp()
183     ]
184     });
185 rakin 25 }, ban);
186     }
187    
188 rakin 336 logSoftBan(banOptions: BanOptions, guild: Guild, user: User, model: IPunishment) {
189 rakin 106 this.channel(async (channel) => {
190     let r = '*No reason provided*';
191    
192     const auditLog = (await guild.fetchAuditLogs({
193     limit: 1,
194     type: 'MEMBER_BAN_ADD',
195     })).entries.first();
196    
197     if (banOptions.reason) {
198     r = banOptions.reason;
199     }
200     else if (auditLog) {
201     console.log(auditLog);
202     const { target, reason } = await auditLog;
203    
204     if (target!.id === user.id && reason) {
205 rakin 428 r = reason.replace(/^\[SOFTBAN\]/, '');
206 rakin 106 }
207     }
208    
209     await channel.send({
210     embeds: [
211     new MessageEmbed()
212     .setColor('#f14a60')
213     .setTitle("A user was softbanned")
214     .setAuthor({
215     name: user.tag,
216     iconURL: user.displayAvatarURL(),
217     })
218     .addField('Reason', r)
219 rakin 336 .addField('Softbanned by', model.mod_tag)
220 rakin 106 .addField('User ID', user.id)
221     .setFooter({
222     text: "Softbanned",
223     })
224     .setTimestamp()
225     ]
226     });
227     }, {
228     guild
229     });
230     }
231    
232 rakin 336 logTempBan(banOptions: BanOptions, guild: Guild, user: User, model: IPunishment) {
233 rakin 106 this.channel(async (channel) => {
234     let r = '*No reason provided*';
235    
236     const auditLog = (await guild.fetchAuditLogs({
237     limit: 1,
238     type: 'MEMBER_BAN_ADD',
239     })).entries.first();
240    
241     if (banOptions.reason) {
242     r = banOptions.reason;
243     }
244     else if (auditLog) {
245     console.log(auditLog);
246     const { target, reason } = await auditLog;
247    
248     if (target!.id === user.id && reason) {
249 rakin 428 r = reason.replace(/^\[TEMPBAN\]/, '');
250 rakin 106 }
251     }
252    
253     await channel.send({
254     embeds: [
255     new MessageEmbed()
256     .setColor('#f14a60')
257     .setTitle("A user was temporarily banned")
258     .setAuthor({
259     name: user.tag,
260     iconURL: user.displayAvatarURL(),
261     })
262     .addField('Reason', r)
263 rakin 336 .addField('Banned by', model.mod_tag)
264 rakin 106 .addField('User ID', user.id)
265 rakin 336 .addField('Duration', ms((model.meta as any).time))
266 rakin 106 .setFooter({
267     text: "Temporarily banned",
268     })
269     .setTimestamp()
270     ]
271     });
272     }, {
273     guild
274     });
275     }
276    
277 rakin 51 logUnbanned(ban: GuildBan) {
278 rakin 25 this.channel(async (channel) => {
279     await channel.send({
280     embeds: [
281     new MessageEmbed()
282     .setColor('#f14a60')
283     .setTitle("A user was unbanned")
284     .setAuthor({
285     name: ban.user.tag,
286     iconURL: ban.user.displayAvatarURL(),
287     })
288     .addField('User ID', ban.user.id)
289     .setFooter({
290     text: "Unbanned",
291     })
292     .setTimestamp()
293     ]
294     });
295     }, ban);
296     }
297    
298 rakin 51 logJoined(member: GuildMember) {
299 rakin 46 this.channelJoinLeft(async (channel) => {
300 rakin 25 await channel.send({
301     embeds: [
302     new MessageEmbed()
303     .setColor('#007bff')
304     .setTitle("New member joined")
305     .setAuthor({
306     name: member.user.tag,
307     iconURL: member.user.displayAvatarURL(),
308     })
309     .setDescription(`<@${member.user.id}> just joined the server!`)
310 rakin 51 .addField('Account Created', `${member.user.createdAt.toLocaleString()} (${timeSince(member.user.createdAt.getTime())})`)
311 rakin 37 .addField('New Account?', (new Date().getTime() - member.user.createdAt.getTime()) <= 3 * 24 * 60 * 60 * 1000 ? ":warning: Yes :warning:" : "No")
312     .addField('Bot?', member.user.bot === true ? 'Yes' : 'No')
313 rakin 25 .addField('User ID', member.user.id)
314     .setFooter({
315     text: "Joined",
316     })
317     .setTimestamp()
318     ]
319     });
320     }, member);
321     }
322    
323 rakin 51 logLeft(member: GuildMember) {
324 rakin 46 this.channelJoinLeft(async (channel) => {
325 rakin 54 const roles = await member.roles.cache.filter(role => role.id !== member.guild.id).reduce((acc, val) => ` ${acc} ${roleMention(val.id)}`, '');
326    
327 rakin 25 await channel.send({
328     embeds: [
329     new MessageEmbed()
330     .setColor('#f14a60')
331     .setTitle("Member left")
332     .setAuthor({
333     name: member.user.tag,
334     iconURL: member.user.displayAvatarURL(),
335     })
336 rakin 54 .setDescription(`**Roles**\n${roles}`)
337 rakin 51 .addField('Joined at', `${member.joinedAt!.toLocaleString()} (${timeSince(member.joinedAt!.getTime())})`)
338 rakin 25 .addField('User ID', member.user.id)
339 rakin 37 .addField('Bot?', member.user.bot === true ? 'Yes' : 'No')
340 rakin 25 .setFooter({
341     text: "Left",
342     })
343     .setTimestamp()
344     ]
345     });
346     }, member);
347     }
348    
349 rakin 51 logBeaned(member: GuildMember, r: string, d: User) {
350 rakin 25 this.channel(async (channel) => {
351     await channel.send({
352     embeds: [
353     new MessageEmbed()
354     .setColor('#007bff')
355     .setTitle("Member beaned")
356     .setAuthor({
357     name: member.user.tag,
358     iconURL: member.user.displayAvatarURL(),
359     })
360     .addField('Reason', r)
361     .addField('Beaned by', d.tag)
362     .addField('User ID', member.user.id)
363     .setFooter({
364     text: "Beaned",
365     })
366     .setTimestamp()
367     ]
368     });
369     }, member);
370     }
371    
372 rakin 338 logMute(member: GuildMember, reason: string, duration: number | null | undefined, d: User, hard: boolean = true) {
373 rakin 25 this.channel(async (channel) => {
374     await channel.send({
375     embeds: [
376     new MessageEmbed()
377     .setColor('#f14a60')
378     .setTitle("Member muted")
379     .setAuthor({
380     name: member.user.tag,
381     iconURL: member.user.displayAvatarURL(),
382     })
383     .addField('Reason', reason)
384     .addField('Muted by', d.tag)
385 rakin 338 .addField('Duration Until', duration ? `${(new Date(Date.now() + duration)).toLocaleString()} (${formatDuration(intervalToDuration({ start: 0, end: duration }))})` : "*No duration set*")
386 rakin 25 .addField('User ID', member.user.id)
387 rakin 124 .addField('Hardmute', hard ? 'Yes' : 'No')
388 rakin 25 .setFooter({
389     text: "Muted",
390     })
391     .setTimestamp()
392     ]
393     });
394     }, member);
395     }
396    
397 rakin 51 logUnmute(member: GuildMember, d: User) {
398 rakin 25 this.channel(async (channel) => {
399     await channel.send({
400     embeds: [
401     new MessageEmbed()
402     .setColor('#007bff')
403     .setTitle("Member unmuted")
404     .setAuthor({
405     name: member.user.tag,
406     iconURL: member.user.displayAvatarURL(),
407     })
408     .addField('Unmuted by', d.tag)
409     .addField('User ID', member.user.id)
410     .setFooter({
411     text: "Unmuted",
412     })
413     .setTimestamp()
414     ]
415     });
416     }, member);
417     }
418    
419 rakin 85 logWarn(msg: Message | CommandInteraction, member: GuildMember | User, d: User, reason: string | undefined, id: number | string) {
420 rakin 51 if ((member as GuildMember).user)
421     member = (member as GuildMember).user;
422 rakin 25
423 rakin 51 this.channel(async (channel) => {
424 rakin 25 await channel.send({
425     embeds: [
426     new MessageEmbed()
427     .setColor('GOLD')
428     .setTitle("Member warned")
429     .setAuthor({
430 rakin 51 name: (member as User).tag,
431 rakin 25 iconURL: member.displayAvatarURL(),
432     })
433 rakin 85 .addField('Reason', reason ?? '*No reason provided*')
434 rakin 25 .addField('Warned by', d.tag)
435     .addField('User ID', member.id)
436 rakin 85 .addField('Case ID', id + '')
437 rakin 25 .setFooter({
438     text: "Warned",
439     })
440     .setTimestamp()
441     ]
442     });
443 rakin 5 }, msg);
444     }
445 rakin 25
446 rakin 51 logWarndel(msg: Message, member: GuildMember, warn: any, d: User) {
447 rakin 25 this.channel(async (channel) => {
448     await channel.send({
449     embeds: [
450     new MessageEmbed()
451     .setColor('GOLD')
452     .setTitle("Warning deleted")
453     .setAuthor({
454     name: member.user.tag,
455     iconURL: member.user.displayAvatarURL(),
456     })
457     .addField('Warned by', d.tag + '')
458     .addField('Warning ID', warn.id + '')
459     .addField('User ID', member.user.id)
460     .setFooter({
461     text: "Warning Deleted",
462     })
463     .setTimestamp()
464     ]
465     });
466     }, msg);
467     }
468 rakin 5 }
469    
470 rakin 51 export default Logger;

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26