/[sudobot]/branches/4.x/src/automod/Logger.ts
ViewVC logotype

Annotation of /branches/4.x/src/automod/Logger.ts

Parent Directory Parent Directory | Revision Log Revision Log


Revision 577 - (hide annotations)
Mon Jul 29 18:52:37 2024 UTC (8 months ago) by rakinar2
File MIME type: application/typescript
File size: 40859 byte(s)
chore: add old version archive branches (2.x to 9.x-dev)
1 rakinar2 577 /**
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 { formatDistanceStrict, formatDistanceToNowStrict, formatDuration, intervalToDuration } from "date-fns";
22     import {
23     Message,
24     MessageEmbedOptions,
25     MessageEmbed as MessageEmbedDiscord,
26     TextChannel,
27     MessageActionRow,
28     MessageButton,
29     FileOptions,
30     GuildBan,
31     BanOptions,
32     Guild,
33     User,
34     GuildMember,
35     Util,
36     GuildChannel,
37     Role,
38     Collection,
39     } from "discord.js";
40     import ms from "ms";
41     import BaseMessageEmbed from "../client/MessageEmbed";
42     import { IGuildInfo } from "../models/GuildInfo";
43     import Punishment, { IPunishment } from "../models/Punishment";
44     import PunishmentType from "../types/PunishmentType";
45     import Service from "../utils/structures/Service";
46     import { timeSince } from "../utils/util";
47    
48     class MessageEmbed extends BaseMessageEmbed {
49     constructor(options?: MessageEmbedDiscord | MessageEmbedOptions) {
50     super(options);
51     this.setTimestamp();
52     }
53     }
54    
55     export default class Logger extends Service {
56     loggingChannel(id: string) {
57     return this.client.guilds.cache.get(id)?.channels.cache.get(this.client.config.props[id].logging_channel) as TextChannel | null;
58     }
59    
60     loggingChannelBoosts(id: string) {
61     return this.client.guilds.cache
62     .get(id)
63     ?.channels.cache.get(
64     this.client.config.props[id].logging_channel_boosts ?? this.client.config.props[id].logging_channel
65     ) as TextChannel | null;
66     }
67    
68     loggingChannelJoinLeave(id: string) {
69     return this.client.guilds.cache.get(id)?.channels.cache.get(this.client.config.props[id].logging_channel_join_leave) as TextChannel | null;
70     }
71    
72     async onRoleCreate(role: Role) {
73     this.loggingChannel(role.guild.id)?.send({
74     embeds: [
75     new MessageEmbed({
76     title: "Role created",
77     fields: [
78     {
79     name: "Role",
80     value: `Name: ${role.name}\nID: ${role.id}\nMention: ${role.toString()}`
81     }
82     ],
83     footer: {
84     text: "Created"
85     },
86     color: 0x007bff
87     })
88     .setTimestamp()
89     ],
90     allowedMentions: {
91     roles: []
92     }
93     });
94     }
95    
96    
97     async onRoleDelete(role: Role) {
98     this.loggingChannel(role.guild.id)?.send({
99     embeds: [
100     new MessageEmbed({
101     title: "Role deleted",
102     fields: [
103     {
104     name: "Role",
105     value: `Name: ${role.name}\nID: ${role.id}\nMention: ${role.toString()}`
106     }
107     ],
108     footer: {
109     text: "Deleted"
110     },
111     color: 0xf14a60
112     })
113     .setTimestamp()
114     ],
115     allowedMentions: {
116     roles: []
117     }
118     });
119     }
120    
121    
122     async onRoleUpdate(oldRole: Role, newRole: Role) {
123     this.loggingChannel(newRole.guild.id)?.send({
124     embeds: [
125     new MessageEmbed({
126     title: "Role updated",
127     fields: [
128     ...(newRole.name !== oldRole.name ? [
129     {
130     name: "Name",
131     value: `New Name: ${newRole.name}\nOld Name: ${oldRole.name}`
132     }
133     ] : [
134     {
135     name: "Name",
136     value: `${newRole.name}`
137     }
138     ]),
139     ...(newRole.color !== oldRole.color ? [
140     {
141     name: "Color",
142     value: `New Color: ${newRole.hexColor}\nOld Color: ${oldRole.hexColor}`
143     }
144     ] : []),
145     ...(!newRole.permissions.equals(oldRole.permissions) ? [
146     {
147     name: "New Permissions",
148     value: `\`${newRole.permissions.toArray().join('`, `')}\``
149     }
150     ] : []),
151     ...(oldRole.icon !== newRole.icon ? [
152     {
153     name: "Icon",
154     value: `New Icon: ${newRole.iconURL()}\nOld Icon: ${oldRole.iconURL()}`
155     }
156     ] : []),
157     {
158     name: "ID",
159     value: `${newRole.id}`
160     }
161     ],
162     footer: {
163     text: "Updated"
164     },
165     })
166     .setTimestamp()
167     .setColor("GREEN")
168     ],
169     allowedMentions: {
170     roles: []
171     }
172     });
173     }
174    
175     async onChannelCreate(channel: GuildChannel) {
176     this.loggingChannel(channel.guild.id)?.send({
177     embeds: [
178     new MessageEmbed({
179     title: `Channel${channel.type === "GUILD_CATEGORY" ? " Category" : ""} Created`,
180     color: 0x07bff,
181     fields: [
182     {
183     name: "Channel",
184     value: `#${channel.name} (${channel.toString()}, ${channel.id})`
185     },
186     {
187     name: "Type",
188     value: channel.type.replace("GUILD_", '')
189     }
190     ],
191     footer: {
192     text: 'Created'
193     }
194     }).setTimestamp()
195     ]
196     }).catch(console.error);
197     }
198    
199     async onChannelDelete(channel: GuildChannel) {
200     this.loggingChannel(channel.guild.id)?.send({
201     embeds: [
202     new MessageEmbed({
203     title: `Channel${channel.type === "GUILD_CATEGORY" ? " Category" : ""} Deleted`,
204     color: 0xf14a60,
205     fields: [
206     {
207     name: "Channel",
208     value: `#${channel.name} (${channel.id})`
209     },
210     {
211     name: "Type",
212     value: channel.type.replace("GUILD_", '')
213     }
214     ],
215     footer: {
216     text: 'Deleted'
217     }
218     }).setTimestamp()
219     ]
220     }).catch(console.error);
221     }
222    
223     async onMemberRoleAdd(member: GuildMember, roles: Role[]) {
224     this.loggingChannel(member.guild.id)?.send({
225     embeds: [
226     new MessageEmbed({
227     title: `Roles added to member`,
228     color: 0xf14a60,
229     fields: [
230     {
231     name: "Member",
232     value: `${member.user.toString()} (${member.user.id})`
233     },
234     {
235     name: "Roles",
236     value: `${roles.map(r => r.toString()).join(', ')}`
237     }
238     ],
239     footer: {
240     text: 'Roles Added'
241     }
242     }).setTimestamp()
243     ],
244     allowedMentions: {
245     roles: [],
246     users: []
247     }
248     }).catch(console.error);
249     }
250    
251     async onMemberRoleUpdate(newMember: GuildMember, oldMember: GuildMember) {
252     this.loggingChannel(newMember.guild.id)?.send({
253     embeds: [
254     new MessageEmbed({
255     author: {
256     name: newMember.user.username,
257     icon_url: newMember.displayAvatarURL()
258     },
259     title: `Roles modified`,
260     color: 0xf14a60,
261     fields: [
262     {
263     name: "Member",
264     value: `${newMember.user.toString()} (${newMember.user.id})`
265     },
266     {
267     name: "Old Roles",
268     value: `${oldMember.roles.cache.map(r => r.toString()).join(', ')}`
269     },
270     {
271     name: "New Roles",
272     value: `${newMember.roles.cache.map(r => r.toString()).join(', ')}`
273     }
274     ],
275     footer: {
276     text: 'Roles Updated'
277     }
278     }).setTimestamp()
279     ],
280     allowedMentions: {
281     roles: [],
282     users: []
283     }
284     }).catch(console.error);
285     }
286    
287     async onMemberRoleRemove(member: GuildMember, roles: Role[]) {
288     this.loggingChannel(member.guild.id)?.send({
289     embeds: [
290     new MessageEmbed({
291     title: `Roles removed from member`,
292     color: 0xf14a60,
293     fields: [
294     {
295     name: "Member",
296     value: `${member.user.toString()} (${member.user.id})`
297     },
298     {
299     name: "Roles",
300     value: `${roles.map(r => r.toString()).join(', ')}`
301     }
302     ],
303     footer: {
304     text: 'Roles Removed'
305     }
306     }).setTimestamp()
307     ],
308     allowedMentions: {
309     roles: [],
310     users: []
311     }
312     }).catch(console.error);
313     }
314    
315    
316     async onBulkDelete(messages: Collection<string, Message>) {
317     this.loggingChannel(messages.at(0)?.guildId!)?.send({
318     embeds: [
319     new MessageEmbed({
320     title: `Messages deleted in bulk`,
321     color: 0xf14a60,
322     fields: [
323     {
324     name: "Channel",
325     value: `${messages.at(0)?.channel.toString()} (${messages.at(0)?.channelId})`
326     },
327     {
328     name: "Count",
329     value: `${messages.size}`
330     }
331     ],
332     footer: {
333     text: 'Deleted'
334     }
335     }).setTimestamp()
336     ]
337     }).catch(console.error);
338     }
339    
340     async onAIModMessageDelete(message: Message, config: any, response: any, meta: any) {
341     const toxicScore = response.data.attributeScores.TOXICITY.summaryScore.value * 100;
342     const severeToxicScore = response.data.attributeScores.SEVERE_TOXICITY.summaryScore.value * 100;
343     const threatScore = response.data.attributeScores.THREAT.summaryScore.value * 100;
344    
345     let conf = meta.toxic ? `Toxicity score is ${toxicScore}%, which is higher than or equal to the given maximum value in the configuration (${config.toxicity * 100}%)` : (
346     meta.severeToxic ? `Severe Toxicity score is ${severeToxicScore}%, which is higher than or equal to the given maximum value in the configuration (${config.severe_toxicity * 100}%)` : (
347     meta.threat ? `Threat score is ${threatScore}%, which is higher than or equal to the given maximum value in the configuration (${config.threat * 100}%)` : `Unknown`
348     )
349     );
350    
351     await this.loggingChannel(message.guildId!)?.send({
352     embeds: [
353     new MessageEmbed({
354     title: "AI Moderator has deleted this message",
355     author: {
356     name: message.author.tag,
357     iconURL: message.author.displayAvatarURL(),
358     },
359     color: 0xf14a60,
360     description: message.content,
361     fields: [
362     {
363     name: "User ID",
364     value: message.author.id,
365     },
366     {
367     name: "Message Analysis Results",
368     value: `Toxicity: ${toxicScore}%\nSevere Toxicity: ${severeToxicScore}%\nThreat: ${threatScore}%`,
369     },
370     {
371     name: "Reason",
372     value: `Deleted the message because of the following configuration:\n\`\`\`${conf}\`\`\``
373     }
374     ],
375     footer: {
376     text: 'Deleted'
377     }
378     })
379     .setTimestamp(),
380     ],
381     });
382     }
383    
384     async onServerBoost(member: GuildMember, level: number) {
385     const distance = formatDistanceToNowStrict(member.premiumSince!);
386    
387     await this.loggingChannelBoosts(member.guild.id)?.send({
388     embeds: [
389     new MessageEmbed({
390     title: "Server Boosted",
391     author: {
392     name: member.user.tag,
393     iconURL: member.user.displayAvatarURL(),
394     },
395     description: `${member.user.toString()} has boosted the server!${level > 0 ? ` The server has reached level **${level}**!` : ""}`,
396     fields: [
397     {
398     name: "Boosting Since",
399     value: `${member.premiumSince!.toUTCString()} (${distance.startsWith("0 second") ? "just now" : distance})`,
400     },
401     ],
402     footer: {
403     text: "Boosted",
404     },
405     }).setTimestamp(),
406     ],
407     });
408     }
409    
410     async onServerUnboost(oldMember: GuildMember, newMember: GuildMember) {
411     await this.loggingChannelBoosts(oldMember.guild.id)?.send({
412     embeds: [
413     new MessageEmbed({
414     title: "Server Unboosted",
415     author: {
416     name: newMember.user.tag,
417     iconURL: newMember.user.displayAvatarURL(),
418     },
419     description: `${newMember.user.toString()} has unboosted the server.`,
420     fields: [
421     {
422     name: "Boosting Since",
423     value: `${oldMember.premiumSince!.toUTCString()} (${formatDistanceToNowStrict(oldMember.premiumSince!)})`,
424     },
425     ],
426     footer: {
427     text: "Unboosted",
428     },
429     })
430     .setColor("PURPLE")
431     .setTimestamp(),
432     ],
433     });
434     }
435    
436     async onNicknameChange(oldMember: GuildMember, newMember: GuildMember) {
437     await this.loggingChannel(oldMember.guild.id)?.send({
438     embeds: [
439     new MessageEmbed({
440     title: "Nickname Updated",
441     author: {
442     name: oldMember.user.tag,
443     iconURL: oldMember.user.displayAvatarURL(),
444     },
445     color: 0xf14a60,
446     fields: [
447     {
448     name: "Old Nickname",
449     value: oldMember.nickname ? Util.escapeMarkdown(oldMember.nickname) : "*No nickname was set*",
450     },
451     {
452     name: "New Nickname",
453     value: newMember.nickname ? Util.escapeMarkdown(newMember.nickname) : "*Nickname was removed*",
454     },
455     {
456     name: "User ID",
457     value: newMember.user.id,
458     },
459     ],
460     footer: {
461     text: "Updated",
462     },
463     }).setTimestamp(),
464     ],
465     });
466     }
467    
468     async onMessageUpdate(oldMessage: Message, newMessage: Message) {
469     const row = new MessageActionRow().addComponents(new MessageButton().setLabel("Go to context").setStyle("LINK").setURL(newMessage.url));
470    
471     if (newMessage.type === "REPLY") {
472     row.addComponents(
473     new MessageButton()
474     .setLabel("Go to referenced message")
475     .setStyle("LINK")
476     .setURL(`https://discord.com/channels/${newMessage.guildId!}/${newMessage.channelId!}/${newMessage.reference!.messageId}`)
477     );
478     }
479    
480     await this.loggingChannel(newMessage.guild!.id)?.send({
481     embeds: [
482     new MessageEmbed({
483     title: "Message Updated",
484     author: {
485     name: oldMessage.author.tag,
486     iconURL: oldMessage.author.displayAvatarURL(),
487     },
488     description: "**-+-+Before**\n" + oldMessage.content + "\n\n**-+-+After**\n" + newMessage.content,
489     fields: [
490     {
491     name: "Message ID",
492     value: newMessage.id,
493     },
494     {
495     name: "User ID",
496     value: oldMessage.author.id,
497     },
498     {
499     name: "Channel",
500     value: `${oldMessage.channel} (${oldMessage.channelId})`,
501     },
502     ],
503     footer: {
504     text: `Updated • ${newMessage.id}`,
505     },
506     }),
507     ],
508     components: [row],
509     });
510     }
511    
512     async onMessageDelete(message: Message) {
513     const embed = new MessageEmbed({
514     title: "Message Deleted",
515     color: 0xf14a60,
516     author: {
517     name: message.author.tag,
518     iconURL: message.author.displayAvatarURL(),
519     },
520     description: message.content,
521     fields: [
522     {
523     name: "Message ID",
524     value: message.id,
525     },
526     {
527     name: "User ID",
528     value: message.author.id,
529     },
530     {
531     name: "Channel",
532     value: `${message.channel} (${message.channelId})`,
533     },
534     ],
535     footer: {
536     text: `Deleted • ${message.id}`,
537     },
538     });
539    
540     const files: FileOptions[] = [];
541    
542     if (message.attachments.size > 0) {
543     let str = "";
544    
545     message.attachments.forEach((a) => {
546     str += `${a.name}\n`;
547     files.push({
548     name: a.name!,
549     attachment: a.proxyURL,
550     });
551     });
552    
553     embed.addFields({
554     name: "Attachments (top)",
555     value: str,
556     });
557     }
558    
559     const row = new MessageActionRow().addComponents(new MessageButton().setLabel("Go to context").setStyle("LINK").setURL(message.url));
560    
561     if (message.type === "REPLY") {
562     row.addComponents(
563     new MessageButton()
564     .setLabel("Go to referenced message")
565     .setStyle("LINK")
566     .setURL(`https://discord.com/channels/${message.guildId!}/${message.channelId!}/${message.reference!.messageId}`)
567     );
568     }
569    
570     await this.loggingChannel(message.guild!.id)?.send({
571     embeds: [embed],
572     components: [row],
573     files,
574     });
575     }
576    
577     async onGuildBanAdd(ban: GuildBan, _executor?: User, id?: string | number) {
578     const auditLog = (
579     await ban.guild.fetchAuditLogs({
580     limit: 1,
581     type: "MEMBER_BAN_ADD",
582     })
583     ).entries.first();
584    
585     const executor = _executor ?? auditLog?.executor;
586    
587     if (executor?.id === this.client.user!.id) {
588     console.log("Action taken by bot");
589     return;
590     }
591    
592     const guildBan = await ban.guild.bans.fetch(ban.user.id);
593     const reason = ban.reason ?? guildBan.reason ?? "*No reason provided*";
594    
595     await this.loggingChannel(ban.guild.id)?.send({
596     embeds: [
597     new MessageEmbed()
598     .setColor("#f14a60")
599     .setTitle("A user was banned")
600     .setAuthor({
601     name: guildBan.user.tag,
602     iconURL: guildBan.user.displayAvatarURL(),
603     })
604     .addField("Reason", reason)
605     .addField("User ID", guildBan.user.id)
606     .addFields(
607     {
608     name: "Banned by",
609     value: executor ? `${executor.tag} (${executor.id})` : "Unknown",
610     },
611     {
612     name: "Infraction ID",
613     value: id?.toString() ?? "*Unavailable*",
614     }
615     )
616     .setFooter({
617     text: "Banned",
618     }),
619     ],
620     });
621     }
622    
623     async onGuildBanRemove(ban: GuildBan, _executor?: User) {
624     const auditLog = (
625     await ban.guild.fetchAuditLogs({
626     limit: 1,
627     type: "MEMBER_BAN_REMOVE",
628     })
629     ).entries.first();
630    
631     const executor = _executor ?? auditLog?.executor;
632    
633     await this.loggingChannel(ban.guild.id)?.send({
634     embeds: [
635     new MessageEmbed()
636     .setColor("#f14a60")
637     .setTitle("A user was unbanned")
638     .setAuthor({
639     name: ban.user.tag,
640     iconURL: ban.user.displayAvatarURL(),
641     })
642     .addField("User ID", ban.user.id)
643     .addFields({
644     name: "Unbanned By",
645     value: executor ? `${executor.tag} (${executor.id})` : "Unknown",
646     })
647     .setFooter({
648     text: "Unbanned",
649     })
650     .setTimestamp(),
651     ],
652     });
653     }
654    
655     async onSoftban(banOptions: BanOptions, guild: Guild, user: User, model: IPunishment) {
656     let r = banOptions.reason ?? "*No reason provided*";
657    
658     await this.loggingChannel(guild.id)?.send({
659     embeds: [
660     new MessageEmbed()
661     .setColor("#f14a60")
662     .setTitle("A user was softbanned")
663     .setAuthor({
664     name: user.tag,
665     iconURL: user.displayAvatarURL(),
666     })
667     .addField("Reason", r)
668     .addField("Softbanned by", `${model.mod_tag} (${model.mod_id})`)
669     .addField("User ID", user.id)
670     .addFields({
671     name: "Case ID",
672     value: model.numericId + "",
673     })
674     .setFooter({
675     text: "Softbanned",
676     })
677     .setTimestamp(),
678     ],
679     });
680     }
681    
682     async onTempBan(banOptions: BanOptions, guild: Guild, user: User, model: IPunishment) {
683     let r = banOptions.reason ?? "*No reason provided*";
684    
685     await this.loggingChannel(guild.id)?.send({
686     embeds: [
687     new MessageEmbed()
688     .setColor("#f14a60")
689     .setTitle("A user was temporarily banned")
690     .setAuthor({
691     name: user.tag,
692     iconURL: user.displayAvatarURL(),
693     })
694     .addField("Reason", r)
695     .addField("Banned by", `${model.mod_tag} (${model.mod_id})`)
696     .addField("User ID", user.id)
697     .addField("Duration", ms((model.meta as any).time))
698     .addFields({
699     name: "Case ID",
700     value: model.numericId + "",
701     })
702     .setFooter({
703     text: "Temporarily banned",
704     })
705     .setTimestamp(),
706     ],
707     });
708     }
709    
710     async onGuildMemberAdd(member: GuildMember, info?: IGuildInfo) {
711     let members = 0,
712     bots = 0;
713    
714     for (const m of member.guild!.members.cache.values()) {
715     if (m.user.bot) bots++;
716     else members++;
717     }
718    
719     const invite = member.user.bot ? null : await this.client.inviteTracker.getInviteInfo(member);
720    
721     await this.loggingChannelJoinLeave(member.guild.id)?.send({
722     embeds: [
723     new MessageEmbed()
724     .setColor("#007bff")
725     .setTitle("New member joined")
726     .setAuthor({
727     name: member.user.tag,
728     iconURL: member.user.displayAvatarURL(),
729     })
730     .setDescription(`<@${member.user.id}> just joined the server! Their position is ${members + bots}th.`)
731     .addField("Account Created", `${member.user.createdAt.toLocaleString()} (${timeSince(member.user.createdAt.getTime())})`)
732     .addField(
733     "New Account?",
734     new Date().getTime() - member.user.createdAt.getTime() <= 3 * 24 * 60 * 60 * 1000 ? ":warning: Yes :warning:" : "No"
735     )
736     .addField("Bot?", member.user.bot === true ? "Yes" : "No")
737     .addField("User ID", member.user.id)
738     .addFields(
739     {
740     name: "Total Members Joined",
741     value: info?.totalMembersJoined?.toString() ?? "*Information unavailable*",
742     },
743     {
744     name: "Positions",
745     value: `Among All members: ${members + bots}th\n${
746     member.user.bot ? `Among bots: ${bots}th` : `Among human members: ${members}th`
747     }`,
748     },
749     {
750     name: "Invite Information",
751     value: invite
752     ? `Inviter: ${invite.inviter ?? "*Unavailable*"}\nInvite URL: [https://discord.gg/${
753     invite.code
754     }](https://discord.gg/${invite.code})`
755     : "*Unavailable*",
756     }
757     )
758     .setFooter({
759     text: `Joined • ${members + bots} members total`,
760     })
761     .setTimestamp(),
762     ],
763     });
764     }
765    
766     async onGuildMemberRemove(member: GuildMember) {
767     const roles = member.roles.cache.filter((role) => role.id !== member.guild.id).reduce((acc, val) => ` ${acc} ${roleMention(val.id)}`, "");
768    
769     await this.loggingChannelJoinLeave(member.guild.id)?.send({
770     embeds: [
771     new MessageEmbed()
772     .setColor("#f14a60")
773     .setTitle("Member left")
774     .setAuthor({
775     name: member.user.tag,
776     iconURL: member.user.displayAvatarURL(),
777     })
778     .setDescription(`**Roles**\n${roles}`)
779     .addField("Joined at", `${member.joinedAt!.toLocaleString()} (${timeSince(member.joinedAt!.getTime())})`)
780     .addField("User ID", member.user.id)
781     .addField("Bot?", member.user.bot === true ? "Yes" : "No")
782     .setFooter({
783     text: `Left • ${member.guild.memberCount} members total`,
784     })
785     .setTimestamp(),
786     ],
787     });
788     }
789    
790     async onMemberShot(member: GuildMember, moderator: User, reason?: string, id?: string) {
791     await this.loggingChannel(member.guild.id)?.send({
792     embeds: [
793     new MessageEmbed()
794     .setColor("#007bff")
795     .setTitle("Member got shot")
796     .setAuthor({
797     name: member.user.tag,
798     iconURL: member.user.displayAvatarURL(),
799     })
800     .addField("Reason", reason ?? "*No reason provided*")
801     .addField("Doctor 💉", moderator.tag)
802     .addField("User ID", member.user.id)
803     .addFields({
804     name: "Infraction ID",
805     value: id ?? "*Unavailable*",
806     })
807     .setFooter({
808     text: "Shot delivered",
809     })
810     .setTimestamp(),
811     ],
812     });
813     }
814    
815     async onMemberKick(member: GuildMember, reason?: string, executor?: User, id?: string) {
816     await this.loggingChannel(member.guild.id)?.send({
817     embeds: [
818     new MessageEmbed({
819     author: {
820     name: member.user.tag,
821     iconURL: member.user.displayAvatarURL(),
822     },
823     title: "Member Kicked",
824     description: "This user has left the server, probably due to a kick.",
825     fields: [
826     {
827     name: "Kicked by",
828     value: executor?.tag ?? "Unknown",
829     },
830     {
831     name: "Reason",
832     value: reason ?? "*No reason provided*",
833     },
834     {
835     name: "Infraction ID",
836     value: id ?? "*Unavailable*",
837     },
838     ],
839     footer: {
840     text: "Kicked",
841     },
842     }).setTimestamp(),
843     ],
844     });
845     }
846    
847     async onMemberMute(member: GuildMember, duration?: number, reason?: string, executor?: User, hard = false, id?: string) {
848     await this.loggingChannel(member.guild.id)?.send({
849     embeds: [
850     new MessageEmbed()
851     .setColor("#f14a60")
852     .setTitle("Member muted")
853     .setAuthor({
854     name: member.user.tag,
855     iconURL: member.user.displayAvatarURL(),
856     })
857     .addField("Reason", reason ?? "*No reason provided*")
858     .addField("Muted by", executor?.tag ?? "Unknown")
859     .addField(
860     "Duration Until",
861     duration
862     ? `${new Date(Date.now() + duration).toLocaleString()} (${formatDuration(
863     intervalToDuration({ start: 0, end: duration })
864     )})`
865     : "*No duration set*"
866     )
867     .addField("User ID", member.user.id)
868     .addField("Hardmute", hard ? "Yes" : "No")
869     .addFields({
870     name: "Infraction ID",
871     value: id ?? "*Unavailable*",
872     })
873     .setFooter({
874     text: "Muted",
875     })
876     .setTimestamp(),
877     ],
878     });
879     }
880    
881     async onMemberUnmute(member: GuildMember, executor?: User) {
882     await this.loggingChannel(member.guild.id)?.send({
883     embeds: [
884     new MessageEmbed()
885     .setColor("#007bff")
886     .setTitle("Member unmuted")
887     .setAuthor({
888     name: member.user.tag,
889     iconURL: member.user.displayAvatarURL(),
890     })
891     .addField("Unmuted by", executor?.tag ?? "Unknown")
892     .addField("User ID", member.user.id)
893     .setFooter({
894     text: "Unmuted",
895     })
896     .setTimestamp(),
897     ],
898     });
899     }
900    
901     async onMemberWarn(user: User, guildID: string, id: string, reason?: string, moderator?: User) {
902     await this.loggingChannel(guildID)?.send({
903     embeds: [
904     new MessageEmbed()
905     .setColor("GOLD")
906     .setTitle("Member warned")
907     .setAuthor({
908     name: user.tag,
909     iconURL: user.displayAvatarURL(),
910     })
911     .addField("Reason", reason ?? "*No reason provided*")
912     .addField("Warned by", moderator?.tag ?? "*No reason provided*")
913     .addField("User ID", user.id)
914     .addField("Infraction ID", id + "")
915     .setFooter({
916     text: "Warned",
917     })
918     .setTimestamp(),
919     ],
920     });
921     }
922    
923     async onMemberWarningDelete(member: GuildMember, id: string, reason?: string, moderator?: User) {
924     await this.loggingChannel(member.guild.id)?.send({
925     embeds: [
926     new MessageEmbed()
927     .setColor("GOLD")
928     .setTitle("Warning deleted")
929     .setAuthor({
930     name: member.user.tag,
931     iconURL: member.user.displayAvatarURL(),
932     })
933     .addField("Warned by", moderator?.tag ?? "Unknown")
934     .addField("Infraction ID", id + "")
935     .addField("User ID", member.user.id)
936     .setFooter({
937     text: "Warning Deleted",
938     })
939     .setTimestamp(),
940     ],
941     });
942     }
943    
944     async onMemberUpdate(oldMember: GuildMember, newMember: GuildMember) {
945     if (oldMember.isCommunicationDisabled() && !newMember.isCommunicationDisabled()) {
946     setTimeout(async () => {
947     const auditLog = await newMember.guild.fetchAuditLogs({
948     type: "MEMBER_UPDATE",
949     limit: 1,
950     });
951    
952     const data = auditLog?.entries.first();
953    
954     console.log(data);
955    
956     Punishment.create({
957     createdAt: new Date(),
958     guild_id: newMember.guild.id,
959     mod_id: data?.executor?.id,
960     mod_tag: data?.executor?.tag,
961     user_id: newMember.user.id,
962     type: PunishmentType.TIMEOUT_REMOVE,
963     }).catch(console.error);
964    
965     await this.loggingChannel(newMember.guild.id)?.send({
966     embeds: [
967     new MessageEmbed()
968     .setColor("GOLD")
969     .setTitle("Member Timeout Removed")
970     .setAuthor({
971     name: newMember.user.tag,
972     iconURL: newMember.user.displayAvatarURL(),
973     })
974     .addField(
975     "Removed by",
976     data?.target?.id === newMember.user.id && data?.executor?.tag
977     ? `${data?.executor?.tag} (${data?.executor?.id})`
978     : "*Timeout expired automatically*"
979     )
980     .addField("User ID", oldMember.user.id)
981     .setFooter({
982     text: "Timeout Removed",
983     })
984     .setTimestamp(),
985     ],
986     });
987     }, 2000);
988     } else if (!oldMember.isCommunicationDisabled() && newMember.isCommunicationDisabled()) {
989     setTimeout(async () => {
990     const auditLog = await newMember.guild.fetchAuditLogs({
991     type: "MEMBER_UPDATE",
992     limit: 1,
993     });
994    
995     const data = auditLog?.entries.first();
996    
997     console.log(data);
998    
999     Punishment.create({
1000     createdAt: new Date(),
1001     guild_id: newMember.guild.id,
1002     mod_id: data?.executor?.id,
1003     mod_tag: data?.executor?.tag,
1004     reason: data?.reason,
1005     user_id: newMember.user.id,
1006     type: PunishmentType.TIMEOUT,
1007     meta: {
1008     time: ms(newMember.communicationDisabledUntilTimestamp - Date.now()),
1009     },
1010     }).catch(console.error);
1011    
1012     await this.loggingChannel(newMember.guild.id)?.send({
1013     embeds: [
1014     new MessageEmbed()
1015     .setColor("#f14a60")
1016     .setTitle("Member Timed Out")
1017     .setAuthor({
1018     name: newMember.user.tag,
1019     iconURL: newMember.user.displayAvatarURL(),
1020     })
1021     .addFields(
1022     {
1023     name: "Reason",
1024     value: data?.reason ?? "*No reason provided*",
1025     },
1026     {
1027     name: "Duration",
1028     value: newMember.communicationDisabledUntil
1029     ? `${newMember.communicationDisabledUntil.toUTCString()} (${formatDistanceStrict(
1030     newMember.communicationDisabledUntil,
1031     new Date()
1032     )})`
1033     : "Unknown",
1034     }
1035     )
1036     .addField(
1037     "Action taken by",
1038     data?.target?.id === newMember.user.id && data?.executor?.tag
1039     ? `${data?.executor?.tag} (${data?.executor?.id})`
1040     : "Unknown"
1041     )
1042     .addField("User ID", oldMember.user.id)
1043     .setFooter({
1044     text: "Timed-out",
1045     })
1046     .setTimestamp(),
1047     ],
1048     });
1049     }, 2000);
1050     }
1051     }
1052     }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26