diff options
13 files changed, 85 insertions, 69 deletions
diff --git a/packages/gateway/src/listeners/channelDeletion.ts b/packages/gateway/src/listeners/channelDeletion.ts index 07aa139..37c9052 100644 --- a/packages/gateway/src/listeners/channelDeletion.ts +++ b/packages/gateway/src/listeners/channelDeletion.ts @@ -1,6 +1,7 @@ import { Client, Events } from "discord.js"; import { CENTRAL_GUILD_ID, DISCORD_AUDIT_LOG_TYPES } from "../constants"; import { logUnexpectedDiscordAPIError } from "../utilities"; +import { logUnexpectedDiscordAPIResult } from "../../../shared/log"; const channelDeletionTracker = new Map< string, @@ -48,19 +49,19 @@ export const handleChannelDeletion = (client: Client) => { userData = { count: 1, firstDeletion: now }; channelDeletionTracker.set(executor.id, userData); - console.warn( + logUnexpectedDiscordAPIResult( `User ${executor.tag} (${executor.id}) deleted first channel`, ); } else { if (now - userData.firstDeletion <= thirtySeconds) { userData.count += 1; - console.warn( + logUnexpectedDiscordAPIResult( `User ${executor.tag} (${executor.id}) deleted channel ${userData.count}/2 within 30 seconds`, ); if (userData.count > 2) { - console.warn( + logUnexpectedDiscordAPIResult( `User ${executor.tag} (${executor.id}) exceeded channel deletion limit, resetting roles`, ); @@ -74,7 +75,7 @@ export const handleChannelDeletion = (client: Client) => { if (rolesToRemove.size > 0) { await member.roles.set([]); - console.warn( + logUnexpectedDiscordAPIResult( `Reset ${rolesToRemove.size} roles for user ${executor.tag}`, ); } @@ -89,7 +90,7 @@ export const handleChannelDeletion = (client: Client) => { userData.count = 1; userData.firstDeletion = now; - console.warn( + logUnexpectedDiscordAPIResult( `User ${executor.tag} (${executor.id}) deleted channel, resetting counter (outside 30s window)`, ); } diff --git a/packages/gateway/src/listeners/messageCreate/aiCommandHandler/index.ts b/packages/gateway/src/listeners/messageCreate/aiCommandHandler/index.ts index 893c3b3..1f6c918 100644 --- a/packages/gateway/src/listeners/messageCreate/aiCommandHandler/index.ts +++ b/packages/gateway/src/listeners/messageCreate/aiCommandHandler/index.ts @@ -2,6 +2,8 @@ import { Message } from "discord.js"; import OpenAI from "openai"; import { handleSlowmodeCommand } from "./slowmode.js"; import { handlePurgeCommand } from "./purge.js"; +import { logUnexpectedDiscordAPIError } from "../../../utilities"; +import { logUnexpectedAIError } from "../../../../../shared/log.js"; const MODERATOR_ROLE_IDS = [ "1406422617765712095", @@ -144,7 +146,7 @@ RESPONSE MUST BE ONLY JSON. NO OTHER TEXT.`, const aiResponse = completion.choices?.[0]?.message?.content?.trim(); if (!aiResponse) { - console.error("No response from OpenRouter"); + logUnexpectedAIError("No response from OpenRouter"); return; } @@ -154,14 +156,16 @@ RESPONSE MUST BE ONLY JSON. NO OTHER TEXT.`, try { commandData = JSON.parse(aiResponse); } catch { - console.error("Failed to parse AI response as JSON:", aiResponse); + logUnexpectedAIError( + `Failed to parse AI response as JSON: ${aiResponse}`, + ); return; } await executeAICommand(message, commandData); } catch (error) { - console.error("Error in AI command handler:", error); + logUnexpectedDiscordAPIError(error); } }; diff --git a/packages/gateway/src/listeners/messageCreate/aiCommandHandler/purge.ts b/packages/gateway/src/listeners/messageCreate/aiCommandHandler/purge.ts index fc06b81..c7e4a38 100644 --- a/packages/gateway/src/listeners/messageCreate/aiCommandHandler/purge.ts +++ b/packages/gateway/src/listeners/messageCreate/aiCommandHandler/purge.ts @@ -1,11 +1,12 @@ import { Message, Collection } from "discord.js"; import { AICommandResponse } from "./index"; +import { logUnexpectedDiscordAPIError } from "../../../utilities"; const safeReact = async (message: Message, emoji: string) => { try { await message.react(emoji); } catch (reactError) { - console.log("Could not react to message (likely deleted):", reactError); + logUnexpectedDiscordAPIError(reactError); } }; @@ -178,18 +179,18 @@ export const handlePurgeCommand = async ( for (let i = 0; i < messagesToDelete.length; i += 100) batches.push(messagesToDelete.slice(i, i + 100)); - for (const batch of batches) - if (batch.length === 1) { - await batch[0].delete(); + for (const messageBatch of batches) + if (messageBatch.length === 1) { + await messageBatch[0].delete(); } else if ("bulkDelete" in channel) { - await (channel as any).bulkDelete(batch); + await (channel as any).bulkDelete(messageBatch); } else { - for (const msg of batch) await msg.delete(); + for (const message of messageBatch) await message.delete(); } await safeReact(message, "✅"); } catch (error) { - console.error("Error purging messages:", error); + logUnexpectedDiscordAPIError(error); await safeReact(message, "❌"); } }; diff --git a/packages/gateway/src/listeners/messageCreate/aiCommandHandler/slowmode.ts b/packages/gateway/src/listeners/messageCreate/aiCommandHandler/slowmode.ts index d23e70c..1f3ce44 100644 --- a/packages/gateway/src/listeners/messageCreate/aiCommandHandler/slowmode.ts +++ b/packages/gateway/src/listeners/messageCreate/aiCommandHandler/slowmode.ts @@ -1,5 +1,6 @@ import { Message } from "discord.js"; import { AICommandResponse } from "./index"; +import { logUnexpectedDiscordAPIError } from "../../../utilities"; export const handleSlowmodeCommand = async ( message: Message, @@ -41,7 +42,7 @@ export const handleSlowmodeCommand = async ( await (channel as any).setRateLimitPerUser(newSlowmode); await message.react("✅"); } catch (error) { - console.error("Error setting slowmode:", error); + logUnexpectedDiscordAPIError(error); await message.react("❌"); } }; diff --git a/packages/gateway/src/listeners/messageCreate/artMediaModeration.ts b/packages/gateway/src/listeners/messageCreate/artMediaModeration.ts index 177a930..c75cc0f 100644 --- a/packages/gateway/src/listeners/messageCreate/artMediaModeration.ts +++ b/packages/gateway/src/listeners/messageCreate/artMediaModeration.ts @@ -3,6 +3,7 @@ import { ART_MEDIA_NSFW_CHANNEL_ID, NSFW_DISCUSSION_CHANNEL_ID, } from "../constants"; +import { logUnexpectedDiscordAPIError } from "../../utilities"; export const handleArtMediaModeration = async (message: Message) => { if (message.channelId !== ART_MEDIA_NSFW_CHANNEL_ID) return; @@ -32,13 +33,10 @@ export const handleArtMediaModeration = async (message: Message) => { try { await errorMessage.delete(); } catch (error) { - console.error( - "Failed to delete art media moderation error message:", - error, - ); + logUnexpectedDiscordAPIError(error); } }, 30000); } catch (error) { - console.error("Error in art media moderation:", error); + logUnexpectedDiscordAPIError(error); } }; diff --git a/packages/gateway/src/listeners/messageCreate/dailyConversationStarter.ts b/packages/gateway/src/listeners/messageCreate/dailyConversationStarter.ts index 2b295ad..d7cfb6e 100644 --- a/packages/gateway/src/listeners/messageCreate/dailyConversationStarter.ts +++ b/packages/gateway/src/listeners/messageCreate/dailyConversationStarter.ts @@ -3,6 +3,8 @@ import { UMA_PERSONAS } from "../../constants"; import { sendPersonaLog } from "../../commands/utilities"; import { CONVERSATION_MIDDLES } from "./constants"; import { generatePersonaMessage } from "./utilities"; +import { logUnexpectedDiscordAPIError } from "../../utilities"; +import { logUnexpectedDiscordAPIResult } from "../../../../shared/log"; const ENABLED_PRIMER_MESSAGE = false; const TARGET_CHANNEL_ID = "1406422619087044675"; @@ -57,10 +59,7 @@ class DailyConversationStarterSystem { } } } catch (error) { - console.error( - "Failed to initialize persistent conversation starter webhook:", - error, - ); + logUnexpectedDiscordAPIError(error); } } @@ -75,8 +74,8 @@ class DailyConversationStarterSystem { ); if (!this.webhookClient) { - console.error( - "Failed to send conversation starter primer message - webhook not initialized", + logUnexpectedDiscordAPIResult( + "Failed to send conversation starter primer message. Webhook not initialised in target channel", ); return; @@ -100,10 +99,7 @@ class DailyConversationStarterSystem { this.tracker.lastMessageTime = Date.now(); } catch (error) { - console.error( - "Failed to send conversation starter primer message:", - error, - ); + logUnexpectedDiscordAPIError(error); } } @@ -136,8 +132,8 @@ class DailyConversationStarterSystem { ); if (!this.webhookClient) { - console.error( - "Failed to send conversation starter message - webhook not initialized", + logUnexpectedDiscordAPIResult( + "Failed to send conversation starter message. Webhook not initialised in target channel", ); return; @@ -161,7 +157,7 @@ class DailyConversationStarterSystem { this.tracker.lastMessageTime = Date.now(); } catch (error) { - console.error("Failed to send conversation starter message:", error); + logUnexpectedDiscordAPIError(error); } } diff --git a/packages/gateway/src/listeners/messageCreate/dmForwarder.ts b/packages/gateway/src/listeners/messageCreate/dmForwarder.ts index d9c7ee1..5a3f3a3 100644 --- a/packages/gateway/src/listeners/messageCreate/dmForwarder.ts +++ b/packages/gateway/src/listeners/messageCreate/dmForwarder.ts @@ -1,4 +1,6 @@ import { Message } from "discord.js"; +import { logUnexpectedDiscordAPIError } from "../../utilities"; +import { logUnexpectedDiscordAPIResult } from "../../../../shared/log"; const DM_FORWARD_CHANNEL_ID = "1430036877120897044"; const TRIGGER_STRING = "tracen_academy_trainer_oc"; @@ -20,13 +22,15 @@ export const handleDmForwarder = async (message: Message) => { !forwardChannel.isTextBased() || forwardChannel.isDMBased() ) { - console.error("DM forward channel not found or not accessible"); + logUnexpectedDiscordAPIResult( + "DM forward channel not found or not accessible", + ); return; } await forwardChannel.send(`<@${message.author.id}>\n\n${message.content}`); } catch (error) { - console.error("Failed to forward DM:", error); + logUnexpectedDiscordAPIError(error); } }; diff --git a/packages/gateway/src/listeners/messageCreate/iqdbModeration.ts b/packages/gateway/src/listeners/messageCreate/iqdbModeration.ts index dff2896..6122778 100644 --- a/packages/gateway/src/listeners/messageCreate/iqdbModeration.ts +++ b/packages/gateway/src/listeners/messageCreate/iqdbModeration.ts @@ -1,5 +1,6 @@ import { Message } from "discord.js"; import { sendAuditLog } from "../../commands/utilities"; +import { log, logUnexpectedDiscordAPIError } from "../../utilities"; const IQDB_MODERATION_CHANNEL_IDS = [ "1410333697701314791", @@ -118,7 +119,7 @@ export const handleIqdbModeration = async (message: Message) => { const similarity = match.similarity!; const isHighConfidence = similarity > 0.75; - console.warn( + log( `Prohibited tags detected: ${foundProhibitedTags.join(", ")}, similarity: ${(similarity * 100).toFixed(1)}%, ${isHighConfidence ? "deleting message" : "sending notification"}`, ); @@ -188,7 +189,7 @@ export const handleIqdbModeration = async (message: Message) => { }); } } catch (error) { - console.error("Error sending image attachment:", error); + logUnexpectedDiscordAPIError(error); await sendAuditLog( message.client, @@ -201,22 +202,19 @@ export const handleIqdbModeration = async (message: Message) => { return; } } catch (error) { - console.error( - `Error fetching tags from ${booruType}:`, - error, - ); + logUnexpectedDiscordAPIError(error); } } } catch (error) { - console.error("Error processing booru match:", error); + logUnexpectedDiscordAPIError(error); } } } } catch (error) { - console.error("Error processing image attachment:", error); + logUnexpectedDiscordAPIError(error); } } } catch (error) { - console.error("Error in iqdb moderation:", error); + logUnexpectedDiscordAPIError(error); } }; diff --git a/packages/gateway/src/listeners/messageCreate/personaRandomMessage.ts b/packages/gateway/src/listeners/messageCreate/personaRandomMessage.ts index a9211ef..2e2704f 100644 --- a/packages/gateway/src/listeners/messageCreate/personaRandomMessage.ts +++ b/packages/gateway/src/listeners/messageCreate/personaRandomMessage.ts @@ -7,6 +7,8 @@ import { PERSONA_REPLY_SECOND_PARTS, } from "./constants"; import { generatePersonaMessage } from "./utilities"; +import { logUnexpectedDiscordAPIError } from "../../utilities"; +import { logUnexpectedDiscordAPIResult } from "../../../../shared/log"; const ENABLED_PRIMER_MESSAGE = false; const TARGET_CHANNEL_ID = "1410333697701314791"; @@ -73,7 +75,7 @@ class PersonaRandomMessageSystem { } } } catch (error) { - console.error("Failed to initialize persistent persona webhook:", error); + logUnexpectedDiscordAPIError(error); } } @@ -88,8 +90,8 @@ class PersonaRandomMessageSystem { ); if (!this.webhookClient) { - console.error( - "Failed to send primer message - webhook not initialized", + logUnexpectedDiscordAPIResult( + "Failed to send primer message. Webhook not initialised in target channel", ); return; @@ -116,7 +118,7 @@ class PersonaRandomMessageSystem { this.tracker.lastPersonaAvatar = randomPersona.avatar; this.tracker.hasReplied = false; } catch (error) { - console.error("Failed to send primer persona message:", error); + logUnexpectedDiscordAPIError(error); } } @@ -161,8 +163,8 @@ class PersonaRandomMessageSystem { ); if (!this.webhookClient) { - console.error( - "Failed to send persona message - webhook not initialized", + logUnexpectedDiscordAPIResult( + "Failed to send persona message. Webhook not initialised in target channel", ); return; @@ -191,14 +193,16 @@ class PersonaRandomMessageSystem { this.tracker.lastPersonaAvatar = randomPersona.avatar; this.tracker.hasReplied = false; } catch (error) { - console.error("Failed to send persona message:", error); + logUnexpectedDiscordAPIError(error); } } private async handleReplyToPersona(): Promise<void> { try { if (!this.webhookClient) { - console.error("Failed to reply to persona - webhook not initialized"); + logUnexpectedDiscordAPIResult( + "Failed to reply to persona. Webhook not initialised in target channel", + ); return; } @@ -232,7 +236,7 @@ class PersonaRandomMessageSystem { this.tracker.hasReplied = true; } catch (error) { - console.error("Failed to send persona reply:", error); + logUnexpectedDiscordAPIError(error); } } diff --git a/packages/gateway/src/listeners/messageCreate/randomEyesReaction.ts b/packages/gateway/src/listeners/messageCreate/randomEyesReaction.ts index 5a7ddfd..fac73d5 100644 --- a/packages/gateway/src/listeners/messageCreate/randomEyesReaction.ts +++ b/packages/gateway/src/listeners/messageCreate/randomEyesReaction.ts @@ -5,6 +5,7 @@ import { CENTRAL_UMABOT_CHANNEL_ID, } from "../../constants"; import { sendPersonaLog } from "../../commands/utilities"; +import { logUnexpectedDiscordAPIError } from "../../utilities"; const EYES_REACTION_CHANNELS = [ CENTRAL_ART_MEDIA_CHANNEL_ID, @@ -25,6 +26,6 @@ export const handleRandomEyesReaction = async (message: Message) => { const messageLink = `https://discord.com/channels/${message.guildId}/${message.channelId}/${message.id}`; await sendPersonaLog(message.client, "reaction", "Bot", messageLink, false); } catch (error) { - console.error("Failed to add :eyes: reaction:", error); + logUnexpectedDiscordAPIError(error); } }; diff --git a/packages/gateway/src/listeners/messageCreate/roleMentionCooldown.ts b/packages/gateway/src/listeners/messageCreate/roleMentionCooldown.ts index 80b06e1..fb0503d 100644 --- a/packages/gateway/src/listeners/messageCreate/roleMentionCooldown.ts +++ b/packages/gateway/src/listeners/messageCreate/roleMentionCooldown.ts @@ -3,6 +3,10 @@ import { CENTRAL_REVIVE_ROLEPLAY_ROLE_ID, CENTRAL_REVIVE_CHAT_ROLE_ID, } from "../../constants"; +import { + logUnexpectedDiscordAPIError, + logUnexpectedDiscordAPIResult, +} from "../../../../shared/log"; const COOLDOWN_ROLES = [ CENTRAL_REVIVE_ROLEPLAY_ROLE_ID, @@ -23,7 +27,9 @@ const sendRevivePingLog = async ( ); if (!logChannel || !logChannel.isTextBased() || logChannel.isDMBased()) { - console.error("Revive ping log channel not found or not text-based"); + logUnexpectedDiscordAPIResult( + "Revive ping log channel not found or not text-based", + ); return; } @@ -45,7 +51,7 @@ const sendRevivePingLog = async ( await logChannel.send({ embeds: [embed] }); } catch (error) { - console.error("Failed to send revive ping log:", error); + logUnexpectedDiscordAPIError(error); } }; @@ -76,7 +82,7 @@ export const handleRoleMentionCooldown = async (message: Message) => { try { await notification.delete(); } catch (error) { - console.error("Failed to delete cooldown notification:", error); + logUnexpectedDiscordAPIError(error); } }, 10000); @@ -94,17 +100,11 @@ export const handleRoleMentionCooldown = async (message: Message) => { await role.setMentionable(true, "Role mention cooldown expired"); roleCooldowns.delete(role.id); } catch (error) { - console.error( - `Failed to re-enable mention permissions for role ${role.name}:`, - error, - ); + logUnexpectedDiscordAPIError(error); } }, COOLDOWN_DURATION); } catch (error) { - console.error( - `Failed to disable mention permissions for role ${role.name}:`, - error, - ); + logUnexpectedDiscordAPIError(error); } } }; diff --git a/packages/gateway/src/listeners/messageCreate/roleplayUmagram.ts b/packages/gateway/src/listeners/messageCreate/roleplayUmagram.ts index e17674e..faae900 100644 --- a/packages/gateway/src/listeners/messageCreate/roleplayUmagram.ts +++ b/packages/gateway/src/listeners/messageCreate/roleplayUmagram.ts @@ -5,6 +5,7 @@ import { CENTRAL_UMAGRAM_CHANNEL_ID, ROLEPLAY_UMAGRAM_CHANNEL_ID, } from "../../constants"; +import { logUnexpectedDiscordAPIError } from "../../utilities"; const GUILD_UMAGRAM_CHANNELS = { [CENTRAL_GUILD_ID]: CENTRAL_UMAGRAM_CHANNEL_ID, @@ -31,7 +32,7 @@ export const handleRoleplayUmagram = async (message: Message) => { try { await message.react("❤️"); } catch (error) { - console.error("Failed to add heart reaction:", error); + logUnexpectedDiscordAPIError(error); } if (isMainChannel && !message.reference) { @@ -50,12 +51,12 @@ export const handleRoleplayUmagram = async (message: Message) => { try { await errorMessage.delete(); } catch (error) { - console.error("Failed to delete error message:", error); + logUnexpectedDiscordAPIError(error); } }, 30000); } } } catch (error) { - console.error("Error in roleplay-umagram moderation:", error); + logUnexpectedDiscordAPIError(error); } }; diff --git a/packages/shared/log.ts b/packages/shared/log.ts index 04c516e..92ab735 100644 --- a/packages/shared/log.ts +++ b/packages/shared/log.ts @@ -46,3 +46,10 @@ export const logUnexpectedDiscordAPIResult = (error: unknown) => { LogLevel.Error, ); }; + +export const logUnexpectedAIError = (error: unknown) => { + log( + `Unexpected AI error: ${error instanceof Error ? error.message : String(error)}`, + LogLevel.Error, + ); +}; |