UNPKG

@befacidev/djs-easy

Version:

Use discord.js but easily for beginners

306 lines (305 loc) 12.4 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.Bot = exports.Events = void 0; const djs = __importStar(require("discord.js")); const ConsoleLogging_1 = require("./handlers/ConsoleLogging"); var Events; (function (Events) { // Guild-related Events["guildJoined"] = "guildCreate"; Events["guildLeaved"] = "guildDelete"; Events["guildUpdated"] = "guildUpdate"; // Channel-related Events["channelCreated"] = "channelCreate"; Events["channelDeleted"] = "channelDelete"; Events["channelUpdated"] = "channelUpdate"; Events["channelPinsUpdated"] = "channelPinsUpdate"; // Emoji & stickers Events["emojiCreated"] = "emojiCreate"; Events["emojiDeleted"] = "emojiDelete"; Events["emojiUpdated"] = "emojiUpdate"; Events["stickerCreated"] = "stickerCreate"; Events["stickerDeleted"] = "stickerDelete"; Events["stickerUpdated"] = "stickerUpdate"; // Member-related Events["memberJoined"] = "guildMemberAdd"; Events["memberLeaved"] = "guildMemberRemove"; Events["memberUpdated"] = "guildMemberUpdate"; // Role-related Events["roleCreated"] = "roleCreate"; Events["roleDeleted"] = "roleDelete"; Events["roleUpdated"] = "roleUpdate"; // Presence & voice Events["presenceUpdated"] = "presenceUpdate"; Events["voiceStateUpdated"] = "voiceStateUpdate"; // Messages Events["newMessage"] = "messageCreate"; Events["messageDeleted"] = "messageDelete"; Events["messageUpdated"] = "messageUpdate"; Events["messageReactionAdded"] = "messageReactionAdd"; Events["messageReactionRemoved"] = "messageReactionRemove"; Events["messageReactionRemovedAll"] = "messageReactionRemoveAll"; Events["typingStarted"] = "typingStart"; // Users Events["userUpdated"] = "userUpdate"; // Interaction Events["interactionCreated"] = "interactionCreate"; // Webhooks Events["webhookUpdated"] = "webhookUpdate"; // AutoModeration Events["autoModBlocked"] = "autoModerationActionExecution"; // Client stuff Events["botReady"] = "ready"; Events["botReconnecting"] = "shardReconnecting"; Events["botDisconnected"] = "shardDisconnect"; Events["botResumed"] = "shardResume"; Events["botError"] = "error"; Events["botWarn"] = "warn"; Events["botDebug"] = "debug"; })(Events || (exports.Events = Events = {})); // types var Log = new ConsoleLogging_1.Logger(); class Bot { constructor(token, options, showDebugLogLevel = false) { this.discordjs_client = new djs.Client({ intents: this._getIntents__(options.intents), closeTimeout: options.closeTimeout ?? 15000, }); this.token = token; this.login().catch(err => { Log.Error(`Connection failure: ${err}`); }); this.showDebugLogLevel = showDebugLogLevel; if (this.showDebugLogLevel) { this.discordjs_client.on(djs.Events.Debug, (message) => { Log.NotImportant(`[Discord] ${message}`); }); } this.discordjs_client.once(djs.Events.ClientReady, (client) => { Log.Success(`Discord Bot connected as ${client.user.tag}!`); }); this.discordjs_client.on("error", (err) => Log.Error(`Client Error: ${err}`)); } /** * Add a listener via Discord.JS * Example: bot.on("messageCreate", (msg) => ...) */ on(event, callback) { this.discordjs_client.on(event, callback); } /** * Send a message on a channel */ async sendMessage(channelId, content) { const channel = await this.discordjs_client.channels.fetch(channelId); if (!channel || !channel.isTextBased()) { throw Log.Error(`Cannot find the channel (or not textual): ${channelId}`); } if (channel instanceof djs.TextChannel || channel instanceof djs.DMChannel || channel instanceof djs.NewsChannel) { return channel.send(content); } throw Log.Error(`The channel ${channelId} doesn't supports sending messages.`); } /** * Send a message to a user (via his ID) in his DM */ async sendDMMessage(userId, content) { try { const user = await this.discordjs_client.users.fetch(userId); if (!user) throw Log.Error(`User ${userId} not found`); const dmChannel = await user.createDM(); return await dmChannel.send(content).then(() => Log.NotImportant(`Sent a message to ${user.username}`)); } catch (err) { throw Log.Error(`Impossible to send the message to ${userId}: ${err}`); } } /** * Register prefix commands via this * Usage Example: bot.registerCommand("!").addCommand("lorem", (message, args) => ...).addCommand("hello", (message, args) => ...) ...; */ registerCommands(prefix) { const commandMap = new Map(); this.discordjs_client.on("messageCreate", (msg) => { if (msg.author.bot || !msg.content.startsWith(prefix)) return; const args = msg.content.slice(prefix.length).trim().split(/ +/); const cmd = args.shift()?.toLowerCase(); if (!cmd) return; const handler = commandMap.get(cmd); if (handler) { try { handler(msg, args); } catch (err) { Log.Error(`Error while executing the prefix command "${cmd}": ${err}`); msg.reply("An error has been occurred, please contact the creator of the bot."); } } }); const builder = { addCommand: (name, handler) => { commandMap.set(name.toLowerCase(), handler); if (this.showDebugLogLevel) Log.NotImportant(`Prefix command "${name}" registered.`); return builder; } }; return builder; } /** * Register slash commands via this * Usage Example: bot.registerSlashCommand() * .addCommand({ name: "lorem", description: "Send a Lorem Ipsum" }, (message, args) => ...) * .addCommand({ name: "hello", description: "Hello, World!" }, (message, args) => ...) * ...; */ registerSlashCommands() { const commandMap = new Map(); this.discordjs_client.on("interactionCreate", async (interaction) => { if (!interaction.isChatInputCommand()) return; const handler = commandMap.get(interaction.commandName); if (handler) { try { await handler(interaction); } catch (err) { Log.Error(`Error while executing the slash command "/${interaction.commandName}": ${err}`); await interaction.reply({ content: "An error has been occurred, please contact the creator of the bot.", ephemeral: true }); } } }); const builder = { addCommand: (command, handler) => { const name = command.name; const description = command.description; commandMap.set(name, handler); this.discordjs_client.once(djs.Events.ClientReady, async () => { const options = command.options?.map((opt) => { let type; switch (opt.type) { case "string": type = 3; break; case "number": type = 10; break; case "integer": type = 4; break; case "user": type = 6; break; default: throw new Error(`Unknown type: ${opt.type}`); } return { name: opt.name, description: opt.description, type, required: opt.required, min_value: opt.minValue, max_value: opt.maxValue, choices: opt.choices // facultatif }; }) ?? []; const data = { name, description, type: 1, options }; try { await this.discordjs_client.application?.commands.create(data); if (this.showDebugLogLevel) Log.NotImportant(`Slash command "/${name}" registered.`); } catch (err) { Log.Error(`Failed to register the slash command "/${name}": ${err}`); } }); return builder; } }; return builder; } registerEvent(event, handler, options = {}) { if (options.once) this.discordjs_client.once(event, handler); else this.discordjs_client.on(event, handler); } // All private things _getIntents__(ctxintents) { const intentMap = { Guilds: djs.GatewayIntentBits.Guilds, ManageGuild: djs.GatewayIntentBits.GuildInvites | djs.GatewayIntentBits.GuildModeration | djs.GatewayIntentBits.GuildScheduledEvents | djs.GatewayIntentBits.GuildExpressions | djs.GatewayIntentBits.GuildIntegrations, Voices: djs.GatewayIntentBits.GuildVoiceStates, Messages: djs.GatewayIntentBits.GuildMessages | djs.GatewayIntentBits.MessageContent | djs.GatewayIntentBits.DirectMessages | djs.GatewayIntentBits.DirectMessageReactions | djs.GatewayIntentBits.DirectMessageTyping, AutoMod: djs.GatewayIntentBits.AutoModerationConfiguration | djs.GatewayIntentBits.AutoModerationExecution, Webhooks: djs.GatewayIntentBits.GuildWebhooks, Presence: djs.GatewayIntentBits.GuildPresences, Members: djs.GatewayIntentBits.GuildMembers, }; return ctxintents.map(name => { const intent = intentMap[name]; if (intent === undefined) { throw Log.Error(`❌ Unknown intent alias: "${name}"`); } return intent; }); } login() { return this.discordjs_client.login(this.token); } } exports.Bot = Bot;