feat: Add command cache(auto deleate command)

This commit is contained in:
kimpure 2026-02-15 11:49:21 +00:00
parent da148bdf2b
commit b12b3c2e2e
3 changed files with 42 additions and 20 deletions

View file

@ -34,8 +34,8 @@ export function defineCommand(
} }
} }
export const commandDirectory = join(__dirname, "commands"); const commandDirectory = join(__dirname, "commands");
export const commandMap = requireDirectorySync<DiscordCommand>(commandDirectory); export const defineCommands = requireDirectorySync<DiscordCommand>(commandDirectory);
export const commandExecuteNameHashMap: { export const commandExecuteNameHashMap: {
[key: string]: DiscordCommandExecute [key: string]: DiscordCommandExecute
} = Object.fromEntries(commandMap.map(command => [command.data.name, command.execute])); } = Object.fromEntries(defineCommands.map(command => [command.data.name, command.execute]));

View file

@ -1,7 +1,11 @@
import { Client, Events, GatewayIntentBits, REST, Routes } from "discord.js"; import { Client, Events, GatewayIntentBits, REST, Routes } from "discord.js";
import { commandMap, DiscordCommand } from "./command"; import { commandExecuteNameHashMap, defineCommands, DiscordCommand } from "./command";
import { eventMap } from "./event"; import { eventMap } from "./event";
import { OutputHandler } from "../utils/outputHandler"; 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 { export class DiscordBot {
rest: REST; rest: REST;
@ -19,25 +23,44 @@ export class DiscordBot {
this.rest = new REST({ version: "10" }).setToken(token); this.rest = new REST({ version: "10" }).setToken(token);
} }
private async putCommands(commands: DiscordCommand[]): Promise<void> {
if (!this.client.isReady())
throw new Error("Client is not ready");
await this.rest.put(
Routes.applicationCommands(this.client.application.id),
{
body: commands.map((command) => command.data.toJSON()),
}
);
}
public async registerCommands(): Promise<void> { public async registerCommands(): Promise<void> {
try { try {
if (!this.client.isReady()) { if (!this.client.isReady()) {
await this.client.once(Events.ClientReady, () => this.putCommands(commandMap)); await this.client.once(Events.ClientReady, () => {});
} else {
await this.putCommands(commandMap);
} }
const commandsCachePath = join(cwd(), "cache", "commands");
await mkdir(commandsCachePath);
const commandsCache: { [key: string]: string } = JSON.parse(await readFile(join(commandsCachePath, "list.json"), "utf-8") || "{}");
for (const [command, id] of Object.entries(commandsCache)) {
if (commandExecuteNameHashMap[command]) {
continue;
}
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;
}, {})
)
);
} catch(err) { } catch(err) {
OutputHandler.errorLog("[Command Register Error]", err); OutputHandler.errorLog("[Command Register Error]", err);
} }

View file

@ -1,7 +1,6 @@
import { Routes } from "discord.js"; import { Routes } from "discord.js";
import { DiscordBot } from "./bot"; import { DiscordBot } from "./bot";
import { APPLICATION_ID, DISCORD_TOKEN } from "./env"; import { APPLICATION_ID, DISCORD_TOKEN } from "./env";
import remove from "./cli/remove_command";
export const bot = new DiscordBot(DISCORD_TOKEN); export const bot = new DiscordBot(DISCORD_TOKEN);