Skip to content

Commit 425a647

Browse files
authored
Fix incorrect "kicked" modlog when users leave (#247)
The logic here was checking whether a return value existed, but I got things twisted as I refactored and had added a "left" case. So members that leave the server are being incorrectly logged as kicked. Strictly speaking, we could in fact open a new thread for every member, thus capturing their entire membership journey — when they join, when the leave (or are removed), any automod triggers… The downside is that it becomes a little bit more "proactive surveillance" vs "incident recording", and in general I prefer to avoid surveillance
1 parent d673164 commit 425a647

File tree

1 file changed

+50
-85
lines changed

1 file changed

+50
-85
lines changed

app/discord/modActionLogger.ts

Lines changed: 50 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -27,66 +27,37 @@ async function handleBanAdd(ban: GuildBan) {
2727
reason,
2828
});
2929

30-
try {
31-
// Check audit log for who performed the ban
32-
const auditLogs = await guild.fetchAuditLogs({
33-
type: AuditLogEvent.MemberBanAdd,
34-
limit: 5,
35-
});
36-
37-
const banEntry = auditLogs.entries.find(
38-
(entry) =>
39-
entry.target?.id === user.id &&
40-
Date.now() - entry.createdTimestamp < AUDIT_LOG_WINDOW_MS,
41-
);
30+
// Check audit log for who performed the ban
31+
const auditLogs = await guild.fetchAuditLogs({
32+
type: AuditLogEvent.MemberBanAdd,
33+
limit: 5,
34+
});
4235

43-
executor = banEntry?.executor ?? null;
44-
reason = banEntry?.reason ?? reason;
36+
const banEntry = auditLogs.entries.find(
37+
(entry) =>
38+
entry.target?.id === user.id &&
39+
Date.now() - entry.createdTimestamp < AUDIT_LOG_WINDOW_MS,
40+
);
4541

46-
// Skip if the bot performed this action (it's already logged elsewhere)
47-
if (executor?.id === guild.client.user?.id) {
48-
log("debug", "ModActionLogger", "Skipping self-ban", {
49-
userId: user.id,
50-
guildId: guild.id,
51-
});
52-
return;
53-
}
54-
} catch (error) {
55-
// If we can't access audit log, still log the ban but without executor info
56-
if (
57-
error instanceof Error &&
58-
error.message.includes("Missing Permissions")
59-
) {
60-
log(
61-
"warn",
62-
"ModActionLogger",
63-
"Cannot access audit log for ban details",
64-
{ userId: user.id, guildId: guild.id },
65-
);
66-
} else {
67-
log("error", "ModActionLogger", "Failed to fetch audit log for ban", {
68-
userId: user.id,
69-
guildId: guild.id,
70-
error,
71-
});
72-
}
73-
}
42+
executor = banEntry?.executor ?? null;
43+
reason = banEntry?.reason ?? reason;
7444

75-
try {
76-
await reportModAction({
77-
guild,
78-
user,
79-
actionType: "ban",
80-
executor,
81-
reason: reason ?? "",
82-
});
83-
} catch (error) {
84-
log("error", "ModActionLogger", "Failed to report ban", {
45+
// Skip if the bot performed this action (it's already logged elsewhere)
46+
if (executor?.id === guild.client.user?.id) {
47+
log("debug", "ModActionLogger", "Skipping self-ban", {
8548
userId: user.id,
8649
guildId: guild.id,
87-
error,
8850
});
51+
return;
8952
}
53+
54+
await reportModAction({
55+
guild,
56+
user,
57+
actionType: "ban",
58+
executor,
59+
reason: reason ?? "",
60+
});
9061
}
9162

9263
async function fetchAuditLogs(
@@ -152,41 +123,39 @@ async function handleMemberRemove(member: GuildMember | PartialGuildMember) {
152123
guildId: guild.id,
153124
});
154125

155-
try {
156-
const auditLogs = await fetchAuditLogs(guild, user);
157-
158-
if (auditLogs) {
159-
const { executor = null, reason = "" } = auditLogs;
160-
await reportModAction({
161-
guild,
162-
user,
163-
actionType: "kick",
164-
executor,
165-
reason,
166-
});
167-
return;
168-
}
169-
await reportModAction({
170-
guild,
171-
user,
172-
actionType: "left",
173-
executor: undefined,
174-
reason: undefined,
175-
});
176-
} catch (error) {
177-
log("error", "ModActionLogger", "Failed to handle member removal", {
178-
userId: user.id,
179-
guildId: guild.id,
180-
error,
181-
});
126+
const auditLogs = await fetchAuditLogs(guild, user);
127+
if (!auditLogs || auditLogs?.actionType === "left") {
128+
return;
182129
}
130+
131+
const { executor = null, reason = "" } = auditLogs;
132+
await reportModAction({
133+
guild,
134+
user,
135+
actionType: "kick",
136+
executor,
137+
reason,
138+
});
183139
}
184140

185141
export default async (bot: Client) => {
186142
bot.on(Events.GuildBanAdd, async (ban) => {
187143
try {
188144
await handleBanAdd(ban);
189145
} catch (error) {
146+
// If we can't access audit log, still log the ban but without executor info
147+
if (
148+
error instanceof Error &&
149+
error.message.includes("Missing Permissions")
150+
) {
151+
log(
152+
"warn",
153+
"ModActionLogger",
154+
"Cannot access audit log for ban details",
155+
{ userId: ban.user.id, guildId: ban.guild.id },
156+
);
157+
return;
158+
}
190159
log("error", "ModActionLogger", "Unhandled error in ban handler", {
191160
userId: ban.user.id,
192161
guildId: ban.guild.id,
@@ -203,11 +172,7 @@ export default async (bot: Client) => {
203172
"error",
204173
"ModActionLogger",
205174
"Unhandled error in member remove handler",
206-
{
207-
userId: member.user?.id,
208-
guildId: member.guild.id,
209-
error,
210-
},
175+
{ userId: member.user?.id, guildId: member.guild.id, error },
211176
);
212177
}
213178
});

0 commit comments

Comments
 (0)