import { AuditLogEvent, Events, Message, PartialMessage } from 'discord.js'; import { Event } from '@/types/EventTypes.js'; import { loadConfig } from '@/util/configLoader.js'; import { addCountingReactions, processCountingMessage, resetCounting, } from '@/util/countingManager.js'; import logAction from '@/util/logging/logAction.js'; import { checkAndAssignLevelRoles, processMessage, } from '@/util/levelingSystem.js'; import { processLevelUpAchievements } from '@/util/achievementManager.js'; export const messageDelete: Event = { name: Events.MessageDelete, execute: async ( message: Omit | PartialMessage>, 'channel'>, ) => { try { if (!message.guild || message.author?.bot) return; const { guild } = message; const auditLogs = await guild.fetchAuditLogs({ type: AuditLogEvent.MessageDelete, limit: 1, }); const executor = auditLogs.entries.first()?.executor; const moderator = executor ? await guild.members.fetch(executor.id) : undefined; await logAction({ guild, action: 'messageDelete', message: message as Message, moderator, }); } catch (error) { console.error('Error handling message delete:', error); } }, }; export const messageUpdate: Event = { name: Events.MessageUpdate, execute: async ( oldMessage: Omit | PartialMessage>, 'channel'>, newMessage: Message, ) => { try { if ( !oldMessage.guild || oldMessage.author?.bot || oldMessage.content === newMessage.content ) { return; } await logAction({ guild: oldMessage.guild, action: 'messageEdit', message: newMessage as Message, oldContent: oldMessage.content ?? '', newContent: newMessage.content ?? '', }); } catch (error) { console.error('Error handling message update:', error); } }, }; export const messageCreate: Event = { name: Events.MessageCreate, execute: async (message: Message) => { try { if (message.author.bot || !message.guild) return; const levelResult = await processMessage(message); const advancementsChannelId = loadConfig().channels.advancements; const advancementsChannel = message.guild?.channels.cache.get( advancementsChannelId, ); if (!advancementsChannel?.isTextBased()) { console.error( 'Advancements channel not found or is not a text channel', ); return; } if (levelResult?.leveledUp) { await advancementsChannel.send( `🎉 Congratulations <@${message.author.id}>! You've leveled up to **Level ${levelResult.newLevel}**!`, ); const assignedRole = await checkAndAssignLevelRoles( message.guild, message.author.id, levelResult.newLevel, ); await processLevelUpAchievements( message.author.id, levelResult.newLevel, message.guild, ); if (assignedRole) { await advancementsChannel.send( `<@${message.author.id}> You've earned the <@&${assignedRole}> role!`, ); } } const countingChannelId = loadConfig().channels.counting; const countingChannel = message.guild?.channels.cache.get(countingChannelId); if (!countingChannel || message.channel.id !== countingChannelId) return; if (!countingChannel.isTextBased()) { console.error('Counting channel not found or is not a text channel'); return; } const result = await processCountingMessage(message); if (result.isValid) { await addCountingReactions(message, result.milestoneType || 'normal'); } else { let errorMessage: string; switch (result.reason) { case 'not_a_number': errorMessage = `${message.author}, that's not a valid number! The count has been reset. The next number should be **1**.`; break; case 'too_high': errorMessage = `${message.author}, too high! The count was **${(result?.expectedCount ?? 0) - 1}** and the next number should have been **${result.expectedCount}**. The count has been reset.`; break; case 'too_low': errorMessage = `${message.author}, too low! The count was **${(result?.expectedCount ?? 0) - 1}** and the next number should have been **${result.expectedCount}**. The count has been reset.`; break; case 'same_user': errorMessage = `${message.author}, you can't count twice in a row! The count has been reset. The next number should be **1**.`; break; default: errorMessage = `${message.author}, something went wrong with the count. The count has been reset. The next number should be **1**.`; } await resetCounting(); await countingChannel.send(errorMessage); await message.react('❌'); } } catch (error) { console.error('Error handling message create: ', error); } }, }; export default [messageCreate, messageDelete, messageUpdate];