import { WebhookClient } from "discord.js"; import { Notification } from "../../../notifications/types"; import { ChatbotChannel } from "../schemas/ChatbotChannel"; import { ChatbotRepository, type IChatbotProfile, type IChatbotMessage } from "../schemas/ChatbotRepository"; function processTemplate(content: string): string { return content.replace(//g, String(Math.floor(Math.random() * 12) + 1)); } function pickRandom(arr: T[]): T | undefined { if (arr.length === 0) return undefined; return arr[Math.floor(Math.random() * arr.length)]; } function getMessageForProfile( profile: IChatbotProfile, globalMessages: IChatbotMessage[], ): string | undefined { if (profile.onlySendSpecified) { const msg = pickRandom(profile.messages); return msg?.content; } const msg = pickRandom(globalMessages); return msg?.content; } export default new Notification({ id: "chatbot", execute: async ({ data }) => { const channelId = data.channelId as string; const channelConfig = await ChatbotChannel.findOne({ channelId, enabled: true }); if (!channelConfig) return; // Resolve repository based on mode let repository; if (channelConfig.mode === "local" && channelConfig.repositoryId) { repository = await ChatbotRepository.findById(channelConfig.repositoryId); } else { repository = await ChatbotRepository.findOne({ scope: "global" }); } if (!repository || repository.messages.length === 0 || repository.profiles.length === 0) return; const profile = pickRandom(repository.profiles); if (!profile) return; const content = getMessageForProfile(profile, repository.messages); if (!content) return; const webhook = new WebhookClient({ id: channelConfig.webhookId, token: channelConfig.webhookToken, }); try { await webhook.send({ content: processTemplate(content), username: profile.name, avatarURL: profile.avatarURL, }); await ChatbotChannel.updateOne( { channelId }, { $set: { lastSentAt: new Date() } }, ); } finally { webhook.destroy(); } }, });