yaejunyang/packages/bot/index.ts

99 lines
2.8 KiB
TypeScript

import { Client, Events, GatewayIntentBits, REST, Routes } from "discord.js";
import { commandExecuteNameHashMap, defineCommands } from "./command";
import { eventMap } from "./event";
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<void> {
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<Record<string, string>>((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<void> {
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 (let index = 0; index < eventMap.length; index++) {
const event = eventMap[index];
if (!event) continue;
this.client.on(event.event, event.callback);
}
} catch (err) {
OutputHandler.errorLog("[Event Register Error]", err);
}
}
}