···11-import type { ChatInputCommandInteraction } from "discord.js";
22-import type { VoidyClient } from "./VoidyClient";
33-44-interface IHandler<T extends object> {
55- invoke: (data: ChatInputCommandInteraction) => void
66-}
77-88-export abstract class Handler<T extends object> implements IHandler<T> {
99- protected client: VoidyClient;
1010-1111- public constructor(client: VoidyClient) {
1212- this.client = client;
1313- }
1414-1515- public abstract invoke(data: ChatInputCommandInteraction): void
1616-}
+21-4
src/core/VoidyClient.ts
···44 type APIApplicationCommandSubcommandOption,
55 type ApplicationCommandDataResolvable,
66 type ClientOptions,
77+ type Interaction,
78 Client,
89} from "discord.js";
910import { Registry } from "./Registry";
1011import type { Event } from "../loaders/EventLoader";
1212+import type { Command } from "../loaders/CommandLoader";
11131214export class VoidyClient extends Client {
1315 public registries: Registry[];
1616+ public cache: Command[] = [];
14171518 public constructor(options: ClientOptions) {
1619 super(options);
···22252326 public async start(token: string) {
2427 // 1. Prepare commands and events, without registering them
2525- const { commands, events } = await this.initialize();
2828+ const {
2929+ commands,
3030+ commandsJSON,
3131+ events
3232+ } = await this.collectBundledRegistryData();
3333+3434+ // 1.1 Cache collected commands
3535+ this.cache = [...commands];
26362737 // 2. Register event listeners
2838 await this.registerEventHandlers(events);
···3141 await this.login(token);
32423343 // 4. Register/Publish commands
3434- await this.registerCommands(commands);
4444+ await this.registerCommands(commandsJSON);
3545 }
36463737- private async initialize() {
4747+ private async collectBundledRegistryData() {
3848 for (const registry of this.registries) {
3949 // 1. Collecting required registry data
4050 console.info(`[Voidy] Collecting registry data: ${registry.dataSource}`);
···4959 await registry.activate();
5060 }
51616262+ // Only get active registries
5263 const activeRegistries = this.registries
5364 .filter(registry => registry.active);
54656666+ // Collect events from active registries
5567 const events = activeRegistries
5668 .flatMap(registry => registry.events);
57697070+ // Collect raw commands from active registries
5871 const commands = activeRegistries
5972 .flatMap(registry => registry.commands)
7373+7474+ // Collect JSON export of commands from active registries
7575+ const commandsJSON = activeRegistries
7676+ .flatMap(registry => registry.commands)
6077 .flatMap(commands => commands.data.toJSON())
61786262- return { commands, events };
7979+ return { commands, commandsJSON, events };
6380 }
64816582 private async registerEventHandlers(events: Event[]) {
+3-13
src/handlers/CommandHandler.ts
···11import type { ChatInputCommandInteraction } from "discord.js";
22-import { Handler } from "../core/Handler";
32import type { Command } from "../loaders/CommandLoader";
43import type { VoidyClient } from "../core/VoidyClient";
5466-export class CommandHandler extends Handler<Command> {
77- public constructor(
88- client: VoidyClient
99- ) {
1010- super(client);
1111- }
1212-1313- public invoke(data: ChatInputCommandInteraction): void {
1414- console.log(data);
1515- // @Todo: implement invoke method, which fetches command information from registries, based on the command name
1616- //
1717- // @Todo: consider whether we actually need handlers as separate classes, or if we can just give the client a handle method.
55+export class ChatInputCommandHandler {
66+ public static invoke(interaction: ChatInputCommandInteraction, payload: Command, client: VoidyClient): void {
77+ payload.execute(interaction, client);
188 }
199}
+1-5
src/modules/core/commands/ping.ts
···44export default {
55 data: new SlashCommandBuilder()
66 .setName("ping")
77- .setDescription("View the websocket ping between Discord and the Bot.")
88- .addSubcommand(subcommand => subcommand
99- .setName("balls")
1010- .setDescription("A required description")
1111- ),
77+ .setDescription("View the websocket ping between Discord and the Bot."),
128139 execute: async (interaction, client) => {
1410 await interaction.reply({
+26-6
src/modules/core/events/interactionCreate.ts
···11-import { Events, type Interaction } from "discord.js";
11+import { Events, MessageFlags, type Interaction } from "discord.js";
22import type { Event } from "../../../loaders/EventLoader";
33import type { VoidyClient } from "../../../core/VoidyClient";
44-import { CommandHandler } from "../../../handlers/CommandHandler";
44+import { ChatInputCommandHandler } from "../../../handlers/CommandHandler";
5566export default {
77 name: Events.InteractionCreate,
88 execute: async (client: VoidyClient, interaction: Interaction) => {
99- if (!interaction.isChatInputCommand() || !interaction.isCommand()) return null;
99+ if (interaction.isChatInputCommand() && interaction.isCommand()) {
1010+ // Filter the client command cache to locate the invoked command
1111+ const payload = client.cache.filter(commands => commands.data.name === interaction.commandName)[0];
10121111- console.log(interaction.commandName);
1212-1313-1313+ if (!payload) return interaction.reply({
1414+ content: `Sorry, but the command ${interaction.commandName} could not be located in my command cache >:3`,
1515+ flags: [MessageFlags.Ephemeral]
1616+ });
1717+1818+ ChatInputCommandHandler.invoke(interaction, payload, client);
1919+ } else {
2020+ let dmChannel = interaction.user.dmChannel;
2121+2222+ // Attempt DM channel creation, if not found.
2323+ if (!dmChannel) {
2424+ dmChannel = await interaction.user.createDM();
2525+ }
2626+2727+ // If the DM channel is still not available, give up.
2828+ if (!dmChannel || !dmChannel.isSendable()) return;
2929+3030+ dmChannel.send({
3131+ content: `Sorry, but your last interaction wasn't successful and has been logged as an error case, for debugging purposes.\n\nIf you have any additional information to share with us, please communicate with the bot within this DM channel, and we will get in contact.\n\nThank you for understanding, and have a great day :3`,
3232+ })
3333+ }
1434 }
1535} as Event