/** * sync.ts * Syncs the message reactions in chat with the database, for when the bot is not running. */ import { Client, Collection, Events, GatewayIntentBits, GuildTextBasedChannel, IntentsBitField, Message, MessageReaction, Partials } from 'discord.js'; import { db, clearDb, openDb, reactionEmojis, recordReaction } from './util'; const client = new Client({ intents: [GatewayIntentBits.MessageContent, IntentsBitField.Flags.Guilds, IntentsBitField.Flags.GuildMessages], partials: [Partials.Message, Partials.Channel, Partials.Reaction], }); client.once(Events.ClientReady, async () => { console.log('[bot] Ready.'); for (let i = 0; i < reactionEmojis.length; ++i) console.log(`[bot] config: reaction_${i + 1} = ${reactionEmojis[i]}`); }); async function startup() { console.log("[db] Clearing database..."); clearDb(); console.log("[db] Opening..."); await openDb(); console.log("[db] Migrating..."); await db.migrate(); console.log("[db] Ready."); console.log("[bot] Logging in..."); await client.login(process.env.TOKEN); const guild = await client.guilds.fetch(process.env.GUILD); if (!guild) { console.error(`[bot] FATAL: guild ${guild.id} not found!`); return 1; } console.log(`[bot] Entered guild ${guild.id}`); const channels = await guild.channels.fetch(); const textChannels = > channels.filter(c => c && 'messages' in c && c.isTextBased); for (const [id, textChannel] of textChannels) { console.log(`[bot] Found text channel ${id}`); let before: string = undefined; let messages = new Collection>(); let newMessages: Collection>; try { do { newMessages = await textChannel.messages.fetch({before, limit: 100}); messages = messages.concat(newMessages); console.log(`[bot] [${id}] Fetched ${messages.size} messages (+${newMessages.size})`); if (messages.size > 0) before = messages.last().id; } while (newMessages.size > 0); console.log(`[bot] [${id}] Fetched all messages.`); const reactions = messages.flatMap(m => m.reactions.cache); console.log(`[bot] Found ${reactions.size} reactions`); for (const [_, reaction] of reactions) { await recordReaction(reaction); } console.log(`[bot] [${id}] Finished recording reactions.`); } catch (err) { console.warn(`[bot] [${id}] Failed to fetch messages and reactions: ${err}`); } } process.exit(0); } startup();