UNPKG

@lilybird/transformers

Version:
559 lines (558 loc) 17.8 kB
import { GuildMember } from "./guild-member.js"; import { channelFactory } from "./channel.js"; import { Message } from "./message.js"; import { User } from "./user.js"; export function interactionFactory(client, interaction) { const data = interactionDataFactory(interaction); if ("guild_id" in interaction) return new GuildInteraction(client, interaction, true, data); return new DMInteraction(client, interaction, false, data); } function interactionDataFactory(interaction) { switch (interaction.type) { case 1: return undefined; case 2: case 4: { return new ApplicationCommandData(interaction.data); } case 3: { return new MessageComponentData(interaction.data); } case 5: { return new ModalSubmitData(interaction.data); } } } export class Interaction { client; id; applicationId; type; token; version = 1; appPermissions; locale; entitlements; authorizingIntegrationOwners; context; data; message = undefined; #inGuild; constructor(client, interaction, isGuild, data) { this.#inGuild = isGuild; this.client = client; this.id = interaction.id; this.applicationId = interaction.application_id; this.type = interaction.type; this.token = interaction.token; this.appPermissions = interaction.app_permissions; this.locale = interaction.locale; this.entitlements = interaction.entitlements; this.authorizingIntegrationOwners = interaction.authorizing_integration_owners; this.context = interaction.context; this.data = data; if ("message" in interaction) this.message = new Message(client, interaction.message); } async reply(content, options) { let flags = 0; let data; let files; if (typeof content === "string") { if (typeof options !== "undefined") { const { ephemeral, suppressEmbeds, componentsV2, flags: fl, files: f, ...obj } = options; flags |= fl ?? 0; if (componentsV2) flags |= 32768; if (ephemeral) flags |= 64; if (suppressEmbeds) flags |= 4; files = f; data = { ...obj, content, flags }; } else { data = { content, flags }; } } else { const { ephemeral, suppressEmbeds, componentsV2, flags: fl, files: f, ...obj } = content; flags |= fl ?? 0; if (componentsV2) flags |= 32768; if (ephemeral) flags |= 64; if (suppressEmbeds) flags |= 4; files = f; data = { ...obj, flags }; } await this.client.rest.createInteractionResponse(this.id, this.token, { type: 4, data }, files); } async deferReply(ephemeral = false) { await this.client.rest.createInteractionResponse(this.id, this.token, { type: 5, data: { flags: ephemeral ? 64 : 0 } }); } async deferComponentReply(ephemeral = false) { await this.client.rest.createInteractionResponse(this.id, this.token, { type: 6, data: { flags: ephemeral ? 64 : 0 } }); } async updateComponents(content, options) { let flags = 0; let data; let files; if (typeof content === "string") { if (typeof options !== "undefined") { const { ephemeral, suppressEmbeds, componentsV2, flags: fl, files: f, ...obj } = options; flags |= fl ?? 0; if (componentsV2) flags |= 32768; if (ephemeral) flags |= 64; if (suppressEmbeds) flags |= 4; files = f; data = { ...obj, content, flags }; } else { data = { content, flags }; } } else { const { ephemeral, suppressEmbeds, componentsV2, flags: fl, files: f, ...obj } = content; flags |= fl ?? 0; if (componentsV2) flags |= 32768; if (ephemeral) flags |= 64; if (suppressEmbeds) flags |= 4; files = f; data = { ...obj, flags }; } await this.client.rest.createInteractionResponse(this.id, this.token, { type: 7, data }, files); } async showChoices(choices) { await this.client.rest.createInteractionResponse(this.id, this.token, { type: 8, data: { choices } }); } async showModal(titleOrOptions, id, components) { let data; if (typeof titleOrOptions === "string") { data = { title: titleOrOptions, custom_id: id, components }; } else { const { id: custom_id, ...obj } = titleOrOptions; data = { ...obj, custom_id }; } await this.client.rest.createInteractionResponse(this.id, this.token, { type: 9, data }); } async followUp(content, options) { let flags = 0; let data; let files; if (typeof content === "string") { if (typeof options !== "undefined") { const { ephemeral, suppressEmbeds, componentsV2, flags: fl, files: f, ...obj } = options; flags |= fl ?? 0; if (componentsV2) flags |= 32768; if (ephemeral) flags |= 64; if (suppressEmbeds) flags |= 4; files = f; data = { ...obj, content, flags }; } else { data = { content, flags }; } } else { const { ephemeral, suppressEmbeds, componentsV2, flags: fl, files: f, ...obj } = content; flags |= fl ?? 0; if (componentsV2) flags |= 32768; if (ephemeral) flags |= 64; if (suppressEmbeds) flags |= 4; files = f; data = { ...obj, flags }; } return new Message(this.client, await this.client.rest.createFollowupMessage(this.client.user.id, this.token, data, files)); } async editReply(content, options) { let data; let files; if (typeof content === "string") { if (typeof options !== "undefined") { const { files: f, ...obj } = options; files = f; data = { ...obj, content }; } else { data = { content }; } } else ({ files, ...data } = content); return new Message(this.client, await this.client.rest.editOriginalInteractionResponse(this.client.user.id, this.token, data, files)); } async editFollowUp(messageId, content, options) { let data; let files; if (typeof content === "string") { if (typeof options !== "undefined") { const { files: f, ...obj } = options; files = f; data = { ...obj, content }; } else { data = { content }; } } else ({ files, ...data } = content); return new Message(this.client, await this.client.rest.editFollowupMessage(this.client.user.id, this.token, messageId, data, files)); } async deleteReply() { await this.client.rest.deleteOriginalInteractionResponse(this.client.application.id, this.token); } async deleteFollowUp(messageId) { await this.client.rest.deleteFollowupMessage(this.client.application.id, this.token, messageId); } async fetchOriginalReply() { return this.client.rest.getWebhookMessage(this.applicationId, this.token, "@original", {}); } isPingInteraction() { return this.type === 1; } isApplicationCommandInteraction() { return this.type === 2; } isAutocompleteInteraction() { return this.type === 4; } isMessageComponentInteraction() { return this.type === 3; } isModalSubmitInteraction() { return this.type === 5; } inGuild() { return this.#inGuild; } inDM() { return !this.#inGuild; } } export class GuildInteraction extends Interaction { guildId; channel; channelId; member; guildLocale; constructor(client, interaction, isDM, data) { super(client, interaction, isDM, data); this.guildId = interaction.guild_id; this.channel = channelFactory(client, interaction.channel); this.channelId = interaction.channel_id; this.member = new GuildMember(client, interaction.member); this.guildLocale = interaction.guild_locale; } } export class DMInteraction extends Interaction { user; constructor(client, interaction, isDM, data) { super(client, interaction, isDM, data); this.user = new User(client, interaction.user); } } export class ApplicationCommandData { id; name; type; resolved; guildId; targetId; #stringOptions = new Map(); #numberOptions = new Map(); #integerOptions = new Map(); #booleanOptions = new Map(); #userOptions = new Map(); #channelOptions = new Map(); #roleOptions = new Map(); #mentionableOptions = new Map(); #attachmentOptions = new Map(); #focused; #subCommandGroup; #subCommand; constructor(data) { this.id = data.id; this.name = data.name; this.type = data.type; this.resolved = data.resolved; this.guildId = data.guild_id; this.targetId = data.target_id; this.#parseOptions(data.options); } #parseOptions(options) { if (!options) return; for (let i = 0, { length } = options; i < length; i++) { const option = options[i]; if (option.focused) { if (typeof option.value === "undefined") continue; this.#focused = { name: option.name, value: option.value }; continue; } switch (option.type) { case 1: { this.#subCommand = option.name; this.#parseOptions(option.options); return; } case 2: { this.#subCommandGroup = option.name; this.#parseOptions(option.options); return; } case 3: { if (typeof option.value !== "string") throw new Error("Something unexpected happened"); this.#stringOptions.set(option.name, option.value); break; } case 4: { if (typeof option.value !== "number") throw new Error("Something unexpected happened"); this.#integerOptions.set(option.name, option.value); break; } case 10: { if (typeof option.value !== "number") throw new Error("Something unexpected happened"); this.#numberOptions.set(option.name, option.value); break; } case 5: { if (typeof option.value !== "boolean") throw new Error("Something unexpected happened"); this.#booleanOptions.set(option.name, option.value); break; } case 6: { if (typeof option.value !== "string") throw new Error("Something unexpected happened"); this.#userOptions.set(option.name, option.value); break; } case 7: { if (typeof option.value !== "string") throw new Error("Something unexpected happened"); this.#channelOptions.set(option.name, option.value); break; } case 8: { if (typeof option.value !== "string") throw new Error("Something unexpected happened"); this.#roleOptions.set(option.name, option.value); break; } case 9: { if (typeof option.value !== "string") throw new Error("Something unexpected happened"); this.#mentionableOptions.set(option.name, option.value); break; } case 11: { if (typeof this.resolved?.attachments === "undefined") throw new Error("Something unexpected happened"); if (typeof option.value !== "string") throw new Error("Something unexpected happened"); this.#attachmentOptions.set(option.name, this.resolved.attachments[option.value].url); break; } } } } isGuildApplicationCommand() { return typeof this.guildId !== "undefined"; } isUIApplicationCommand() { return typeof this.targetId !== "undefined"; } isChatInputCommand() { return this.type === 1; } isUserCommand() { return this.type === 2; } isMessageCommand() { return this.type === 3; } getFocused() { return this.#focused; } get subCommand() { return this.#subCommand; } get subCommandGroup() { return this.#subCommandGroup; } getString(name, assert = false) { if (assert) if (!this.#stringOptions.has(name)) throw new NotFoundError("String"); return this.#stringOptions.get(name); } getNumber(name, assert = false) { if (assert) if (!this.#numberOptions.has(name)) throw new NotFoundError("Number"); return this.#numberOptions.get(name); } getInteger(name, assert = false) { if (assert) if (!this.#integerOptions.has(name)) throw new NotFoundError("Integer"); return this.#integerOptions.get(name); } getBoolean(name, assert = false) { if (assert) if (!this.#booleanOptions.has(name)) throw new NotFoundError("Boolean"); return this.#booleanOptions.get(name); } getUser(name, assert = false) { if (assert) if (!this.#userOptions.has(name)) throw new NotFoundError("User"); return this.#userOptions.get(name); } getChannel(name, assert = false) { if (assert) if (!this.#channelOptions.has(name)) throw new NotFoundError("Channel"); return this.#channelOptions.get(name); } getRole(name, assert = false) { if (assert) if (!this.#roleOptions.has(name)) throw new NotFoundError("Role"); return this.#roleOptions.get(name); } getMentionable(name, assert = false) { if (assert) if (!this.#mentionableOptions.has(name)) throw new NotFoundError("Mentionable"); return this.#mentionableOptions.get(name); } getAttachment(name, assert = false) { if (assert) if (!this.#attachmentOptions.has(name)) throw new NotFoundError("Attachment"); return this.#attachmentOptions.get(name); } } class NotFoundError extends Error { constructor(type) { super(); this.message = `${type} was not found`; } } export class MessageComponentData { id; type; values; resolved; constructor(data) { this.id = data.custom_id; this.type = data.component_type; this.resolved = data.resolved; this.values = data.values; } isButton() { return this.type === 2; } isSelectMenu() { return this.type === 3 || (this.type >= 5 && this.type <= 8); } } export class ModalSubmitData { id; components; constructor(data) { this.id = data.custom_id; this.components = data.components; } }