feat: add discord analytics
Node.js CI / Lint and Test (push) Failing after 29s

This commit is contained in:
2025-10-09 19:56:00 -07:00
parent 91d7a1ef28
commit e38d1057f4
16 changed files with 55 additions and 41 deletions
+8 -1
View File
@@ -1,3 +1,4 @@
import { DiscordAnalytics } from "@nhcarrigan/discord-analytics";
import { ExtendedClient } from "../interfaces/ExtendedClient";
import { checkEntitledGuild } from "../utils/checkEntitledGuild";
@@ -17,6 +18,7 @@ import { onThreadCreate } from "./thread/onThreadCreate";
import { onThreadDelete } from "./thread/onThreadDelete";
import { onThreadUpdate } from "./thread/onThreadUpdate";
import { onVoiceUpdate } from "./voice/onVoiceUpdate";
import { logHandler } from "../utils/logHandler.js";
/**
* Module to mount the Discord event listeners.
@@ -24,8 +26,13 @@ import { onVoiceUpdate } from "./voice/onVoiceUpdate";
* @param {ExtendedClient} bot The bot's Discord instance.
*/
export const handleEvents = (bot: ExtendedClient) => {
const analytics = new DiscordAnalytics(bot, logHandler);
/* Client Events */
bot.on("ready", async () => await onReady(bot));
bot.once("ready", async () => {
await onReady(bot);
analytics.startCron();
});
bot.on("disconnect", () => onDisconnect());
/* Message Events */
+2
View File
@@ -5,6 +5,7 @@ import { getModActionFromAuditLog } from "../../modules/events/getModActionFromA
import { addCase } from "../../utils/addCase";
import { errorHandler } from "../../utils/errorHandler";
import { sendLogMessage } from "../../utils/sendLogMessage";
import { logHandler } from "../../utils/logHandler.js";
/**
* Handles properly logging a manual mod action based on audit logs.
@@ -72,6 +73,7 @@ export const onAuditLogEntry = async (
false,
caseNum
);
await logHandler.metric("audit_log_action", 1, { modAction, guildId: guild.id, targetId: target.id });
} catch (err) {
await errorHandler(bot, "on audit log entry", err);
}
+2
View File
@@ -9,6 +9,7 @@ import { handleMassBanModal } from "../../modules/modals/handleMassBanModal";
import { handleMessageReportModal } from "../../modules/modals/handleMessageReportModal";
import { checkEntitledGuild } from "../../utils/checkEntitledGuild";
import { errorHandler } from "../../utils/errorHandler";
import { logHandler } from "../../utils/logHandler.js";
/**
* Handles interactions.
@@ -60,6 +61,7 @@ export const onInteraction = async (
await handleMessageReportModal(bot, interaction);
}
}
await logHandler.metric("interaction_create", 1, { userId: interaction.user.id, guildId: interaction.guild.id, command: interaction.isCommand() ? interaction.commandName : interaction.customId });
} catch (err) {
const id = await errorHandler(bot, "on interaction", err);
if (!interaction.isAutocomplete()) {
+2
View File
@@ -3,6 +3,7 @@ import { GuildMember } from "discord.js";
import { ExtendedClient } from "../../interfaces/ExtendedClient";
import { getConfig } from "../../modules/data/getConfig";
import { errorHandler } from "../../utils/errorHandler";
import { logHandler } from "../../utils/logHandler.js";
/**
* Sends a log message to the configured log channel when a member
@@ -36,6 +37,7 @@ export const onMemberAdd = async (bot: ExtendedClient, member: GuildMember) => {
await channel.send({
content: `${user.tag} (${user.id}) has joined the server. Total Members: ${guild.memberCount}`
});
await logHandler.metric("member_join", 1, { userId: user.id, guildId: guild.id });
} catch (err) {
await errorHandler(bot, "on member add", err);
}
+2
View File
@@ -3,6 +3,7 @@ import { GuildMember, PartialGuildMember } from "discord.js";
import { ExtendedClient } from "../../interfaces/ExtendedClient";
import { getConfig } from "../../modules/data/getConfig";
import { errorHandler } from "../../utils/errorHandler";
import { logHandler } from "../../utils/logHandler.js";
/**
* Sends a log message to the configured log channel when a member
@@ -54,6 +55,7 @@ export const onMemberRemove = async (
await channel.send({
content: `${user.tag} (${user.id}) has left the server (joined at ${joinStamp}). Total Members: ${guild.memberCount}`
});
await logHandler.metric("member_leave", 1, { userId: user.id, guildId: guild.id });
} catch (err) {
await errorHandler(bot, "on member remove", err);
}
+2
View File
@@ -3,6 +3,7 @@ import { GuildMember, PartialGuildMember } from "discord.js";
import { ExtendedClient } from "../../interfaces/ExtendedClient";
import { getConfig } from "../../modules/data/getConfig";
import { errorHandler } from "../../utils/errorHandler";
import { logHandler } from "../../utils/logHandler.js";
/**
* Sends a log message to the configured log channel when a member's
@@ -74,6 +75,7 @@ export const onMemberUpdate = async (
)}`
});
}
await logHandler.metric("member_update", 1, { userId: user.id, guildId: guild.id });
} catch (err) {
await errorHandler(bot, "on member update", err);
}
+3
View File
@@ -9,6 +9,7 @@ import { errorHandler } from "../../utils/errorHandler";
import { sendLogMessage } from "../../utils/sendLogMessage";
import { sendModDm } from "../../utils/sendModDm";
import { triggerModRequest } from "../../utils/triggerModRequest";
import { logHandler } from "../../utils/logHandler.js";
const linkRegex = /https?:\/\/([a-zA-Z0-9_.-]{2,256}\.\w{2,24}\b)/g;
@@ -67,6 +68,7 @@ export const onMessage = async (bot: ExtendedClient, message: Message) => {
duration: calculateMuteDuration(24, "hours"),
pruneDays: 0
});
await logHandler.metric("automod_trigger", 1, { userId: author.id, guildId: guild.id });
return;
}
}
@@ -135,6 +137,7 @@ export const onMessage = async (bot: ExtendedClient, message: Message) => {
for (const record of levelRoles) {
await member.roles.add(record.roleId).catch(() => null);
}
await logHandler.metric("message_create", 1, { userId: author.id, guildId: guild.id });
} catch (err) {
await errorHandler(bot, "on message", err);
}
+2
View File
@@ -5,6 +5,7 @@ import { ExtendedClient } from "../../interfaces/ExtendedClient";
import { getConfig } from "../../modules/data/getConfig";
import { customSubstring } from "../../utils/customSubstring";
import { errorHandler } from "../../utils/errorHandler";
import { logHandler } from "../../utils/logHandler.js";
/**
* Handles a message delete event.
@@ -67,6 +68,7 @@ export const onMessageDelete = async (
parse: []
}
});
await logHandler.metric("message_delete", 1, { userId: author?.id ?? "unknown", guildId: guild.id });
} catch (err) {
await errorHandler(bot, "on message delete", err);
}
+2
View File
@@ -5,6 +5,7 @@ import { getConfig } from "../../modules/data/getConfig";
import { customSubstring } from "../../utils/customSubstring";
import { errorHandler } from "../../utils/errorHandler";
import { generateDiff } from "../../modules/events/generateDiff";
import { logHandler } from "../../utils/logHandler.js";
/**
* Handles a message edit event.
@@ -58,6 +59,7 @@ export const onMessageEdit = async (
}>:\`\`\`diff\n${customSubstring(diffContent, 4000)}\n\`\`\``,
allowedMentions: { parse: [] }
});
await logHandler.metric("message_edit", 1, { userId: author?.id ?? "unknown", guildId: guild.id });
} catch (err) {
await errorHandler(bot, "on message edit", err);
}
+2
View File
@@ -3,6 +3,7 @@ import { ThreadChannel } from "discord.js";
import { ExtendedClient } from "../../interfaces/ExtendedClient";
import { getConfig } from "../../modules/data/getConfig";
import { errorHandler } from "../../utils/errorHandler";
import { logHandler } from "../../utils/logHandler.js";
/**
* Handles the creation of a new thread.
@@ -36,6 +37,7 @@ export const onThreadCreate = async (
await channel.send({
content: `${thread.name} has been created in <#${thread.parentId}>`
});
await logHandler.metric("thread_create", 1, { userId: thread.ownerId ?? "unknown", guildId: thread.guild.id });
} catch (err) {
await errorHandler(bot, "on thread create", err);
}
+2
View File
@@ -3,6 +3,7 @@ import { ThreadChannel } from "discord.js";
import { ExtendedClient } from "../../interfaces/ExtendedClient";
import { getConfig } from "../../modules/data/getConfig";
import { errorHandler } from "../../utils/errorHandler";
import { logHandler } from "../../utils/logHandler.js";
/**
* Handles the deletion of a thread.
@@ -32,6 +33,7 @@ export const onThreadDelete = async (
await channel.send({
content: `${thread.name} has been deleted from <#${thread.parentId}>`
});
await logHandler.metric("thread_delete", 1, { userId: thread.ownerId ?? "unknown", guildId: thread.guild.id });
} catch (err) {
await errorHandler(bot, "on thread create", err);
}
+2
View File
@@ -3,6 +3,7 @@ import { ThreadChannel } from "discord.js";
import { ExtendedClient } from "../../interfaces/ExtendedClient";
import { getConfig } from "../../modules/data/getConfig";
import { errorHandler } from "../../utils/errorHandler";
import { logHandler } from "../../utils/logHandler.js";
/**
* Handles a thread update.
@@ -48,6 +49,7 @@ export const onThreadUpdate = async (
content: `${oldThread.name} has been renamed to ${newThread.name} in <#${newThread.parentId}>`
});
}
await logHandler.metric("thread_update", 1, { userId: newThread.ownerId ?? "unknown", guildId: newThread.guild.id });
} catch (err) {
await errorHandler(bot, "on thread update", err);
}
+2
View File
@@ -3,6 +3,7 @@ import { VoiceState } from "discord.js";
import { ExtendedClient } from "../../interfaces/ExtendedClient";
import { getConfig } from "../../modules/data/getConfig";
import { errorHandler } from "../../utils/errorHandler";
import { logHandler } from "../../utils/logHandler.js";
/**
* Handles voice state updates.
@@ -76,6 +77,7 @@ export const onVoiceUpdate = async (
content: `${newVoice.member.user.tag} (${newVoice.member.id}) has been deafened.`
});
}
await logHandler.metric("voice_update", 1, { userId: newVoice.member?.id ?? "unknown", guildId: newVoice.guild.id });
} catch (err) {
await errorHandler(bot, "on voice update", err);
}