import type { ApplicationCommandData, Client, Snowflake } from "discord.js"; import { Collection, REST, Routes } from "discord.js"; import cfg from "@/config.ts"; import type { ICommand } from "@/types.ts"; import _logger from "@/utils/logging.ts"; import { crawlDirectory, getHandlerPath } from "./common.ts"; const logger = _logger.child({ name: "interactions" }); export const commands = new Collection(); async function getCommands(): Promise { const processFile = async (fileUrl: string) => { const { default: interaction } = await import(fileUrl); if (!interaction) return; if ( !interaction.data && !interaction.buttonExecute && !interaction.modalExecute ) { logger.info(`${fileUrl} does not have a data property, skipping`); return; } let commandName = interaction.data?.name; if (!commandName) { const urlPath = new URL(fileUrl).pathname; const filename = urlPath.split("/").pop(); commandName = filename?.replace(".ts", ""); } if (!commandName) return; if (interaction.enabled === false) { logger.info(`${commandName} was disabled, skipping`); return; } commands.set(commandName, interaction); return interaction; }; return await crawlDirectory( getHandlerPath("interactions"), processFile, ); } async function registerInteractions( client: Client, interactions: ApplicationCommandData[], ) { if (!client.user) return logger.error("client user is not available"); if (!client.application) return logger.error("client application is not available"); if (interactions.length === 0) return; logger.info("registering interactions..."); const rest = new REST({ version: "9" }).setToken(cfg.data.discord.token); try { logger.info("registering commands..."); await rest.put(Routes.applicationCommands(client.user.id), { body: interactions, }); logger.info(`registered ${interactions.length} commands`); } catch (error) { logger.error(error, "failed to register commands"); } } async function registerCommands(client: Client) { await getCommands(); const slashCommands = commands .map((command) => command.data) .filter((data): data is ApplicationCommandData => !!data); if (slashCommands.length === 0) return logger.warn("no commands found"); await registerInteractions(client, slashCommands); } export default registerCommands;