A powerful and extendable Discord bot, with it's own module system :3
thevoid.cafe/projects/voidy
1import { ChannelType, MessageFlags, PermissionFlagsBits, SlashCommandSubcommandBuilder } from "discord.js";
2import { Command, requirePermission } from "@voidy/framework";
3import { GuildConfig, type IGuildConfig } from "../schemas/GuildConfig";
4
5export default new Command({
6 id: "guild.setup",
7 use: [requirePermission(PermissionFlagsBits.ManageGuild)],
8 data: new SlashCommandSubcommandBuilder()
9 .setName("setup")
10 .setDescription("Set up guild configuration (logging, welcome, auto-roles).")
11 .addChannelOption((option) =>
12 option
13 .setName("log_channel")
14 .setDescription("Channel for member join/leave logging.")
15 .addChannelTypes(ChannelType.GuildText)
16 .setRequired(true),
17 )
18 .addChannelOption((option) =>
19 option
20 .setName("welcome_channel")
21 .setDescription("Channel for welcome messages.")
22 .addChannelTypes(ChannelType.GuildText),
23 )
24 .addRoleOption((option) =>
25 option.setName("member_role").setDescription("Auto-role assigned to new members."),
26 )
27 .addRoleOption((option) =>
28 option.setName("bot_role").setDescription("Auto-role assigned to new bots."),
29 ),
30
31 execute: async ({ interaction, client }) => {
32 const logChannel = interaction.options.getChannel("log_channel", true);
33 const welcomeChannel = interaction.options.getChannel("welcome_channel");
34 const memberRole = interaction.options.getRole("member_role");
35 const botRole = interaction.options.getRole("bot_role");
36
37 const update: Record<string, string | undefined> = {
38 "logging.channelId": logChannel.id,
39 };
40 if (welcomeChannel) update["welcome.channelId"] = welcomeChannel.id;
41 if (memberRole) update["autoRoles.memberRoleId"] = memberRole.id;
42 if (botRole) update["autoRoles.botRoleId"] = botRole.id;
43
44 const doc = await GuildConfig.findOneAndUpdate(
45 { guildId: interaction.guildId },
46 { $set: update },
47 { upsert: true, new: true },
48 );
49
50 const cache = client.data.get("guildConfig") as Map<string, IGuildConfig> | undefined;
51 if (cache && interaction.guildId) cache.set(interaction.guildId, doc.toObject());
52
53 const lines = [`Logging channel set to <#${logChannel.id}>`];
54 if (welcomeChannel) lines.push(`Welcome channel set to <#${welcomeChannel.id}>`);
55 if (memberRole) lines.push(`Member auto-role set to <@&${memberRole.id}>`);
56 if (botRole) lines.push(`Bot auto-role set to <@&${botRole.id}>`);
57
58 await interaction.reply({
59 content: `Guild configuration updated:\n${lines.join("\n")}`,
60 flags: [MessageFlags.Ephemeral],
61 });
62 },
63});