const WINDOW_MS = 150_000; // 2.5 minutes const recentPosts = new Map(); function normalizeKey(text) { return text.toLowerCase().replace(/\s+/g, " ").trim().slice(0, 200); } export function trackCrossChannelMessage(guildId, userId, channelId, messageId, text) { const normalized = normalizeKey(text); if (!normalized) { return { duplicateAcrossChannels: false, priorMessages: [] }; } const key = `${guildId}:${userId}:${normalized}`; const now = Date.now(); const existing = recentPosts.get(key); if (existing && now - existing.firstSeen < WINDOW_MS) { const priorMessages = [...existing.messages.entries()].map(([chId, msgId]) => ({ channelId: chId, messageId: msgId, })); existing.channels.add(channelId); existing.messages.set(channelId, messageId); const duplicateAcrossChannels = existing.channels.size >= 2; return { duplicateAcrossChannels, priorMessages: duplicateAcrossChannels ? priorMessages : [] }; } recentPosts.set(key, { channels: new Set([channelId]), messages: new Map([[channelId, messageId]]), firstSeen: now, }); if (recentPosts.size > 5000) { for (const [entryKey, entry] of recentPosts) { if (now - entry.firstSeen > WINDOW_MS) { recentPosts.delete(entryKey); } } } return { duplicateAcrossChannels: false, priorMessages: [] }; }