A powerful and extendable Discord bot, with it's own module system :3
thevoid.cafe/projects/voidy
1import type { ChatInputCommandInteraction, Interaction } from "discord.js";
2import { MessageFlags } from "discord.js";
3import type { InteractionStep, InteractionStepContext } from "../../types/Step";
4import type { CommandResource } from "../../types/Resource";
5import { runMiddleware } from "../../types/Middleware";
6import { createContext } from "../../core/context";
7
8export const chatInputStep: InteractionStep = {
9 name: "chatInput",
10
11 match(interaction: Interaction): boolean {
12 return interaction.isChatInputCommand();
13 },
14
15 async handle(interaction: Interaction, { client, cache }: InteractionStepContext): Promise<void> {
16 const i = interaction as ChatInputCommandInteraction;
17
18 let commandId = i.commandName;
19 const subgroup = i.options.getSubcommandGroup(false);
20 if (subgroup) commandId += `.${subgroup}`;
21 const subcommand = i.options.getSubcommand(false);
22 if (subcommand) commandId += `.${subcommand}`;
23
24 const command = cache.get<CommandResource>("command", commandId);
25
26 if (!command) {
27 await i.reply({
28 content: `Sorry, but the command \`${commandId}\` could not be found.`,
29 flags: [MessageFlags.Ephemeral],
30 });
31 return;
32 }
33
34 // Collect option data for logging
35 const data: Record<string, unknown> = {};
36 for (const opt of i.options.data) {
37 if (opt.options) {
38 for (const sub of opt.options) {
39 if (sub.options) {
40 for (const nested of sub.options) {
41 data[nested.name] = nested.value;
42 }
43 } else {
44 data[sub.name] = sub.value;
45 }
46 }
47 } else {
48 data[opt.name] = opt.value;
49 }
50 }
51
52 const lines = [
53 `# ChatInputCommand`,
54 `### Metadata`,
55 `- **Command:** \`${command.id}\``,
56 `- **User:** \`${i.user.tag}\` (${i.user.id})`,
57 `- **Guild:** \`${i.guild?.name ?? "DM"}\` (${i.guildId ?? "N/A"})`,
58 `- **Channel:** <#${i.channelId}>`,
59 `### Data`,
60 "```json",
61 JSON.stringify(data, null, 2),
62 "```",
63 ];
64
65 client.logger.send(lines.join("\n"));
66
67 const ctx = createContext(client, command, i);
68
69 await runMiddleware(command.use, i, client, () => command.execute(ctx));
70 },
71};