import { Client, Intents, type ClientEvents, type CreateGuildApplicationCommandOptions } from 'oceanic.js' import reactrole from './commands/reactrole.ts' import { reactionKey } from './emoji.ts' import { rosepack } from './rosepack.ts' import { panels } from './store.ts' import { applyReaction, syncPanels } from './sync.ts' const registry = rosepack.createRegistry({ slashCommands: [reactrole] }) const token = process.env.DISCORD_TOKEN const applicationID = process.env.DISCORD_APPLICATION_ID if (token === undefined || applicationID === undefined) { throw new Error('set DISCORD_TOKEN and DISCORD_APPLICATION_ID in .env before starting.') } const client = new Client({ auth: `Bot ${token}`, gateway: { intents: Intents.GUILDS | Intents.GUILD_MESSAGE_REACTIONS } }) client.on('interactionCreate', (interaction) => registry.dispatch({ app: undefined, interaction })) const onReaction = (reacted: boolean) => async (...[message, reactor, reaction]: ClientEvents['messageReactionRemove']) => { const panel = panels.get(message.id) if (panel === undefined || reactionKey(reaction.emoji) !== panel.emoji) return if ('bot' in reactor && reactor.bot) return await applyReaction(client, message.id, panel, reactor.id, reacted) } client.on('messageReactionAdd', onReaction(true)) client.on('messageReactionRemove', onReaction(false)) client.once('ready', async () => { if (client.application.id !== applicationID) { throw new Error('DISCORD_APPLICATION_ID does not match the connected bot application.') } const devGuildID = process.env.DISCORD_DEV_GUILD_ID if (devGuildID !== undefined && devGuildID !== '') { // the registry only holds slash commands, so every payload is guild-installable await client.rest.applications.bulkEditGuildCommands(applicationID, devGuildID, [ ...(registry.payload as readonly CreateGuildApplicationCommandOptions[]) ]) console.log(`registered ${registry.payload.length} commands in dev guild ${devGuildID}`) } else { const registered = await registry.registerGlobal({ applicationID, client }) console.log(`registered ${registered.length} global commands`) } await syncPanels(client) }) await client.connect()