1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
import { BotListener, colors, Emitter, humanizeDuration, Moderation, ModLogType, sleep, Time, type BotClientEvents } from '#lib';
import { AuditLogEvent, EmbedBuilder, Events, PermissionFlagsBits } from 'discord.js';
export default class ModlogSyncKickListener extends BotListener {
public constructor() {
super('modlogSyncKick', {
emitter: Emitter.Client,
event: Events.GuildMemberRemove
});
}
public async exec(...[member]: BotClientEvents[Events.GuildMemberRemove]) {
if (!(await member.guild.hasFeature('logManualPunishments'))) return;
if (!member.guild.members.me) return; // bot was removed from guild
if (!member.guild.members.me.permissions.has(PermissionFlagsBits.ViewAuditLog)) {
return member.guild.error(
'modlogSyncKick',
`Could not sync the potential manual kick of ${member.user.tag} to the modlog because I do not have the "View Audit Log" permission.`
);
}
const now = new Date();
await sleep(500 * Time.Millisecond); // wait for audit log entry
const logs = (await member.guild.fetchAuditLogs({ type: AuditLogEvent.MemberKick })).entries.filter(
(entry) => entry.target?.id === member.user.id
);
const first = logs.first();
if (!first) return;
if (!first.executor || first.executor?.bot) return;
if (Math.abs(first.createdAt.getTime() - now.getTime()) > Time.Minute) {
throw new Error(`Time is off by over a minute: ${humanizeDuration(Math.abs(first.createdAt.getTime() - now.getTime()))}`);
}
const { log } = await Moderation.createModLogEntry({
client: this.client,
type: ModLogType.KICK,
user: member.user,
moderator: first.executor,
reason: `[Manual] ${first.reason ? first.reason : 'No reason given'}`,
guild: member.guild
});
if (!log) throw new Error('Failed to create modlog entry');
const logChannel = await member.guild.getLogChannel('moderation');
if (!logChannel) return;
const logEmbed = new EmbedBuilder()
.setColor(colors.Red)
.setTimestamp()
.setFooter({ text: `CaseID: ${log.id}` })
.setAuthor({
name: member.user.tag,
iconURL: member.user.avatarURL({ extension: 'png', size: 4096 }) ?? undefined
})
.addFields(
{ name: '**Action**', value: 'Manual Kick' },
{ name: '**User**', value: `${member.user} (${member.user.tag})` },
{ name: '**Moderator**', value: `${first.executor} (${first.executor.tag})` },
{ name: '**Reason**', value: `${first.reason ? first.reason : '[No Reason Provided]'}` }
);
return await logChannel.send({ embeds: [logEmbed] });
}
}
|