logging: more cleanup, kick and ban events

This commit is contained in:
Cynthia Foxwell 2025-06-21 12:49:05 -06:00
parent ae53e37204
commit 0ea9264ae3
Signed by: Cynosphere
SSH key fingerprint: SHA256:H3SM8ufP/uxqLwKSH7xY89TDnbR9uOHzjLoBr0tlajk

View file

@ -81,6 +81,9 @@ const WHITELISTED_EVENTS = new Set([
"GUILD_PROFILE_UPDATE",
]);
const cacheBanTimeout = {};
const leaveTimeout = {};
events.add("guildAuditLogEntryCreate", "logging", async function (entry) {
const channel = await getLoggingChannel(entry.guild);
if (!channel) return;
@ -94,9 +97,6 @@ events.add("guildAuditLogEntryCreate", "logging", async function (entry) {
case AuditLogActions.CHANNEL_OVERWRITE_CREATE:
case AuditLogActions.CHANNEL_OVERWRITE_UPDATE:
case AuditLogActions.CHANNEL_OVERWRITE_DELETE:
case AuditLogActions.MEMBER_KICK:
case AuditLogActions.MEMBER_BAN_ADD:
case AuditLogActions.MEMBER_BAN_REMOVE:
case AuditLogActions.BOT_ADD:
case AuditLogActions.ROLE_CREATE:
case AuditLogActions.ROLE_UPDATE:
@ -185,7 +185,7 @@ events.add("guildAuditLogEntryCreate", "logging", async function (entry) {
footer: {
text: `Channel ID: ${entry.targetID}`,
},
timestamp: new Date().toISOString(),
timestamp: new Date(snowflakeToTimestamp(entry.id)).toISOString(),
},
],
});
@ -297,7 +297,8 @@ events.add("guildAuditLogEntryCreate", "logging", async function (entry) {
embeds: [
{
color: COLOR_CHANGED,
title: `Server updated`,
title: `Server Updated`,
timestamp: new Date(snowflakeToTimestamp(entry.id)).toISOString(),
fields,
thumbnail:
thumbnail != null
@ -311,10 +312,6 @@ events.add("guildAuditLogEntryCreate", "logging", async function (entry) {
url: image,
}
: null,
footer: {
text: `Guild ID: ${entry.targetID}`,
},
timestamp: new Date().toISOString(),
},
],
});
@ -340,6 +337,22 @@ events.add("guildAuditLogEntryCreate", "logging", async function (entry) {
value: formatChange(oldVisibility, newVisibility),
inline: true,
});
break;
}
case "server_tag": {
fields.push({
name: "Server Tag",
value: formatChange(oldValue, newValue),
inline: true,
});
break;
}
default: {
fields.push({
name: `\`${key}\``,
value: formatChange(oldValue, newValue),
inline: true,
});
}
}
}
@ -361,11 +374,8 @@ events.add("guildAuditLogEntryCreate", "logging", async function (entry) {
{
color: COLOR_CHANGED,
title: `Server Profile Updated`,
timestamp: new Date(snowflakeToTimestamp(entry.id)).toISOString(),
fields,
footer: {
text: `Guild ID: ${entry.targetID}`,
},
timestamp: new Date().toISOString(),
},
],
});
@ -420,11 +430,11 @@ events.add("guildAuditLogEntryCreate", "logging", async function (entry) {
? "themselves"
: `member <@${entry.targetID}> (${formatUsername(target)})`
}`,
timestamp: new Date(snowflakeToTimestamp(entry.id)).toISOString(),
fields,
footer: {
text: `User ID: ${entry.targetID}`,
},
timestamp: new Date().toISOString(),
},
],
});
@ -453,7 +463,7 @@ events.add("guildAuditLogEntryCreate", "logging", async function (entry) {
} ${roles.length > 1 ? `${roles.length} ` : ""}role${plural} ${added ? "to" : "from"} ${
isSelf ? "self" : `<@${entry.targetID}> (${formatUsername(entry.target.user)})`
}`,
timestamp: new Date().toISOString(),
timestamp: new Date(snowflakeToTimestamp(entry.id)).toISOString(),
fields: [
!addAndRemove && {
name: `Role${plural}`,
@ -493,6 +503,7 @@ events.add("guildAuditLogEntryCreate", "logging", async function (entry) {
)}) created webhook \`${after.name.replaceAll("`", "\u02cb")}\` in <#${entry.after.channel_id}> (${
entry.guild.channels.get(after.channel_id)?.name ?? "<uncached>"
})`,
timestamp: new Date(snowflakeToTimestamp(entry.id)).toISOString(),
fields: [
after.application_id != null && {
name: "Application ID",
@ -525,7 +536,7 @@ events.add("guildAuditLogEntryCreate", "logging", async function (entry) {
color: COLOR_ADDED,
title: `${after.invitable != null ? "Private " : ""}Thread Created`,
description: `<#${entry.targetID}> (${after.name})`,
timestamp: new Date().toISOString(),
timestamp: new Date(snowflakeToTimestamp(entry.id)).toISOString(),
fields: [
{
name: "Created by",
@ -616,7 +627,7 @@ events.add("guildAuditLogEntryCreate", "logging", async function (entry) {
description: `<@${entry.user.id}> (${formatUsername(entry.user)}) ${verb} <#${entry.targetID}>${
entry.target?.name != null ? ` (${entry.target.name})` : ""
}`,
timestamp: new Date().toISOString(),
timestamp: new Date(snowflakeToTimestamp(entry.id)).toISOString(),
fields: [
after.name != null && {
name: "Name",
@ -663,7 +674,7 @@ events.add("guildAuditLogEntryCreate", "logging", async function (entry) {
color: COLOR_REMOVED,
title: `${entry.before.invitable != null ? "Private " : ""}Thread Deleted`,
description: `<#${entry.targetID}> (${entry.before.name})`,
timestamp: new Date().toISOString(),
timestamp: new Date(snowflakeToTimestamp(entry.id)).toISOString(),
fields: [
{
name: "Deleted by",
@ -690,6 +701,150 @@ events.add("guildAuditLogEntryCreate", "logging", async function (entry) {
});
break;
}
case AuditLogActions.MEMBER_KICK: {
const leaveData = leaveTimeout[entry.guild.id];
let member;
if (leaveData.user === entry.targetID) {
clearTimeout(leaveData.timeout);
member = leaveData.member;
}
const user = await hf.bot.requestHandler.request("GET", APIEndpoints.USER(entry.targetID), true);
const defaultAvatar = getDefaultAvatar(user.id, user.discriminator ?? 0);
const avatar = user.avatar ? CDNEndpoints.USER_AVATAR(user.id, user.avatar) : defaultAvatar;
channel.createMessage({
embeds: [
{
color: COLOR_REMOVED,
title: "User Kicked",
description: `<@${entry.user.id}> (${formatUsername(entry.user)}) kicked <@${user.id}> (${formatUsername(
user
)})`,
timestamp: new Date(snowflakeToTimestamp(entry.id)).toISOString(),
fields: [
member?.joinedAt && {
name: "Joined",
value: `<t:${Math.floor(member.joinedAt / 1000)}:R>`,
inline: true,
},
member?.nick && {
name: "Nickname",
value: member.nick,
inline: true,
},
entry.integrationType != null && {
name: "Integration Type",
value: `\`${entry.integrationType}\``,
inline: true,
},
member?.roles?.length > 0 && {
name: "Roles",
value: member.roles
.sort((a, b) => entry.guild.roles.get(b).position - entry.guild.roles.get(a).position)
.map((role) => `<@&${role}>`)
.join(", "),
inline: false,
},
entry.reason != null && {
name: "Reason",
value: `\`${entry.reason.replaceAll("`", "\u02cb")}\``,
},
].filter((x) => !!x),
footer: {
text: `User ID: ${entry.targetID}`,
},
thumbnail: {
url: avatar,
},
},
],
});
break;
}
case AuditLogActions.MEMBER_BAN_ADD: {
const callback = async () => {
const user = await hf.bot.requestHandler.request("GET", APIEndpoints.USER(entry.targetID), true);
const defaultAvatar = getDefaultAvatar(user.id, user.discriminator ?? 0);
const avatar = user.avatar ? CDNEndpoints.USER_AVATAR(user.id, user.avatar) : defaultAvatar;
channel.createMessage({
embeds: [
{
color: COLOR_REMOVED,
title: "User Banned",
description: `<@${entry.user.id}> (${formatUsername(entry.user)}) banned <@${
user.id
}> (${formatUsername(user)})`,
timestamp: new Date(snowflakeToTimestamp(entry.id)).toISOString(),
fields: [
entry.reason != null && {
name: "Reason",
value: `\`${entry.reason.replaceAll("`", "\u02cb")}\``,
},
].filter((x) => !!x),
footer: {
text: `User ID: ${entry.targetID}`,
},
thumbnail: {
url: avatar,
},
},
],
});
};
if (entry.user.bot) {
cacheBanTimeout[entry.guild.id] = {
user: entry.user.id,
timeout: setTimeout(callback, 1500),
};
break;
} else {
await callback();
}
break;
}
case AuditLogActions.MEMBER_BAN_REMOVE: {
const cacheBan = cacheBanTimeout[entry.guild.id];
if (cacheBan?.user === entry.user.id) {
clearTimeout(cacheBan.timeout);
delete cacheBanTimeout[entry.guild.id];
break;
}
const user = await hf.bot.requestHandler.request("GET", APIEndpoints.USER(entry.targetID), true);
const defaultAvatar = getDefaultAvatar(user.id, user.discriminator ?? 0);
const avatar = user.avatar ? CDNEndpoints.USER_AVATAR(user.id, user.avatar) : defaultAvatar;
channel.createMessage({
embeds: [
{
color: COLOR_ADDED,
title: "User Unbanned",
description: `<@${entry.user.id}> (${formatUsername(entry.user)}) unbanned <@${
user.id
}> (${formatUsername(user)})`,
timestamp: new Date(snowflakeToTimestamp(entry.id)).toISOString(),
fields: [
entry.reason != null && {
name: "Reason",
value: `\`${entry.reason.replaceAll("`", "\u02cb")}\``,
},
].filter((x) => !!x),
footer: {
text: `User ID: ${entry.targetID}`,
},
thumbnail: {
url: avatar,
},
},
],
});
break;
}
}
} catch (err) {
const eventName = Object.entries(AuditLogActions).find(([name, val]) => val === entry.actionType)[0];
@ -823,48 +978,56 @@ events.add("guildMemberRemove", "logging", async function (guild, member) {
const timestamp = new Date().toISOString();
if (member instanceof Member) {
const user = member.user;
const defaultAvatar = getDefaultAvatar(user.id, user.discriminator ?? 0);
const avatar = user.avatar ? CDNEndpoints.USER_AVATAR(user.id, user.avatar) : defaultAvatar;
const callback = async () => {
const user = member.user;
const defaultAvatar = getDefaultAvatar(user.id, user.discriminator ?? 0);
const avatar = user.avatar ? CDNEndpoints.USER_AVATAR(user.id, user.avatar) : defaultAvatar;
channel
.createMessage({
embeds: [
{
color: COLOR_REMOVED,
title: "Member Left",
description: `<@${user.id}> (${formatUsername(user)})`,
timestamp,
thumbnail: {
url: avatar,
channel
.createMessage({
embeds: [
{
color: COLOR_REMOVED,
title: "Member Left",
description: `<@${user.id}> (${formatUsername(user)})`,
timestamp,
thumbnail: {
url: avatar,
},
fields: [
member?.joinedAt && {
name: "Joined",
value: `<t:${Math.floor(member.joinedAt / 1000)}:R>`,
inline: true,
},
member?.nick && {
name: "Nickname",
value: member.nick,
inline: true,
},
member?.roles?.length > 0 && {
name: "Roles",
value: member.roles
.sort((a, b) => guild.roles.get(b).position - guild.roles.get(a).position)
.map((role) => `<@&${role}>`)
.join(", "),
inline: false,
},
].filter((x) => !!x),
footer: {
text: `User ID: ${user.id}`,
},
},
fields: [
{
name: "Joined",
value: `<t:${Math.floor(member.joinedAt / 1000)}:R>`,
inline: true,
},
member?.nick && {
name: "Nickname",
value: member.nick,
inline: true,
},
member?.roles?.length > 0 && {
name: "Roles",
value: member.roles
.sort((a, b) => guild.roles.get(b).position - guild.roles.get(a).position)
.map((role) => `<@&${role}>`)
.join(", "),
inline: false,
},
].filter((x) => !!x),
footer: {
text: `User ID: ${user.id}`,
},
},
],
})
.catch(() => {});
],
})
.catch(() => {});
};
leaveTimeout[guild.id] = {
user: member.user.id,
member,
timeout: setTimeout(callback, 2000),
};
} else {
const user = await hf.bot.requestHandler.request("GET", APIEndpoints.USER(member.user.id), true);
const defaultAvatar = getDefaultAvatar(user.id, user.discriminator ?? 0);