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

Compare changes

Choose any two refs to compare.

Changed files
+56 -9
packages
bot
src
modules
economy
commands
framework
src
+1 -5
packages/bot/src/index.ts
··· 9 9 // Client initialization with intents and stuff... 10 10 const client = new VoidyClient({ 11 11 intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages], 12 - developers: ["423520077246103563"], 12 + developers: Bun.env.BOT_ADMINS?.split(",") ?? ["423520077246103563"], 13 13 logChannelId: "1451025628206731459" 14 14 }); 15 15 ··· 26 26 // Token validation and client start 27 27 if (!Bun.env.BOT_TOKEN) throw new Error("[Voidy] Missing bot token"); 28 28 await client.start(Bun.env.BOT_TOKEN, `${import.meta.dirname}/modules`); 29 - 30 - //=============================================== 31 - // API initialization 32 - //===============================================
+2 -2
packages/bot/src/modules/economy/commands/minecraft/shop/add-item.ts
··· 43 43 .setDescription("Maximum stack size (default: 64)"), 44 44 ), 45 45 46 - execute: async (interaction, _client) => { 46 + execute: async (interaction, client) => { 47 47 await interaction.deferReply({ flags: [MessageFlags.Ephemeral] }); 48 48 49 49 const item = interaction.options.getString("item", true); ··· 80 80 flags: [MessageFlags.Ephemeral], 81 81 }); 82 82 } catch (err) { 83 - console.error("Failed to add shop item:", err); 83 + client.logger.send(`[minecraft.shop.add-item] Failed: \`\`\`${err}\`\`\``); 84 84 85 85 await interaction.followUp({ 86 86 content: "❌ Failed to add shop item. Check logs for details.",
+3 -2
packages/bot/src/modules/economy/commands/minecraft/shop/generate.ts
··· 13 13 .setDescription("Force pick an item to highlight.") 14 14 ), 15 15 16 - execute: async (interaction, _client) => { 16 + execute: async (interaction, client) => { 17 17 await interaction.deferReply({ flags: [MessageFlags.Ephemeral] }); 18 18 19 19 const highlight = interaction.options.getString("highlight"); 20 20 21 + // Todo: Replace hardcoded URL with environment variable 21 22 try { 22 23 const res = await fetch( 23 24 "https://voidy.thevoid.cafe/api/v1/shop/generate", ··· 51 52 flags: [MessageFlags.Ephemeral], 52 53 }); 53 54 } catch (err) { 54 - console.error("Failed to generate shop:", err); 55 + client.logger.send(`[minecraft.shop.generate] Failed: \`\`\`${err}\`\`\``); 55 56 56 57 await interaction.followUp({ 57 58 content: "❌ Failed to generate a new shop. Check logs for details.",
+48
packages/bot/src/modules/economy/commands/minecraft/shop/rm-item.ts
··· 1 + import { MessageFlags, SlashCommandSubcommandBuilder } from "discord.js"; 2 + import type { Command } from "@voidy/framework"; 3 + import { MinecraftShopItem } from "../../../schemas"; 4 + 5 + export default { 6 + id: "minecraft.shop.rm-item", 7 + devOnly: true, 8 + data: new SlashCommandSubcommandBuilder() 9 + .setName("rm-item") 10 + .setDescription("Remove a Minecraft shop item from the database.") 11 + .addStringOption((option) => 12 + option 13 + .setName("item") 14 + .setDescription("Minecraft item id (e.g. minecraft:diamond)") 15 + .setRequired(true), 16 + ), 17 + 18 + execute: async (interaction, client) => { 19 + await interaction.deferReply({ flags: [MessageFlags.Ephemeral] }); 20 + 21 + const item = interaction.options.getString("item", true); 22 + 23 + try { 24 + // Remove item from database, if it exists 25 + const deleted = await MinecraftShopItem.findOneAndDelete({ item }); 26 + 27 + if (!deleted) { 28 + await interaction.followUp({ 29 + content: `⚠️ Item \`${item}\` does not exist in the shop database.`, 30 + flags: [MessageFlags.Ephemeral], 31 + }); 32 + return; 33 + } 34 + 35 + await interaction.followUp({ 36 + content: `✅ Removed shop item \`${item}\` from the database.`, 37 + flags: [MessageFlags.Ephemeral], 38 + }); 39 + } catch (err) { 40 + client.logger.send(`[minecraft.shop.rm-item] Failed: \`\`\`${err}\`\`\``); 41 + 42 + await interaction.followUp({ 43 + content: "❌ Failed to remove shop item. Check logs for details.", 44 + flags: [MessageFlags.Ephemeral], 45 + }); 46 + } 47 + }, 48 + } as Command;
+2
packages/framework/src/handlers/CommandHandler.ts
··· 17 17 return; 18 18 } 19 19 20 + client.logger.send(`[ChatInputCommandHandler] \`${payload.id}\` invoked by \`${interaction.user.tag}\``); 21 + 20 22 payload.execute(interaction, client); 21 23 } 22 24 }