UNPKG

commandbot

Version:

A framework that helps you create your own Discord bot easier.

119 lines (118 loc) 5.55 kB
import { Interaction, Message, MessageEmbed } from "discord.js"; import { OperationSuccess } from "../../errors.js"; import { Command } from "./Command.js"; /** * Function (executable) command * @class * @extends {Command} */ export class FunctionCommand extends Command { /** * Command function (called on command execution) * @type {CommandFunction} * @private * @readonly */ _function; /** * Whether a SUCCESS message should be sent after executing the command function (when there is no other reply) * @type {boolean} * @public * @readonly */ announceSuccess; /** * Whether a reply should be visible only to the caller * * - NONE - bot replies are public and visible to everyone in a text channel * - INTERACTIONS - bot will mark responses to Discord interactions as ephemeral and they will only be visible to the command caller * - FULL - INTERACTIONS + responses to prefix interactions will be sent as direct messages to the command caller * * [Read more](https://support.discord.com/hc/pl/articles/1500000580222-Ephemeral-Messages-FAQ) * @type {EphemeralType} * @public * @readonly * @remarks Since ephemeral interactions cannot be deleted, a placeholding embed will be sent when there will be no response from the command function and _announceSuccess_ will be set to false (placeholding message uses _color_ and _title_ parameters from SUCCESS system message configuration) */ ephemeral; /** * Executable command constructor * @constructor * @param {CommandManager} manager - command manager attached to this command * @param {CommandType} type - command type * @param {FunctionCommandInit} options - command initailization options */ constructor(manager, type, options) { super(manager, type, { name: options.name, default_permission: options.default_permission, }); this._function = options.function ?? ((input) => { if (this.manager.help) return this.manager.help.generateMessage(input.interaction, this.name); else return; }); this.announceSuccess = options.announceSuccess ?? true; this.ephemeral = options.ephemeral ?? "NONE"; } /** * Invoke the command * @param {InputManager} input - input data manager * @returns {Promise<void>} A *Promise* that resolves after the function command is completed * @public * @async */ async start(input) { if (input.interaction instanceof Interaction && !input.interaction.isCommand() && !input.interaction.isContextMenu()) throw new TypeError(`Interaction not recognized`); if (input.interaction instanceof Interaction) await input.interaction.deferReply({ ephemeral: this.ephemeral !== "NONE" }); await this.handleReply(input.interaction, await this._function(input)); } /** * Reply handler * @param {Message | Interaction} interaction - Discord interaction object * @param {void | string | MessageEmbed | ReplyMessageOptions} result - result of command function execution * @return {Promise<void>} * @private * @async */ async handleReply(interaction, result) { if (interaction instanceof Interaction && !interaction.isCommand() && !interaction.isContextMenu()) throw new TypeError(`Interaction not recognized`); if (result instanceof Object && ("content" in result || "embeds" in result || "files" in result || "components" in result || "sticker" in result)) { if (interaction instanceof Message) this.ephemeral === "FULL" ? await interaction.member?.send(result) : await interaction.reply(result); else if (interaction instanceof Interaction) await interaction.editReply(result); } else if (typeof result == "string") { if (interaction instanceof Message) this.ephemeral === "FULL" ? await interaction?.member?.send({ content: result }) : await interaction?.reply({ content: result }); else if (interaction instanceof Interaction) await interaction.editReply({ content: result, }); } else if (result instanceof MessageEmbed) { if (interaction instanceof Message) this.ephemeral === "FULL" ? await interaction.member?.send({ embeds: [result] }) : await interaction?.reply({ embeds: [result] }); else if (interaction instanceof Interaction) await interaction.editReply({ embeds: [result] }); } else if (this.announceSuccess && (interaction instanceof Interaction ? !interaction.replied : true)) { throw new OperationSuccess(this); } else if (interaction instanceof Interaction && !interaction.replied) { this.ephemeral !== "NONE" ? await interaction.editReply({ embeds: [new MessageEmbed().setTitle(this.manager.client.messages.SUCCESS.title).setColor(this.manager.client.messages.SUCCESS.accentColor ?? "#00ff00")], }) : await interaction.deleteReply(); } } }