-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlogs_handler.ts
154 lines (137 loc) · 6.15 KB
/
logs_handler.ts
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
import {
AuditLogEvent, Client, Guild, GuildAuditLogsEntry, GuildBan, GuildMember, PartialGuildMember, TextChannel,
User
} from 'discord.js';
import {Snowflake} from "discord-api-types/v10";
import {getConfig} from "./config";
export default async (client: Client, lock) => {
const {guildId, welcomesChannel, discordWelcomesChannel, logChannel, nitroChannel, nitroBoostRole} = await getConfig();
const pendingMembers = new Set()
const leaveStates: Record<Snowflake,
{
kick?: GuildAuditLogsEntry<AuditLogEvent.MemberKick> | null,
ban?: GuildBan | null,
timeoutHandle?: ReturnType<typeof setTimeout>
}> = {}
let logs: TextChannel
async function getKick(member: GuildMember | PartialGuildMember) {
const kick = (await member.guild.fetchAuditLogs({limit: 1, type: AuditLogEvent.MemberKick})).entries.first()
if (!kick || Date.now() - kick.createdTimestamp > 3000) return null
return member.id === kick.target.id ? kick : null
}
async function memberLeft(member: GuildMember | PartialGuildMember | User, guild: Guild, done) {
const leaveState = leaveStates[member.id]
const tag = member instanceof User ? member.tag : member.user.tag
const channel = guild.channels.cache.get(welcomesChannel) as TextChannel
if (leaveState.ban) {
if (typeof leaveState.ban === 'string') {
channel.send(`Curse you warlock, don't ever return! (${tag} has been banned from ${guild.name} for ${leaveState.ban})`)
.then(() => done())
.catch(done)
}
} else {
const callback = () => {
const name = member instanceof User ? member.username : member.displayName
delete leaveStates[member.id];
if (leaveState.kick) {
if (typeof leaveState.kick === 'string') {
channel.send(`Off to torment with you, ${name}! (${tag} has been kicked from ${guild.name} for ${leaveState.kick})`)
.then(() => done())
.catch(done)
} else {
channel.send(`Off to torment with you, ${name}! (${tag} has been kicked from ${guild.name})`)
.then(() => done())
.catch(done)
}
} else {
channel.send(`Shame, ${name} was brewing a nice concoction as well (${tag} has left ${guild.name})`)
.then(() => done())
.catch(done)
}
}
if (leaveState.kick) {
callback()
} else {
getKick(member as GuildMember).then(kick => {
leaveState.kick = kick
callback()
}).catch(done)
}
}
}
client.on('ready', client => client.guilds.cache.get(guildId)
.channels.fetch(logChannel)
.then(channel => {
logs = channel as TextChannel
})
);
client.on('guildMemberAdd', async member => {
await logs.send(`User ${member} entered membership screening.`)
await lock.acquire('pendingMembers', done => {
pendingMembers.add(member.id)
done()
})
})
client.on('guildMemberRemove', async member => {
if (await lock.acquire('pendingMembers', done => done(undefined, pendingMembers.has(member.id)))) {
await logs.send(`User ${member}[${member.user.tag}] left membership screening.`)
} else {
await logs.send(`User ${member}[${member.user.tag}] left the server.`)
await lock.acquire('leaveStates', done => {
const leaveState = leaveStates[member.id]
if (leaveState) {
memberLeft(member, member.guild, done)
} else {
getKick(member).then(kick => {
if (kick) {
leaveStates[member.id] = {kick}
memberLeft(member, member.guild, done)
} else {
leaveStates[member.id] = {
timeoutHandle: setTimeout(() => lock.acquire('leaveStates', done => {
memberLeft(member, member.guild, done)
}), 1500)
}
done()
}
}).catch(done)
}
})
}
})
client.on('guildBanAdd', async ban => {
const fullBan = await ban.fetch(true)
await lock.acquire('leaveStates', done => {
const leaveState = leaveStates[fullBan.user.id]
if (leaveState) {
leaveState.ban = fullBan
// If we know it's a ban, why wait?
clearTimeout(leaveState.timeoutHandle)
memberLeft(fullBan.user, fullBan.guild, done)
} else {
leaveStates[fullBan.user.id] = {ban: fullBan}
}
done()
})
})
client.on('messageCreate', async message => {
if (message.channelId === discordWelcomesChannel && message.system) {
await lock.acquire('pendingMembers', done => {
if (pendingMembers.has(message.member.id)) {
pendingMembers.delete(message.member.id);
(message.guild.channels.cache.get(welcomesChannel) as TextChannel)
.send(`Welcome ${message.member} to the Witch's Grove`)
.then(() => done()).catch(done)
} else {
done()
}
})
}
})
client.on('guildMemberUpdate', async (oldMember, newMember) => {
if (!oldMember.roles.resolve(nitroBoostRole) && newMember.roles.resolve(nitroBoostRole)) {
await (newMember.guild.channels.cache.get(nitroChannel) as TextChannel)
.send(`🎉 🎉 Thank you ${newMember} for boosting ${newMember.guild.name}!! 🎉 🎉`)
}
})
}