Discord bot to open dong files
1import {
2 ChatInputCommandInteraction,
3 Client,
4 Collection,
5 Events,
6 GatewayIntentBits,
7 MessageFlags,
8 type Interaction,
9} from "discord.js";
10// import { Glob } from "bun";
11import { glob } from "glob";
12import "dotenv/config";
13import path from "node:path";
14
15const token = process.env.token;
16if (!token) throw new Error("Token required. Please fill in TOKEN in .env");
17console.log("Token Valid!");
18
19const __dirname = import.meta.dirname;
20
21// client typing
22export type customClient = Client & {
23 // add command typing
24 commands: Collection<
25 string,
26 {
27 data: { name: string };
28 execute: (
29 interaction: ChatInputCommandInteraction & { client: customClient }
30 ) => Promise<void>;
31 }
32 >;
33};
34// new client
35const client: customClient = new Client({
36 intents: [GatewayIntentBits.Guilds],
37 // as customclient as i cannot add .commands till this is done
38}) as customClient;
39
40// setup commands
41client.commands = new Collection();
42// const commandGlob = new Glob("**/*.ts");
43for (const file of await glob("src/commands/**/*.ts", {
44 ignore: "node_modules",
45})) {
46 const command = await import("file:///" + path.join(__dirname, "..", file));
47 // check command contains all required properties
48 if (
49 "data" in command &&
50 "execute" in command &&
51 typeof command.data === "object" &&
52 command.data !== null &&
53 "name" in command.data &&
54 typeof command.data.name === "string"
55 ) {
56 client.commands.set(command.data.name, command);
57 console.log("[loaded]", file);
58 } else {
59 // log missing features
60 console.log(`[WARNING] ${file} is not a valid command!`, command);
61 }
62}
63
64// when client is ready do this once
65client.once(Events.ClientReady, (ready) => {
66 console.log(`Ready! Logged in as ${ready.user.tag}`);
67});
68
69// _interaction so we can cast types properly
70// we need access to client.commands
71// we could just do it as a global but this makes it go wherever the command goes soooo
72client.on(Events.InteractionCreate, async (_interaction) => {
73 const interaction = _interaction as Interaction & { client: customClient };
74 if (!interaction.isChatInputCommand()) return;
75 const command = interaction.client.commands.get(interaction.commandName);
76 if (!command) {
77 console.error(`No command ${interaction.commandName}`);
78 return;
79 }
80
81 try {
82 await command.execute(interaction);
83 } catch (e) {
84 console.error(e);
85 if (interaction.replied || interaction.deferred) {
86 await interaction.followUp({
87 content: "There was an error while executing this command!",
88 flags: MessageFlags.Ephemeral,
89 });
90 } else {
91 await interaction.reply({
92 content: "There was an error while executing this command!",
93 flags: MessageFlags.Ephemeral,
94 });
95 }
96 }
97});
98
99client.login(token);