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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 428 - (show 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 /**
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 import { roleMention } from '@discordjs/builders';
21 import { formatDuration, intervalToDuration } from 'date-fns';
22 import { BanOptions, CommandInteraction, FileOptions, Guild, GuildBan, GuildMember, Message, MessageEmbed, MessageOptions, MessagePayload, TextChannel, User } from 'discord.js';
23 import ms from 'ms';
24 import DiscordClient from '../client/Client';
25 import { IPunishment } from '../models/Punishment';
26 import { timeSince } from '../utils/util';
27
28 class Logger {
29 client: DiscordClient;
30 pause = false;
31 pauseBan = false;
32
33 pauseAll(p = true) {
34 this.pause = p;
35 }
36
37 constructor(client: DiscordClient) {
38 this.client = client;
39 }
40
41 channel(callback: (channel: TextChannel) => any, msg: any) {
42 if (this.pause) {
43 return;
44 }
45
46 let channelID = this.client.config.props[msg.guild!.id].logging_channel;
47 let channel = msg.guild!.channels.cache.find((c: any) => c.id === channelID) as TextChannel;
48
49 if (channel) {
50 return callback(channel);
51 }
52 }
53
54 channelJoinLeft(callback: (channel: TextChannel) => any, msg: any) {
55 let channelID = this.client.config.props[msg.guild!.id].logging_channel_join_leave;
56 let channel = msg.guild!.channels.cache.find((c: any) => c.id === channelID) as TextChannel;
57
58 if (channel) {
59 return callback(channel);
60 }
61 }
62
63 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 log(guild: Guild, callback: (channel: TextChannel) => any) {
73 this.channel(callback, { guild });
74 }
75
76 logEdit(oldMsg: Message, newMsg: Message) {
77 this.channel(async (channel) => {
78 await channel.send({
79 embeds: [
80 new MessageEmbed()
81 .setColor('#007bff')
82 .setTitle('Message Edited in #' + (newMsg.channel as TextChannel).name + " (" + newMsg.channel.id + ")")
83 .setDescription('**-+-+Before**\n' + oldMsg.content + '\n\n**-+-+After**\n' + newMsg.content)
84 .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 logDelete(msg: Message) {
99 this.channel(async (channel) => {
100 const embed = new MessageEmbed()
101 .setColor('#f14a60')
102 .setTitle('Message Deleted in #' + (msg.channel as TextChannel).name + " (" + msg.channel.id + ")")
103 .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
114 const files: FileOptions[] = [];
115
116 if (msg.attachments.size > 0) {
117 let str = '';
118
119 msg.attachments.forEach(a => {
120 str += `${a.name}\n`;
121 files.push({
122 name: a.name!,
123 attachment: a.proxyURL
124 });
125 });
126
127 embed.addField('Attachments (top)', str);
128 }
129
130 await channel.send({
131 embeds: [
132 embed
133 ],
134 files
135 });
136 }, msg);
137 }
138
139 logBanned(ban: GuildBan) {
140 this.channel(async (channel) => {
141 let r = '*No reason provided*';
142
143 const auditLog = (await ban.guild.fetchAuditLogs({
144 limit: 1,
145 type: 'MEMBER_BAN_ADD',
146 })).entries.first();
147
148 if (ban.reason) {
149 r = ban.reason;
150 }
151 else if (auditLog) {
152 console.log(auditLog);
153 const { target, reason } = await auditLog;
154
155 if (target!.id === ban.user.id && reason) {
156 r = reason.replace(/^\[BAN\]/, '');
157 }
158
159 if (auditLog.executor?.id === this.client.user!.id && (r.startsWith("[TEMPBAN]") || r.startsWith("[SOFTBAN]"))) {
160 return;
161 }
162 }
163
164 await channel.send({
165 embeds: [
166 new MessageEmbed()
167 .setColor('#f14a60')
168 .setTitle("A user was banned")
169 .setAuthor({
170 name: ban.user.tag,
171 iconURL: ban.user.displayAvatarURL(),
172 })
173 .addField('Reason', r)
174 .addField('User ID', ban.user.id)
175 .setFooter({
176 text: "Banned",
177 })
178 .setTimestamp()
179 ]
180 });
181 }, ban);
182 }
183
184 logSoftBan(banOptions: BanOptions, guild: Guild, user: User, model: IPunishment) {
185 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 r = reason.replace(/^\[SOFTBAN\]/, '');
202 }
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 .addField('Softbanned by', model.mod_tag)
216 .addField('User ID', user.id)
217 .setFooter({
218 text: "Softbanned",
219 })
220 .setTimestamp()
221 ]
222 });
223 }, {
224 guild
225 });
226 }
227
228 logTempBan(banOptions: BanOptions, guild: Guild, user: User, model: IPunishment) {
229 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 r = reason.replace(/^\[TEMPBAN\]/, '');
246 }
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 .addField('Banned by', model.mod_tag)
260 .addField('User ID', user.id)
261 .addField('Duration', ms((model.meta as any).time))
262 .setFooter({
263 text: "Temporarily banned",
264 })
265 .setTimestamp()
266 ]
267 });
268 }, {
269 guild
270 });
271 }
272
273 logUnbanned(ban: GuildBan) {
274 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 logJoined(member: GuildMember) {
295 this.channelJoinLeft(async (channel) => {
296 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 .addField('Account Created', `${member.user.createdAt.toLocaleString()} (${timeSince(member.user.createdAt.getTime())})`)
307 .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 .addField('User ID', member.user.id)
310 .setFooter({
311 text: "Joined",
312 })
313 .setTimestamp()
314 ]
315 });
316 }, member);
317 }
318
319 logLeft(member: GuildMember) {
320 this.channelJoinLeft(async (channel) => {
321 const roles = await member.roles.cache.filter(role => role.id !== member.guild.id).reduce((acc, val) => ` ${acc} ${roleMention(val.id)}`, '');
322
323 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 .setDescription(`**Roles**\n${roles}`)
333 .addField('Joined at', `${member.joinedAt!.toLocaleString()} (${timeSince(member.joinedAt!.getTime())})`)
334 .addField('User ID', member.user.id)
335 .addField('Bot?', member.user.bot === true ? 'Yes' : 'No')
336 .setFooter({
337 text: "Left",
338 })
339 .setTimestamp()
340 ]
341 });
342 }, member);
343 }
344
345 logBeaned(member: GuildMember, r: string, d: User) {
346 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 logMute(member: GuildMember, reason: string, duration: number | null | undefined, d: User, hard: boolean = true) {
369 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 .addField('Duration Until', duration ? `${(new Date(Date.now() + duration)).toLocaleString()} (${formatDuration(intervalToDuration({ start: 0, end: duration }))})` : "*No duration set*")
382 .addField('User ID', member.user.id)
383 .addField('Hardmute', hard ? 'Yes' : 'No')
384 .setFooter({
385 text: "Muted",
386 })
387 .setTimestamp()
388 ]
389 });
390 }, member);
391 }
392
393 logUnmute(member: GuildMember, d: User) {
394 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 logWarn(msg: Message | CommandInteraction, member: GuildMember | User, d: User, reason: string | undefined, id: number | string) {
416 if ((member as GuildMember).user)
417 member = (member as GuildMember).user;
418
419 this.channel(async (channel) => {
420 await channel.send({
421 embeds: [
422 new MessageEmbed()
423 .setColor('GOLD')
424 .setTitle("Member warned")
425 .setAuthor({
426 name: (member as User).tag,
427 iconURL: member.displayAvatarURL(),
428 })
429 .addField('Reason', reason ?? '*No reason provided*')
430 .addField('Warned by', d.tag)
431 .addField('User ID', member.id)
432 .addField('Case ID', id + '')
433 .setFooter({
434 text: "Warned",
435 })
436 .setTimestamp()
437 ]
438 });
439 }, msg);
440 }
441
442 logWarndel(msg: Message, member: GuildMember, warn: any, d: User) {
443 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 }
465
466 export default Logger;

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26