├── .gitignore ├── environment.d.ts ├── examples ├── slash_chat_input_user.js ├── slash_context_menu_msg.js ├── message_command.js └── slash_chat_input.js ├── Commands ├── Message │ └── Misc │ │ └── ping.js └── Slash │ └── Misc │ └── ping.js ├── settings └── config.js ├── bot.js ├── events ├── ready.js ├── interactionCreate.js └── messageCreate.js ├── handlers ├── eventHandler.js ├── messageHandler.js ├── functions.js ├── slashHandler.js └── Client.js ├── LICENSE ├── package.json ├── index.d.ts └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .env 3 | package-lock.json 4 | -------------------------------------------------------------------------------- /environment.d.ts: -------------------------------------------------------------------------------- 1 | declare global { 2 | namespace NodeJS { 3 | interface ProcessEnv { 4 | TOKEN: string; 5 | PREFIX: string; 6 | GuildID: string; 7 | environment: "dev" | "prod" | "debug"; 8 | } 9 | } 10 | } 11 | 12 | export {}; 13 | -------------------------------------------------------------------------------- /examples/slash_chat_input_user.js: -------------------------------------------------------------------------------- 1 | import { ApplicationCommandType } from "discord.js"; 2 | 3 | /** 4 | * @type {import("../../..").CUcommand} 5 | */ 6 | export default { 7 | name: "", 8 | category: "", 9 | type: ApplicationCommandType.User, 10 | 11 | run: async ({ client, interaction }) => { 12 | // Code 13 | }, 14 | }; 15 | -------------------------------------------------------------------------------- /examples/slash_context_menu_msg.js: -------------------------------------------------------------------------------- 1 | import { ApplicationCommandType } from "discord.js"; 2 | 3 | /** 4 | * @type {import("../../..").CMcommand} 5 | */ 6 | export default { 7 | name: "", 8 | category: "", 9 | type: ApplicationCommandType.Message, 10 | 11 | run: async ({ client, interaction }) => { 12 | // Code 13 | }, 14 | }; 15 | -------------------------------------------------------------------------------- /examples/message_command.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @type {import("../../../index.js").Mcommand} 3 | */ 4 | export default { 5 | name: "", 6 | description: "", 7 | userPermissions: ["SendMessages"], 8 | botPermissions: ["SendMessages", "EmbedLinks"], 9 | category: "", 10 | cooldown: 5, 11 | 12 | run: async ({ client, message, args, prefix }) => { 13 | // Code 14 | }, 15 | }; 16 | -------------------------------------------------------------------------------- /examples/slash_chat_input.js: -------------------------------------------------------------------------------- 1 | import { ApplicationCommandType } from "discord.js"; 2 | 3 | /** 4 | * @type {import("../../../index.js").Scommand} 5 | */ 6 | export default { 7 | name: "", 8 | description: "", 9 | userPermissions: ["SendMessages"], 10 | botPermissions: ["SendMessages", "EmbedLinks"], 11 | category: "", 12 | type: ApplicationCommandType.ChatInput, 13 | 14 | run: async ({ client, interaction }) => { 15 | // Code 16 | }, 17 | }; 18 | -------------------------------------------------------------------------------- /Commands/Message/Misc/ping.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @type {import("../../../index.js").Mcommand} 3 | */ 4 | export default { 5 | name: "ping", 6 | description: "Check the bot's latency.", 7 | userPermissions: ["SendMessages"], 8 | botPermissions: ["SendMessages", "EmbedLinks"], 9 | category: "Misc", 10 | cooldown: 5, 11 | 12 | run: async ({ client, message, args, prefix }) => { 13 | // Code 14 | await client.sendEmbed(message, `🏓 Pong \`${client.ws.ping}\``); 15 | }, 16 | }; 17 | -------------------------------------------------------------------------------- /settings/config.js: -------------------------------------------------------------------------------- 1 | import { Colors } from "discord.js"; 2 | 3 | const settings = { 4 | TOKEN: process.env.TOKEN || "Bot_Token", 5 | PREFIX: process.env.PREFIX || "BotPrefix", 6 | Owners: ["OwnersId", "OwnersId"], 7 | Slash: { 8 | Global: false, 9 | GuildID: process.env.GuildID || "Guild_Id", 10 | }, 11 | embed: { 12 | color: Colors.Blurple, 13 | wrongColor: Colors.Red, 14 | }, 15 | emoji: { 16 | success: "✅", 17 | error: "❌", 18 | }, 19 | }; 20 | 21 | export default settings; 22 | -------------------------------------------------------------------------------- /Commands/Slash/Misc/ping.js: -------------------------------------------------------------------------------- 1 | import { ApplicationCommandType } from "discord.js"; 2 | 3 | /** 4 | * @type {import("../../../index").Scommand} 5 | */ 6 | export default { 7 | name: "ping", 8 | description: "Check the bot's latency.", 9 | userPermissions: ["SendMessages"], 10 | botPermissions: ["SendMessages", "EmbedLinks"], 11 | category: "Misc", 12 | type: ApplicationCommandType.ChatInput, 13 | 14 | run: async ({ client, interaction }) => { 15 | // Code 16 | await client.sendEmbed(interaction, `🏓 Pong \`${client.ws.ping}\``); 17 | }, 18 | }; 19 | -------------------------------------------------------------------------------- /bot.js: -------------------------------------------------------------------------------- 1 | import "dotenv/config"; 2 | import { Bot } from "./handlers/Client.js"; 3 | 4 | /** 5 | * The client instance representing the bot. 6 | * @type {Bot} 7 | */ 8 | export const client = new Bot(); 9 | 10 | // Login the bot using the provided token 11 | client.build(client.config.TOKEN); 12 | 13 | /** 14 | * Initializes and logs in the bot. 15 | * @module BotInitialization 16 | */ 17 | 18 | // Handle uncaught exceptions 19 | process.on("uncaughtException", (error) => { 20 | console.error("An uncaught exception occurred:", error); 21 | }); 22 | 23 | // Handle unhandled promise rejections 24 | process.on("unhandledRejection", (error) => { 25 | console.error("An unhandled promise rejection occurred:", error); 26 | }); 27 | -------------------------------------------------------------------------------- /events/ready.js: -------------------------------------------------------------------------------- 1 | import { ActivityType } from "discord.js"; 2 | import { client } from "../bot.js"; 3 | 4 | /** 5 | * Event listener for when the client becomes ready. 6 | * This event is emitted once the bot has successfully connected to Discord and is ready to start receiving events. 7 | * @event client#ready 8 | */ 9 | client.on("ready", async () => { 10 | try { 11 | // Log a message indicating that the client is ready 12 | console.log(`> ✅ ${client.user.tag} is now online`); 13 | 14 | // Set the activity for the client 15 | client.user.setActivity({ 16 | name: `Coded By Kabir ❤️‍🔥`, // Set the activity name 17 | type: ActivityType.Watching, // Set the activity type 18 | }); 19 | } catch (error) { 20 | // Log any errors that occur 21 | console.error("An error occurred in the ready event:", error); 22 | } 23 | }); 24 | 25 | /** 26 | * Sets the bot's presence and activity when it becomes ready. 27 | * @module ReadyEvent 28 | */ 29 | -------------------------------------------------------------------------------- /handlers/eventHandler.js: -------------------------------------------------------------------------------- 1 | import { readdir } from "node:fs/promises"; 2 | 3 | /** 4 | * Loads event handlers for the client. 5 | * @param {Bot} client - The client instance. 6 | */ 7 | export default async (client) => { 8 | try { 9 | let count = 0; 10 | 11 | const eventFiles = await readdir("./events"); 12 | const eventFilesFiltered = eventFiles.filter((file) => 13 | file.endsWith(".js") 14 | ); 15 | 16 | await Promise.all( 17 | eventFilesFiltered.map(async (file) => { 18 | try { 19 | await import(`../events/${file}`).then((r) => r.default); 20 | count++; 21 | } catch (error) { 22 | console.error(`Error loading event from file ${file}:`, error); 23 | return 0; 24 | } 25 | }) 26 | ); 27 | 28 | console.log(`> ✅ Successfully loaded ${count} events.`); 29 | } catch (error) { 30 | console.error("An error occurred while reading the events folder:", error); 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 ᴋᴀʙɪʀ々ꜱɪɴɢʜ 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /handlers/messageHandler.js: -------------------------------------------------------------------------------- 1 | import { Bot } from "./Client.js"; 2 | import { readdir } from "node:fs/promises"; 3 | 4 | /** 5 | * Loads message commands for the client. 6 | * @param {Bot} client - The client instance. 7 | */ 8 | export default async (client) => { 9 | try { 10 | const commandsDir = await readdir(`./Commands/Message`); 11 | 12 | await Promise.all( 13 | commandsDir.map(async (dir) => { 14 | const commands = await readdir(`./Commands/Message/${dir}`); 15 | const filterCommands = commands.filter((f) => f.endsWith(".js")); 16 | 17 | await Promise.all( 18 | filterCommands.map(async (cmd) => { 19 | try { 20 | /** 21 | * @type {import("../index.js").Scommand} 22 | */ 23 | const command = await import( 24 | `../Commands/Message/${dir}/${cmd}` 25 | ).then((r) => r.default); 26 | 27 | if (command.name) { 28 | client.mcommands.set(command.name, command); 29 | } 30 | } catch (error) { 31 | console.error(`Error loading command from file ${cmd}:`, error); 32 | } 33 | }) 34 | ); 35 | }) 36 | ); 37 | 38 | console.log( 39 | `> ✅ Successfully loaded ${client.mcommands.size} message commands.` 40 | ); 41 | } catch (error) { 42 | console.error( 43 | "An error occurred while reading the commands directory:", 44 | error 45 | ); 46 | } 47 | }; 48 | -------------------------------------------------------------------------------- /handlers/functions.js: -------------------------------------------------------------------------------- 1 | import { 2 | CommandInteraction, 3 | Collection, 4 | PermissionFlagsBits, 5 | } from "discord.js"; 6 | 7 | /** 8 | * Manages cooldown for commands. 9 | * @param {CommandInteraction} interaction - The command interaction. 10 | * @param {Object} cmd - The command object containing cooldown information. 11 | * @returns {number | false} The time left on cooldown in seconds, or false if the command is not on cooldown. 12 | */ 13 | export function cooldown(interaction, cmd) { 14 | if (!interaction || !cmd) return; 15 | let { client, member } = interaction; 16 | 17 | // Ensure cooldowns collection exists for the command 18 | if (!client.cooldowns.has(cmd.name)) { 19 | client.cooldowns.set(cmd.name, new Collection()); 20 | } 21 | 22 | const now = Date.now(); 23 | const timestamps = client.cooldowns.get(cmd.name); 24 | const cooldownAmount = cmd.cooldown * 1000; 25 | 26 | if (timestamps.has(member.id)) { 27 | const expirationTime = timestamps.get(member.id) + cooldownAmount; 28 | if (now < expirationTime) { 29 | const timeLeft = (expirationTime - now) / 1000; // Get the time left until cooldown expires 30 | return timeLeft; 31 | } else { 32 | timestamps.set(member.id, now); 33 | setTimeout(() => timestamps.delete(member.id), cooldownAmount); 34 | return false; // Command is not on cooldown 35 | } 36 | } else { 37 | timestamps.set(member.id, now); 38 | setTimeout(() => timestamps.delete(member.id), cooldownAmount); 39 | return false; // Command is not on cooldown 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "discordjs-base-handler", 3 | "version": "2.1.0", 4 | "description": "A Discord bot handler for managing events and commands.", 5 | "main": "bot.js", 6 | "type": "module", 7 | "scripts": { 8 | "start": "node bot.js" 9 | }, 10 | "author": "KABIRSINGH2004", 11 | "license": "MIT", 12 | "repository": { 13 | "type": "git", 14 | "url": "https://github.com/kabirsingh2004/discordjs-base-handler" 15 | }, 16 | "bugs": { 17 | "url": "https://github.com/kabirsingh2004/discordjs-base-handler/issues" 18 | }, 19 | "homepage": "https://github.com/kabirsingh2004/discordjs-base-handler", 20 | "keywords": [ 21 | "discord", 22 | "bot", 23 | "handler", 24 | "javascript", 25 | "discordjs", 26 | "v14", 27 | "slashcommands", 28 | "advanced", 29 | "comprehensive", 30 | "flexible", 31 | "easy-to-use", 32 | "well-documented", 33 | "maintained", 34 | "command handler", 35 | "event handler", 36 | "slash command handler", 37 | "modal handler", 38 | "button handler", 39 | "interaction handler", 40 | "permission handling", 41 | "rate limiting", 42 | "cooldown handling", 43 | "localization", 44 | "internationalization", 45 | "scalability", 46 | "performance", 47 | "discord bot development", 48 | "discord bot making", 49 | "discord bot programming", 50 | "discord bot tutorial", 51 | "discord bot guide", 52 | "discord bot example" 53 | ], 54 | "dependencies": { 55 | "discord.js": "^14.17.3", 56 | "dotenv": "^16.4.7" 57 | }, 58 | "engines": { 59 | "node": ">=16" 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /index.d.ts: -------------------------------------------------------------------------------- 1 | import { Bot } from "./handlers/Client.js"; 2 | import { 3 | ApplicationCommandNonOptions, 4 | CommandInteraction, 5 | ContextMenuCommandInteraction, 6 | InteractionReplyOptions, 7 | Message, 8 | UserContextMenuCommandInteraction, 9 | InteractionResponse, 10 | ApplicationCommandDataResolvable, 11 | PermissionResolvable, 12 | } from "discord.js"; 13 | 14 | interface McommandOptions { 15 | client?: Bot; 16 | message?: Message; 17 | args?: string[]; 18 | prefix?: string; 19 | } 20 | 21 | export interface Mcommand { 22 | name: string; 23 | description: string; 24 | userPermissions: PermissionResolvable[]; 25 | botPermissions: PermissionResolvable[]; 26 | category: string; 27 | owneronly: boolean; 28 | run: (options: McommandOptions) => {}; 29 | } 30 | 31 | interface ScommandOptions { 32 | client?: Bot; 33 | interaction?: CommandInteraction; 34 | } 35 | 36 | export interface CustomSCommand { 37 | name: string; 38 | description: string; 39 | userPermissions: PermissionResolvable[]; 40 | botPermissions: PermissionResolvable[]; 41 | category: string; 42 | type: number; 43 | options?: ApplicationCommandNonOptions[]; 44 | run: (options: ScommandOptions) => {}; 45 | } 46 | 47 | type Scommand = ApplicationCommandDataResolvable & CustomSCommand; 48 | 49 | export interface CMcommand { 50 | name: string; 51 | category: string; 52 | type: number; 53 | run: (client: Bot, interaction: ContextMenuCommandInteraction) => {}; 54 | } 55 | 56 | export interface CUcommand { 57 | name: string; 58 | category: string; 59 | type: number; 60 | run: (client: Bot, interaction: UserContextMenuCommandInteraction) => {}; 61 | } 62 | 63 | export type send = ( 64 | interactionOrMessage: CommandInteraction | Message, 65 | options: InteractionReplyOptions 66 | ) => Promise; 67 | 68 | export type SendEmbedFunction = ( 69 | interaction: CommandInteraction, 70 | data: string, 71 | ephemeral?: boolean 72 | ) => Promise; 73 | -------------------------------------------------------------------------------- /handlers/slashHandler.js: -------------------------------------------------------------------------------- 1 | import { Bot } from "./Client.js"; 2 | import { readdir } from "node:fs/promises"; 3 | 4 | /** 5 | * Loads slash commands for the client and registers them globally or in a specific guild. 6 | * @param {Bot} client - The client instance. 7 | */ 8 | export default async function loadSlashCommands(client) { 9 | const { 10 | Slash: { Global, GuildID }, 11 | } = client.config; 12 | 13 | try { 14 | let allCommands = []; 15 | const commandsDir = await readdir(`./Commands/Slash`); 16 | 17 | await Promise.all( 18 | commandsDir.map(async (dir) => { 19 | const commands = await readdir(`./Commands/Slash/${dir}`); 20 | let filterCommands = commands.filter((f) => f.endsWith(".js")); 21 | 22 | await Promise.all( 23 | filterCommands.map(async (cmd) => { 24 | try { 25 | /** 26 | * @type {import("../index.js").Scommand} 27 | */ 28 | const command = await import( 29 | `../Commands/Slash/${dir}/${cmd}` 30 | ).then((r) => r.default); 31 | 32 | if (command.name) { 33 | client.scommands.set(command.name, command); 34 | allCommands.push(command); 35 | } 36 | } catch (error) { 37 | console.error(`Error loading command from file ${cmd}:`, error); 38 | } 39 | }) 40 | ); 41 | }) 42 | ); 43 | 44 | // Register commands globally or in a specific guild 45 | await client.on("ready", async () => { 46 | if (Global) { 47 | client.application.commands.set(allCommands); 48 | } else { 49 | const guild = client.guilds.cache.get(GuildID); 50 | if (guild) await guild.commands.set(allCommands); 51 | } 52 | }); 53 | 54 | console.log( 55 | `> ✅ Successfully loaded ${client.scommands.size} slash commands.` 56 | ); 57 | } catch (error) { 58 | console.error( 59 | "An error occurred while reading the commands directory:", 60 | error 61 | ); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /events/interactionCreate.js: -------------------------------------------------------------------------------- 1 | import { InteractionType } from "discord.js"; 2 | import { client } from "../bot.js"; 3 | 4 | /** 5 | * Handles interaction events, such as slash commands. 6 | * @param {Interaction} interaction - The interaction received from Discord. 7 | */ 8 | client.on("interactionCreate", async (interaction) => { 9 | try { 10 | // Ignore interactions from bots or outside of guilds 11 | if (interaction.user.bot || !interaction.guild) return; 12 | 13 | // Check if the interaction is a command 14 | if (interaction.type == InteractionType.ApplicationCommand) { 15 | // Get the command object from the command collection 16 | const command = client.scommands.get(interaction.commandName); 17 | 18 | // If command not found, respond with error message 19 | if (!command) { 20 | return client.send(interaction, { 21 | content: `\`${interaction.commandName}\` is not a valid command !!`, 22 | ephemeral: true, 23 | }); 24 | } 25 | 26 | // Extract member and command permissions 27 | const { member, guild } = interaction; 28 | const { userPermissions, botPermissions } = command; 29 | 30 | // Check user permissions 31 | const missingUserPerms = userPermissions.filter( 32 | (perm) => !member.permissions.has(perm) 33 | ); 34 | if (missingUserPerms.length > 0) { 35 | await client.sendEmbed( 36 | interaction, 37 | `You are missing the following permissions: \`${missingUserPerms.join( 38 | ", " 39 | )}\`` 40 | ); 41 | return; 42 | } 43 | 44 | // Check bot permissions 45 | const missingBotPerms = botPermissions.filter( 46 | (perm) => !guild.members.me.permissions.has(perm) 47 | ); 48 | if (missingBotPerms.length > 0) { 49 | await client.sendEmbed( 50 | interaction, 51 | `I am missing the following permissions: \`${missingBotPerms.join( 52 | ", " 53 | )}\`` 54 | ); 55 | return; 56 | } 57 | 58 | // Run the command 59 | await command.run({ client, interaction }); 60 | } 61 | } catch (error) { 62 | // Log any errors that occur 63 | console.error("An error occurred in interactionCreate event:", error); 64 | 65 | // Send a generic error message to the user 66 | await client.sendEmbed( 67 | interaction, 68 | "An error occurred while processing your command. Please try again later." 69 | ); 70 | } 71 | }); 72 | -------------------------------------------------------------------------------- /events/messageCreate.js: -------------------------------------------------------------------------------- 1 | import { cooldown } from "../handlers/functions.js"; 2 | import { client } from "../bot.js"; 3 | 4 | /** 5 | * Event listener for when a message is created. 6 | * @param {Message} message - The message object received from Discord. 7 | */ 8 | client.on("messageCreate", async (message) => { 9 | try { 10 | // Check for necessary conditions 11 | if (message.author.bot || !message.guild || !message.id) return; 12 | 13 | const prefix = client.config.PREFIX; 14 | 15 | const mentionPrefix = new RegExp( 16 | `^(<@!?${client.user.id}>|${escapeRegex(prefix)})\\s*` 17 | ); 18 | 19 | if (!mentionPrefix.test(message.content)) return; 20 | const [, nPrefix] = message.content.match(mentionPrefix); 21 | const args = message.content.slice(nPrefix.length).trim().split(/ +/); 22 | const cmd = args.shift().toLowerCase(); 23 | 24 | if (cmd.length === 0) { 25 | if (nPrefix.includes(client.user.id)) { 26 | return client.sendEmbed( 27 | message, 28 | ` ${client.config.emoji.success} To See My All Commands Type \`/help\` or \`${prefix}help\`` 29 | ); 30 | } 31 | } 32 | 33 | // Find the command 34 | /** 35 | * @type {import("../index.js").Mcommand} 36 | */ 37 | const command = 38 | client.mcommands.get(cmd) || 39 | client.mcommands.find( 40 | (cmds) => cmds.aliases && cmds.aliases.includes(cmd) 41 | ); 42 | 43 | // Check if the command exists 44 | if (!command) return; 45 | 46 | const { owneronly, userPermissions, botPermissions } = command; 47 | const { author, member, guild } = message; 48 | 49 | // Check ownership 50 | if (owneronly && !client.config.Owners.includes(author.id)) { 51 | return client.sendEmbed( 52 | message, 53 | `This command is restricted to authorized person only.` 54 | ); 55 | } 56 | // Check user permissions 57 | const missingUserPerms = userPermissions.filter( 58 | (perm) => !member.permissions.has(perm) 59 | ); 60 | if (missingUserPerms.length > 0) { 61 | await client.sendEmbed( 62 | message, 63 | `You are missing the following permissions: \`${missingUserPerms.join( 64 | ", " 65 | )}\`` 66 | ); 67 | return; 68 | } 69 | 70 | // Check bot permissions 71 | const missingBotPerms = botPermissions.filter( 72 | (perm) => !guild.members.me.permissions.has(perm) 73 | ); 74 | if (missingBotPerms.length > 0) { 75 | await client.sendEmbed( 76 | message, 77 | `I am missing the following permissions: \`${missingBotPerms.join( 78 | ", " 79 | )}\`` 80 | ); 81 | return; 82 | } 83 | 84 | // Check cooldown 85 | if (cooldown(message, command)) { 86 | return client.sendEmbed( 87 | message, 88 | `You are currently on cooldown. Please wait for ${cooldown( 89 | message, 90 | command 91 | ).toFixed()} seconds before trying again.` 92 | ); 93 | } 94 | 95 | // Run the command 96 | await command.run({ client, message, args, prefix }); 97 | } catch (error) { 98 | console.error( 99 | "An error occurred while processing messageCreate event:", 100 | error 101 | ); 102 | } 103 | }); 104 | 105 | /** 106 | * Escapes special characters in a string to create a regex pattern. 107 | * @param {string} newPrefix - The string to escape. 108 | * @returns {string} The escaped string. 109 | */ 110 | function escapeRegex(newPrefix) { 111 | return newPrefix?.replace(/[.*+?^${}()|[\]\\]/g, `\\$&`); 112 | } 113 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Hi, I'm Kabir! 👋 2 | 3 | I'm a Discord Bot Developer and here is mine bot handler 4 | 5 | ## Installation | How to use the Handler 6 | 7 | 1. Clone this repository. 8 | 2. Fill in the required details in **`settings/config.js`**. 9 | 3. Run `npm install` to install dependencies. 10 | 4. Start the bot with `node index.js`. 11 | 12 | ### _Modify - config.js_ 13 | 14 | ```js 15 | import { Colors } from "discord.js"; 16 | 17 | const settings = { 18 | TOKEN: process.env.TOKEN || "BOT_TOKEN", 19 | PREFIX: process.env.PREFIX || "BOT_PREFIX", 20 | Owners: ["OwnersId", "OwnersId"], 21 | Slash: { 22 | Global: false, 23 | GuildID: process.env.GuildID || "GUILD_ID", 24 | }, 25 | }; 26 | 27 | export default settings; 28 | ``` 29 | 30 | ## Handler Features 31 | 32 | - Easy-to-use Handler 33 | - Event handling support 34 | - Slash commands 35 | - Message commands 36 | - Built on [discord.js](https://discord.js.org/#/) 37 | - Code snippets for commands 38 | - Subdirectory support in the commands folder 39 | - Code suggestions in Handler 40 | 41 | ## Feedback 42 | 43 | If you have any feedback or need assistance, please join out [Discord Server](https://discord.gg/PcUVWApWN3) 44 | 45 | ## Usage/Examples 46 | 47 | - Commands Example 48 | 49 | # Slash Chat Input Command 50 | 51 | ```js 52 | import { ApplicationCommandType, PermissionFlagsBits } from "discord.js"; 53 | 54 | /** 55 | * @type {import("../../../index.js").Scommand} 56 | */ 57 | export default { 58 | name: "", 59 | description: "", 60 | userPermissions: [PermissionFlagsBits.SendMessages], 61 | botPermissions: [ 62 | PermissionFlagsBits.SendMessages, 63 | PermissionFlagsBits.EmbedLinks, 64 | ], 65 | category: "", 66 | type: ApplicationCommandType.ChatInput, 67 | 68 | run: async ({ client, interaction }) => { 69 | // Code 70 | }, 71 | }; 72 | ``` 73 | 74 | # Slash Message Input Command 75 | 76 | ```js 77 | import { ApplicationCommandType } from "discord.js"; 78 | 79 | /** 80 | * @type {import("../../..").CMcommand} 81 | */ 82 | export default { 83 | name: "", 84 | category: "", 85 | type: ApplicationCommandType.Message, 86 | 87 | run: async ({ client, interaction }) => { 88 | // Code 89 | }, 90 | }; 91 | ``` 92 | 93 | # Slash User Input Command 94 | 95 | ```js 96 | const { ApplicationCommandType } = require("discord.js"); 97 | 98 | /** 99 | * @type {import("../../..").CUcommand} 100 | */ 101 | export default { 102 | name: "", 103 | category: "", 104 | type: ApplicationCommandType.User, 105 | 106 | run: async ({ client, interaction }) => { 107 | // Code 108 | }, 109 | }; 110 | ``` 111 | 112 | # Message/Prefix Command 113 | 114 | ```js 115 | import { PermissionFlagsBits } from "discord.js"; 116 | 117 | /** 118 | * @type {import("../../../index.js").Mcommand} 119 | */ 120 | export default { 121 | name: "", 122 | description: "", 123 | userPermissions: [PermissionFlagsBits.SendMessages], 124 | botPermissions: [ 125 | PermissionFlagsBits.SendMessages, 126 | PermissionFlagsBits.EmbedLinks, 127 | ], 128 | category: "", 129 | cooldown: 5, 130 | 131 | run: async ({ client, message, args, prefix }) => { 132 | // Code 133 | }, 134 | }; 135 | ``` 136 | 137 | ## License 138 | 139 | This project is licensed under the [MIT License](https://choosealicense.com/licenses/mit/). See the [LICENSE](LICENSE) file for details. 140 | 141 | # Acknowledgements 142 | 143 | Thank you for considering the use of Kabir's Discord Bot Handler! If you find it helpful, we encourage you to give it a ⭐️. 144 | 145 | ## Contributing 146 | 147 | If you encounter any bugs or have suggestions for improvement, please open a pull request. Your contributions are highly appreciated! 148 | 149 | ## Support 150 | 151 | For any inquiries or assistance, feel free to reach out to us on our [Discord Server](https://discord.gg/PcUVWApWN3). 152 | 153 | Happy coding! 🚀 154 | -------------------------------------------------------------------------------- /handlers/Client.js: -------------------------------------------------------------------------------- 1 | import { 2 | Client, 3 | GatewayIntentBits, 4 | Partials, 5 | Collection, 6 | EmbedBuilder, 7 | CommandInteraction, 8 | Message, 9 | InteractionResponse, 10 | MessageFlags, 11 | } from "discord.js"; 12 | import settings from "../settings/config.js"; 13 | 14 | /** 15 | * Custom client class extending Discord.js Client. 16 | */ 17 | export class Bot extends Client { 18 | /** 19 | * Creates an instance of Bot. 20 | */ 21 | constructor() { 22 | super({ 23 | partials: [ 24 | Partials.Channel, 25 | Partials.GuildMember, 26 | Partials.Message, 27 | Partials.User, 28 | ], 29 | intents: [ 30 | GatewayIntentBits.Guilds, 31 | GatewayIntentBits.GuildMessages, 32 | GatewayIntentBits.GuildVoiceStates, 33 | GatewayIntentBits.MessageContent, 34 | GatewayIntentBits.GuildMembers, 35 | ], 36 | shards: "auto", 37 | failIfNotExists: false, 38 | allowedMentions: { 39 | parse: ["everyone", "roles", "users"], 40 | users: [], 41 | roles: [], 42 | repliedUser: false, 43 | }, 44 | }); 45 | 46 | // Set global variables 47 | this.config = settings; 48 | this.scommands = new Collection(); 49 | this.mcommands = new Collection(); 50 | this.cooldowns = new Collection(); 51 | this.events = new Collection(); 52 | } 53 | 54 | /** 55 | * Builds the client and logs in with the provided token. 56 | * @param {string} token - The bot token. 57 | */ 58 | async build(token) { 59 | await loadHandlers(this); 60 | this.login(token); 61 | } 62 | 63 | /** 64 | * Sends an embed message. 65 | * @param {Interaction} interaction - The interaction where the message is sent. 66 | * @param {string} data - The content of the message. 67 | * @param {boolean} [ephemeral=false] - Whether the message should be ephemeral. 68 | * @returns {Promise} The sent message or interaction response. 69 | */ 70 | async sendEmbed(interaction, data, ephemeral = false) { 71 | return this.send(interaction, { 72 | embeds: [ 73 | new EmbedBuilder() 74 | .setColor(this.config.embed.color) 75 | .setDescription(`${data.substring(0, 3000)}`), 76 | ], 77 | flags: ephemeral ? MessageFlags.Ephemeral : undefined, 78 | }); 79 | } 80 | 81 | /** 82 | * Gets the footer for an embed message. 83 | * @param {User} user - The user to display in the footer. 84 | * @returns {Footer} The footer object. 85 | */ 86 | getFooter(user) { 87 | return { 88 | text: `Requested By ${user.username}`, 89 | iconURL: user.displayAvatarURL(), 90 | }; 91 | } 92 | 93 | /** 94 | * Sends a message or interaction response. 95 | * @param {CommandInteraction | Message} interactionOrMessage - The interaction or message. 96 | * @param {import("discord.js").InteractionReplyOptions} options - The options for the reply. 97 | * @returns {Promise} The sent message or interaction response. 98 | */ 99 | async send(interactionOrMessage, options) { 100 | try { 101 | if (interactionOrMessage.deferred || interactionOrMessage.replied) { 102 | await interactionOrMessage.deferReply().catch((e) => {}); 103 | return interactionOrMessage.followUp(options); 104 | } else { 105 | return interactionOrMessage.reply(options); 106 | } 107 | } catch (error) { 108 | return interactionOrMessage.channel.send(options); 109 | } 110 | } 111 | } 112 | 113 | /** 114 | * Loads message, slash, and event handlers for the client. 115 | * @param {Bot} client - The client instance. 116 | */ 117 | async function loadHandlers(client) { 118 | ["messageHandler", "slashHandler", "eventHandler"].forEach(async (file) => { 119 | let handler = await import(`./${file}.js`).then((r) => r.default); 120 | await handler(client); 121 | }); 122 | } 123 | --------------------------------------------------------------------------------