import { Client, Events, GatewayIntentBits, REST, Routes } from "discord.js"; import { commandExecuteNameHashMap, defineCommands } from "./commands"; import { eventMap } from "./events"; import { OutputHandler } from "../utils/outputHandler"; import { APPLICATION_ID } from "../env"; import { mkdir, readFile, writeFile } from "node:fs/promises"; import { join } from "node:path"; import { cwd } from "node:process"; export class DiscordBot { rest: REST; client: Client; constructor(token: string) { this.client = new Client({ intents: [ GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.GuildVoiceStates, GatewayIntentBits.MessageContent, ], }); this.rest = new REST({ version: "10" }).setToken(token); } public async registerCommands(): Promise { try { if (!this.client.isReady()) { await this.client.once(Events.ClientReady, () => {}); } const commandsCachePath = join(cwd(), "cache", "commands"); await mkdir(commandsCachePath, { recursive: true, }); let commandsCache: { [key: string]: string }; try { commandsCache = JSON.parse( await readFile(join(commandsCachePath, "list.json"), "utf-8"), ); } catch { commandsCache = {}; } for (const [command, id] of Object.entries(commandsCache)) { if (commandExecuteNameHashMap[command]) { continue; } console.log(`sync(delete) command: ${command}(${id})`); await this.deleteCommand(id); } await this.rest.put(Routes.applicationCommands(APPLICATION_ID), { body: defineCommands.map((command) => command.data.toJSON()), }); await writeFile( join(commandsCachePath, "list.json"), JSON.stringify( ( (await this.rest.get( Routes.applicationCommands(APPLICATION_ID), )) as { name: string; id: string; }[] ).reduce>((acc, cur) => { acc[cur.name] = cur.id; return acc; }, {}), null, 2, ), ); } catch (err) { OutputHandler.errorLog("[Command Register Error]", err); } } public async deleteCommand(commandId: string): Promise { if (!this.client.isReady()) throw new Error("Client is not ready"); await this.rest.delete( Routes.applicationCommand(this.client.application.id, commandId), ); } public registerEvents() { try { for (const event of eventMap) { this.client.on(event.event as any, event.callback as any); } } catch (err) { OutputHandler.errorLog("[Event Register Error]", err); } } }