UNPKG

@jadl/cmd

Version:
157 lines (156 loc) 7.54 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.CommandHandler = void 0; const CommandFactory_1 = require("../handler/CommandFactory"); const Symbols_1 = require("../Symbols"); const v9_1 = require("discord-api-types/v9"); const CommandError_1 = require("../structures/CommandError"); const InteractionChanges_1 = require("../utils/InteractionChanges"); const builders_1 = require("@jadl/builders"); const form_data_1 = __importDefault(require("form-data")); const InteractionCommandResponse_1 = require("../structures/InteractionCommandResponse"); const WorkerInject_1 = require("../structures/WorkerInject"); class CommandHandler extends CommandFactory_1.CommandFactory { constructor(worker, injections, options = {}) { super(injections.filter((x) => !(x instanceof WorkerInject_1.WorkerInject))); this.worker = worker; const workerInjects = injections.filter((x) => x instanceof WorkerInject_1.WorkerInject); this.commands.forEach((x) => { if (x[Symbols_1.Symbols.injections]) workerInjects.push(...x[Symbols_1.Symbols.injections]); }); workerInjects.forEach((inject) => inject._setup(this.worker)); this.options = { interactionGuild: options.interactionGuild, ephemeralError: options.ephemeralError ?? true }; worker.on('INTERACTION_CREATE', (int) => { void this.handleInteraction(int); workerInjects.forEach((inject) => inject._onInteraction(int, this.worker)); }); worker.on('READY', () => { if (this.worker.comms.id === '0') void this.updateInteractions(); }); } formCommandEndpoint(guildId, interactionId) { // eslint-disable-next-line @typescript-eslint/restrict-template-expressions return `/applications/${this.worker.user.id}/${this.options.interactionGuild ?? guildId ? `/guilds/${this.options.interactionGuild ?? guildId}/` : ''}commands${interactionId ? `/${interactionId}` : ''}`; } async updateInteractions() { const oldInteractions = (await this.worker.api.get(this.formCommandEndpoint())); const newInteractions = this.commands.map((cmd) => cmd[Symbols_1.Symbols.interaction]); const changes = (0, InteractionChanges_1.SeekInteractions)(oldInteractions, newInteractions); await Promise.all([ ...[ ...changes.added, ...newInteractions.filter((x) => this.findCommand(x.name)?.[Symbols_1.Symbols.guild]) ].map(async (x) => await this.worker.api.post(this.formCommandEndpoint(this.findCommand(x.name)?.[Symbols_1.Symbols.guild]), { body: x })), ...changes.updated.map(async (x) => await this.worker.api.post(this.formCommandEndpoint(this.findCommand(x.name)?.[Symbols_1.Symbols.guild]), { body: x })), ...changes.deleted.map(async (x) => await this.worker.api.delete(this.formCommandEndpoint(undefined, x.id))) ]); this.worker.log(`Added ${changes.added.length}, deleted ${changes.deleted.length}, and updated ${changes.updated.length} command interactions`); } async handleInteraction(_interaction) { if (_interaction.type !== v9_1.InteractionType.ApplicationCommand) return; if (!_interaction.data || (_interaction.data.type !== v9_1.ApplicationCommandType.ChatInput && _interaction.data.type !== v9_1.ApplicationCommandType.User && _interaction.data.type !== v9_1.ApplicationCommandType.Message)) return; const command = this.findCommand(_interaction.data.name); if (!command) return; const interaction = { ..._interaction, responded: false }; // TODO sub commands const running = interaction.data.type === v9_1.ApplicationCommandType.ChatInput ? interaction.data.options && [ v9_1.ApplicationCommandOptionType.Subcommand, v9_1.ApplicationCommandOptionType.SubcommandGroup ].includes(interaction.data.options[0].type) ? interaction.data.options[0].name : Symbols_1.Symbols.baseCommand : Symbols_1.Symbols.baseCommand; const baseCommand = command[Symbols_1.Symbols.commands].find((x) => x.name === running); if (!baseCommand) return; try { for (const runner of baseCommand.canRun) { if (!(await runner(interaction, this))) return; } for (const runner of baseCommand.onRun) { await runner(interaction, this); } const res = await command[baseCommand.method]?.(interaction, this); await this.handleRes?.(res, interaction); } catch (err) { if (err instanceof CommandError_1.CommandError) { if (this.options.ephemeralError) { const formatted = (0, builders_1.parseMessage)(err.response); if (!(formatted instanceof form_data_1.default)) { err.response = { ...formatted, flags: v9_1.MessageFlags.Ephemeral }; } } void this.handleRes(err.response, interaction).catch((err) => { console.error(err); }); } else if (err instanceof Error) { err.message += ` (In command ${baseCommand.name === Symbols_1.Symbols.baseCommand ? command[Symbols_1.Symbols.commandName] : baseCommand.name.toString()})`; console.error(err); } else { console.error(err); } } } async editOriginal(res, int) { await this.worker.api.patch(`/webhooks/${this.worker.user.id}/${int.token}/messages/@original`, (0, builders_1.parse)(res)); } static async callback(worker, body, int) { return await worker.api.post(`/interactions/${int.id}/${int.token}/callback`, { body }); } async callback(body, int) { return await CommandHandler.callback(this.worker, body, int); } async handleRes(res, int) { if (res instanceof InteractionCommandResponse_1.InteractionCommandResponse) { await this.callback(res.data, int); } else if (int.responded) { await this.editOriginal(res, int); } else { const msg = (0, builders_1.parseMessage)(res); if (msg instanceof form_data_1.default) { await this.callback({ type: v9_1.InteractionResponseType.DeferredChannelMessageWithSource }, int); await this.editOriginal(res, int); } else { await this.callback({ type: v9_1.InteractionResponseType.ChannelMessageWithSource, data: msg }, int); } } } } exports.CommandHandler = CommandHandler;