A powerful and extendable Discord bot, with it's own module system :3 thevoid.cafe/projects/voidy

✨ (handlers) deploy commands, add Command class

Jo ba5803e6 d5eb7dbd

+86 -20
+4 -1
deno.json
··· 4 4 }, 5 5 "imports": { 6 6 "@std/assert": "jsr:@std/assert@1", 7 - "discord.js": "npm:discord.js@^14.17.3" 7 + "discord.js": "npm:discord.js@^14.17.3", 8 + "discord-api-types/gateway": "npm:discord-api-types@0.37.118/gateway", 9 + "discord-api-types/rest": "npm:discord-api-types@0.37.118/rest", 10 + "@discord.js/builders": "npm:@discordjs/builders@1.10.0" 8 11 } 9 12 }
+5
deno.lock
··· 4 4 "jsr:@std/assert@1": "1.0.11", 5 5 "jsr:@std/internal@^1.0.5": "1.0.5", 6 6 "npm:@discordjs/builders@1.10.0": "1.10.0", 7 + "npm:@discordjs/rest@2.4.2": "2.4.2", 8 + "npm:discord-api-types@*": "0.37.118", 9 + "npm:discord-api-types@0.37.118": "0.37.118", 7 10 "npm:discord.js@14.17.3": "14.17.3", 8 11 "npm:discord.js@^14.17.3": "14.17.3" 9 12 }, ··· 168 171 "workspace": { 169 172 "dependencies": [ 170 173 "jsr:@std/assert@1", 174 + "npm:@discordjs/builders@1.10.0", 175 + "npm:discord-api-types@0.37.118", 171 176 "npm:discord.js@^14.17.3" 172 177 ] 173 178 }
-17
src/handlers/commandHandler.ts
··· 1 - import { walk } from "https://deno.land/std@0.170.0/fs/walk.ts"; 2 - import { VoidyClient } from "../utils/classes/VoidyClient.ts"; 3 - 4 - export async function handleCommands(client: VoidyClient, path: string = "src/commands") { 5 - for await (const walkEntry of walk(path)) { 6 - if (!walkEntry.isFile) continue; 7 - 8 - const command = (await import(`file://${Deno.cwd()}/${walkEntry.path}`)).default; 9 - 10 - if ("data" in command && "execute" in command) { 11 - client.commands.set(command.data.name, command); 12 - console.log(`[Voidy] Loaded command: ${command.data.name}`); 13 - } else { 14 - console.log(`[Voidy] Command ${walkEntry.path} is missing the "data" or "execute" property.`); 15 - } 16 - } 17 - }
+56
src/handlers/handleCommand.ts
··· 1 + import { walk } from "https://deno.land/std@0.170.0/fs/walk.ts"; 2 + import { VoidyClient } from "../utils/classes/VoidyClient.ts"; 3 + import { Command } from "../utils/classes/Command.ts"; 4 + import { REST, Routes } from "discord.js"; 5 + import { RESTPostAPIChatInputApplicationCommandsJSONBody } from "discord-api-types/rest"; 6 + 7 + export async function handleCommands(client: VoidyClient, path: string = "src/commands") { 8 + console.log(`[Voidy] Loading commands from ${path}...`); 9 + 10 + const commands = []; 11 + 12 + // Iterate through each command found in the specified directory 13 + for await (const walkEntry of walk(path)) { 14 + if (!walkEntry.isFile) continue; 15 + 16 + const command: Command = (await import(`file://${Deno.cwd()}/${walkEntry.path}`)).default; 17 + 18 + if ("data" in command && "execute" in command) { 19 + client.commands.set(command.data.name, command); 20 + commands.push(command.data.toJSON()); 21 + 22 + console.log(`[Voidy] Loaded command: ${command.data.name}`); 23 + } else { 24 + console.log(`[Voidy] Command ${walkEntry.path} is missing the "data" or "execute" property.`); 25 + } 26 + } 27 + 28 + console.log(); 29 + 30 + // Deploy commands to all guilds 31 + await deployCommands(commands); 32 + } 33 + 34 + async function deployCommands(commands: RESTPostAPIChatInputApplicationCommandsJSONBody[]) { 35 + console.log(`[Voidy] Deploying ${commands.length} commands...`); 36 + 37 + // Grab the bot token from the BOT_TOKEN environment variable 38 + const token = Deno.env.get("BOT_TOKEN"); 39 + if (!token) throw new Error("BOT_TOKEN environment variable is missing"); 40 + 41 + // Generate a new instance of the discord.js rest client using the bot token 42 + const rest = new REST().setToken(token); 43 + 44 + // Grab the bot client id from the BOT_CLIENT_ID environment variable 45 + const clientId = Deno.env.get("BOT_CLIENT_ID"); 46 + if (!clientId) throw new Error("BOT_CLIENT_ID environment variable is missing"); 47 + 48 + // Send a put request to the application commands endpoint, the request body contains an array of all commands 49 + await rest.put( 50 + Routes.applicationCommands(clientId), 51 + { body: commands }, 52 + ); 53 + 54 + console.log(`[Voidy] Successfully deployed ${commands.length} commands.`); 55 + console.log(); 56 + }
+18
src/utils/classes/Command.ts
··· 1 + import { SlashCommandBuilder } from "discord.js/builders"; 2 + import { CommandInteraction } from "discord.js"; 3 + import { VoidyClient } from "./VoidyClient.ts"; 4 + 5 + export class Command { 6 + constructor( 7 + options: { 8 + data: SlashCommandBuilder, 9 + execute: (interaction: CommandInteraction, client: VoidyClient) => void 10 + } 11 + ) { 12 + this.data = options.data; 13 + this.execute = options.execute; 14 + } 15 + 16 + public data: SlashCommandBuilder; 17 + public execute: (interaction: CommandInteraction, client: VoidyClient) => void; 18 + }
+3 -2
src/utils/classes/VoidyClient.ts
··· 1 1 import { Client, ClientOptions, Collection } from "discord.js"; 2 + import {Command} from "./Command.ts"; 2 3 3 4 export class VoidyClient extends Client { 4 5 constructor(options: ClientOptions) { 5 6 super(options); 6 7 7 - this.commands = new Collection<string, object>(); 8 + this.commands = new Collection<string, Command>(); 8 9 } 9 10 10 - public commands: Collection<string, object>; 11 + public commands: Collection<string, Command>; 11 12 }