diff options
| author | Fuwn <[email protected]> | 2025-10-23 23:59:54 -0700 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2025-10-24 00:00:49 -0700 |
| commit | 454d848c43aa8223118ea5982adfbb36681dd765 (patch) | |
| tree | a969c5317b05f9f804c2ed198b042ec98a9c9cb1 /packages/gateway/src/database | |
| parent | feat(gateway:listeners): Add role persistence (diff) | |
| download | umabotdiscord-454d848c43aa8223118ea5982adfbb36681dd765.tar.xz umabotdiscord-454d848c43aa8223118ea5982adfbb36681dd765.zip | |
feat(gateway:listeners): Add emoji and sticker usage tracking
Diffstat (limited to 'packages/gateway/src/database')
| -rw-r--r-- | packages/gateway/src/database/emojiUsageTracker.ts | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/packages/gateway/src/database/emojiUsageTracker.ts b/packages/gateway/src/database/emojiUsageTracker.ts new file mode 100644 index 0000000..604e8a6 --- /dev/null +++ b/packages/gateway/src/database/emojiUsageTracker.ts @@ -0,0 +1,178 @@ +import { Message } from "discord.js"; +import prisma from "./prisma"; +import { logUnexpectedDiscordAPIError } from "../utilities"; + +export class EmojiUsageTracker { + static async trackEmojiUsage(message: Message): Promise<void> { + if (!message.guild) return; + + try { + const guildId = message.guild.id; + const customEmojiRegex = /<a?:(\w+):(\d+)>/g; + const matches = message.content.matchAll(customEmojiRegex); + + for (const match of matches) { + const emojiName = match[1]; + const emojiId = match[2]; + const emoji = message.guild.emojis.cache.get(emojiId); + + if (!emoji) continue; + + await this.recordEmojiUsage(guildId, emojiId, emojiName); + } + + if (message.reactions.cache.size > 0) + for (const reaction of message.reactions.cache.values()) { + const emoji = reaction.emoji; + + if (emoji.id && message.guild.emojis.cache.has(emoji.id)) + await this.recordEmojiUsage( + guildId, + emoji.id, + emoji.name || "unknown", + ); + } + } catch (error) { + logUnexpectedDiscordAPIError(error); + } + } + + static async trackStickerUsage(message: Message): Promise<void> { + if (!message.guild) return; + + try { + const guildId = message.guild.id; + + for (const sticker of message.stickers.values()) + if (sticker.guildId === guildId) + await this.recordStickerUsage(guildId, sticker.id, sticker.name); + } catch (error) { + logUnexpectedDiscordAPIError(error); + } + } + + private static async recordEmojiUsage( + guildId: string, + emojiId: string, + emojiName: string, + ): Promise<void> { + try { + const existing = await prisma.emojiUsage.findUnique({ + where: { + guildId_emojiId: { + guildId, + emojiId, + }, + }, + }); + + if (existing) { + await prisma.emojiUsage.update({ + where: { + guildId_emojiId: { + guildId, + emojiId, + }, + }, + data: { + usageCount: existing.usageCount + 1, + lastUsed: new Date(), + }, + }); + } else { + await prisma.emojiUsage.create({ + data: { + guildId, + emojiId, + emojiName, + usageCount: 1, + firstUsed: new Date(), + lastUsed: new Date(), + }, + }); + } + } catch (error) { + logUnexpectedDiscordAPIError(error); + } + } + + private static async recordStickerUsage( + guildId: string, + stickerId: string, + stickerName: string, + ): Promise<void> { + try { + const existing = await prisma.stickerUsage.findUnique({ + where: { + guildId_stickerId: { + guildId, + stickerId, + }, + }, + }); + + if (existing) { + await prisma.stickerUsage.update({ + where: { + guildId_stickerId: { + guildId, + stickerId, + }, + }, + data: { + usageCount: existing.usageCount + 1, + lastUsed: new Date(), + }, + }); + } else { + await prisma.stickerUsage.create({ + data: { + guildId, + stickerId, + stickerName, + usageCount: 1, + firstUsed: new Date(), + lastUsed: new Date(), + }, + }); + } + } catch (error) { + logUnexpectedDiscordAPIError(error); + } + } + + static async getEmojiStats(guildId: string, limit: number = 50) { + try { + return await prisma.emojiUsage.findMany({ + where: { guildId }, + orderBy: { usageCount: "desc" }, + take: limit, + }); + } catch (error) { + logUnexpectedDiscordAPIError(error); + + return []; + } + } + + static async getStickerStats(guildId: string, limit: number = 50) { + try { + return await prisma.stickerUsage.findMany({ + where: { guildId }, + orderBy: { usageCount: "desc" }, + take: limit, + }); + } catch (error) { + logUnexpectedDiscordAPIError(error); + + return []; + } + } + + // static async cleanupDeletedAssets(guildId: string): Promise<void> { + // try { + // } catch (error) { + // logUnexpectedDiscordAPIError(error); + // } + // } +} |