UNPKG

@confis/discordapiwrapper

Version:

A fast and lightweight discord api wrapper.

1,443 lines (1,423 loc) 118 kB
var axios = require('axios'); var WebSocket = require('ws'); var assert = require('assert'); var console$1 = require('console'); /****************************************************************************** Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ***************************************************************************** */ /* global Reflect, Promise, SuppressedError, Symbol, Iterator */ function __classPrivateFieldGet(receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); } function __classPrivateFieldSet(receiver, state, value, kind, f) { if (kind === "m") throw new TypeError("Private method is not writable"); if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; } typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { var e = new Error(message); return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; }; var _Manager_cache; /** * Manages a cache of objects that extend the Base class. */ class Manager { constructor() { _Manager_cache.set(this, []); } get length() { return __classPrivateFieldGet(this, _Manager_cache, "f").length; } get array() { return __classPrivateFieldGet(this, _Manager_cache, "f"); } /** * Gets the element at the specified index. * @param index The index of the element to get. * @returns The element at the specified index, or null if the index is out of bounds. */ getByIndex(index) { return __classPrivateFieldGet(this, _Manager_cache, "f")[index]; } /** * Returns the elements of an array that meet the condition specified in a callback function. * * @param predicate A function that accepts up to three arguments. The filter method calls the predicate function one time for each element in the cache. */ filter(predicate) { return __classPrivateFieldGet(this, _Manager_cache, "f").filter(predicate); } /** * Adds a new element to the cache or multiple elements if an array is provided. * @param data The element(s) to add to the cache. * @returns The added element. */ cache(data) { if (!Array.isArray(data)) { if (__classPrivateFieldGet(this, _Manager_cache, "f").some(a => a.id === data.id)) { const index = __classPrivateFieldGet(this, _Manager_cache, "f").findIndex((a) => a.id === data.id); __classPrivateFieldGet(this, _Manager_cache, "f").splice(index, 1); __classPrivateFieldGet(this, _Manager_cache, "f").splice(index, 0, data); } else { __classPrivateFieldGet(this, _Manager_cache, "f").push(data); } return __classPrivateFieldGet(this, _Manager_cache, "f").find((a) => a.id === data.id); } else { for (const part of data) { if (__classPrivateFieldGet(this, _Manager_cache, "f").some(a => a.id === part.id)) { const index = __classPrivateFieldGet(this, _Manager_cache, "f").findIndex((a) => a.id === part.id); __classPrivateFieldGet(this, _Manager_cache, "f").splice(index, 1); __classPrivateFieldGet(this, _Manager_cache, "f").splice(index, 0, part); } else { __classPrivateFieldGet(this, _Manager_cache, "f").push(part); } } } } /** * Removes the element with the specified ID from the cache. * @param id The ID of the element to remove. */ delete(id) { const index = __classPrivateFieldGet(this, _Manager_cache, "f").findIndex((a) => a.id === id); if (index > -1) __classPrivateFieldGet(this, _Manager_cache, "f").splice(index, 1); } /** * Gets the element with the specified ID from the cache. * @param id The ID of the element to get. * @returns The element with the specified ID, or undefined if the element is not found. */ get(id) { return __classPrivateFieldGet(this, _Manager_cache, "f").find((a) => a.id === id); } /** * Updates the element with the specified ID in the cache. * @param id The ID of the element to update. * @param data The data to update the element with. */ update(id, data) { const index = __classPrivateFieldGet(this, _Manager_cache, "f").findIndex((a) => a.id === id); if (index > -1) { __classPrivateFieldGet(this, _Manager_cache, "f")[index]._patch(data); } } } _Manager_cache = new WeakMap(); /** * A bitfield of all available permissions. */ const PermissionsBitField = { CREATE_INSTANT_INVITE: 0x1, KICK_MEMBERS: 0x2, BAN_MEMBERS: 0x4, ADMINISTRATOR: 0x8, MANAGE_CHANNELS: 0x10, MANAGE_GUILD: 0x20, ADD_REACTIONS: 0x40, VIEW_AUDIT_LOG: 0x80, PRIORITY_SPEAKER: 0x100, STREAM: 0x200, VIEW_CHANNEL: 0x400, SEND_MESSAGES: 0x800, SEND_TTS_MESSAGES: 0x1000, MANAGE_MESSAGES: 0x2000, EMBED_LINKS: 0x4000, ATTACH_FILES: 0x8000, READ_MESSAGE_HISTORY: 0x10000, MENTION_EVERYONE: 0x20000, USE_EXTERNAL_EMOJIS: 0x40000, VIEW_GUILD_INSIGHTS: 0x80000, CONNECT: 0x100000, SPEAK: 0x200000, MUTE_MEMBERS: 0x400000, DEAFEN_MEMBERS: 0x800000, MOVE_MEMBERS: 0x1000000, USE_VAD: 0x2000000, CHANGE_NICKNAME: 0x4000000, MANAGE_NICKNAMES: 0x8000000, MANAGE_ROLES: 0x10000000, MANAGE_WEBHOOKS: 0x20000000, MANAGE_EMOJIS_AND_STICKERS: 0x40000000, USE_APPLICATION_COMMANDS: 0x800000000, REQUEST_TO_SPEAK: 0x100000000, MANAGE_EVENTS: 0x200000000, MANAGE_THREADS: 0x400000000, CREATE_PUBLIC_THREADS: 0x800000000, CREATE_PRIVATE_THREADS: 0x1000000000, USE_EXTERNAL_STICKERS: 0x2000000000, SEND_MESSAGES_IN_THREADS: 0x4000000000, START_EMBEDDED_ACTIVITIES: 0x8000000000, MODERATE_MEMBERS: 0x10000000000, }; /** * Calculates the permissions from a given bitfield. * @param permBitfield The bitfield to calculate the permissions from. * @returns An array of permissions. */ function PermissionCalculator(permBitfield) { const currentPermissions = []; const permissionUpper = Math.floor(permBitfield / 0x100000000); const permissionLower = Math.floor(permBitfield % 0x100000000); for (let key in PermissionsBitField) { if ((PermissionsBitField[key] >= 0x100000000 && permissionUpper & Math.floor(PermissionsBitField[key] / 0x100000000)) || (PermissionsBitField[key] < 0x100000000 && permissionLower & PermissionsBitField[key])) { currentPermissions.push(key); } else { continue; } } if (currentPermissions.includes("ADMINISTRATOR")) { for (let key in PermissionsBitField) { if (!currentPermissions.find((a) => a === key)) { currentPermissions.push(key); } } } return currentPermissions; } /** * Base class for all API objects. */ class Base { constructor(client) { Object.defineProperty(this, "_client", { value: client, configurable: false, enumerable: false, }); } /** * Returns the client */ get client() { return this._client; } _clone() { return Object.assign(Object.create(this), this); } /** * Returns a JSON representation of the object. */ toJson() { const dict = {}; for (const [k, v] of Object.entries(this)) { if (k !== "client") Reflect.set(dict, k, v?.id ?? v?.toJSON?.() ?? v); } return dict; } _patch(data) { } } var _a, _Routes_baseURL; class Routes { static Message(channelID, messageID) { return `${__classPrivateFieldGet(this, _a, "f", _Routes_baseURL)}/channels/${channelID}/messages/${messageID}`; } static ChannelTyping(channelID) { return `${__classPrivateFieldGet(this, _a, "f", _Routes_baseURL)}/channels/${channelID}/typing`; } static SendChannelMessage(channelID) { return `${__classPrivateFieldGet(this, _a, "f", _Routes_baseURL)}/channels/${channelID}/messages`; } static EditChannelMessage(channelID, messageID) { return `${__classPrivateFieldGet(this, _a, "f", _Routes_baseURL)}/channels/${channelID}/messages/${messageID}`; } static InteractionCallback(id, token) { return `${__classPrivateFieldGet(this, _a, "f", _Routes_baseURL)}/interactions/${id}/${token}/callback`; } static OriginalMessage(botID, token) { return `${__classPrivateFieldGet(this, _a, "f", _Routes_baseURL)}/webhooks/${botID}/${token}/messages/@original`; } static InteractionFollowUp(botID, token) { return `${__classPrivateFieldGet(this, _a, "f", _Routes_baseURL)}/webhooks/${botID}/${token}`; } static DMChannel() { return `${__classPrivateFieldGet(this, _a, "f", _Routes_baseURL)}/users/@me/channels`; } static GuildRoute(guildID) { return `${__classPrivateFieldGet(this, _a, "f", _Routes_baseURL)}/users/@me/guilds/${guildID}`; } static GuildBan(guildID, memberID) { return `${__classPrivateFieldGet(this, _a, "f", _Routes_baseURL)}/guilds/${guildID}/bans/${memberID}`; } static GuildKick(guildID, memberID) { return `${__classPrivateFieldGet(this, _a, "f", _Routes_baseURL)}/guilds/${guildID}/members/${memberID}`; } static GuildMember(guildID, memberID) { return `${__classPrivateFieldGet(this, _a, "f", _Routes_baseURL)}/guilds/${guildID}/members/${memberID}`; } static ChannelWebhooks(channelID) { return `${__classPrivateFieldGet(this, _a, "f", _Routes_baseURL)}/channels/${channelID}/webhooks`; } static ChannelWebhookSendMessage(webhookID, webhookToken) { return `${__classPrivateFieldGet(this, _a, "f", _Routes_baseURL)}webhooks/${webhookID}/${webhookToken}?wait=true`; } static Reaction(channelID, messageID, emoji) { return `${__classPrivateFieldGet(this, _a, "f", _Routes_baseURL)}channels/${channelID}/messages/${messageID}/reactions/${encodeURIComponent(emoji)}/@me`; } static GetReaction(channelID, messageID, emoji) { return `${__classPrivateFieldGet(this, _a, "f", _Routes_baseURL)}channels/${channelID}/messages/${messageID}/reactions/${encodeURIComponent(emoji)}`; } static UserReaction(channelID, messageID, emoji, userID) { return `${__classPrivateFieldGet(this, _a, "f", _Routes_baseURL)}channels/${channelID}/messages/${messageID}/reactions/${encodeURIComponent(emoji)}/${userID}`; } } _a = Routes; _Routes_baseURL = { value: "https://discord.com/api/v10/" }; var _Member_guildID, _Member_rolesIDs; /** Member object */ class Member extends Base { constructor(data, client) { super(client); _Member_guildID.set(this, void 0); _Member_rolesIDs.set(this, []); this.joinedAt = new Date(data.joined_at); this.id = data.user.id; this.nick = data.nick; __classPrivateFieldSet(this, _Member_guildID, data.guild_id, "f"); __classPrivateFieldSet(this, _Member_rolesIDs, data.roles, "f"); } toString() { return this.user.toString(); } /** * Get the guild of the member * * @returns A guild object */ get guild() { return this.client.guilds.get(__classPrivateFieldGet(this, _Member_guildID, "f")); } /** * Get the display name of the member * * @returns The display name of the member */ get displayName() { return this.nick || this.user.displayName; } /** * Get the roles of the member * * @returns An array of roles */ get roles() { const roles = []; for (let i = 0; i < __classPrivateFieldGet(this, _Member_rolesIDs, "f").length; i++) { const role = __classPrivateFieldGet(this, _Member_rolesIDs, "f")[i]; const roleObject = this.client.roles.get(role); if (roleObject) { roles.push(roleObject); } } return roles; } /** * Get the user object for the member * * @returns A user object */ get user() { return this.client.users.get(this.id); } /** * Get the permissions of the member * * @returns An array of permissions */ get permissions() { let perms = []; if (this.id === this.guild.ownerID) { for (const key in PermissionsBitField) { perms.push(key); } } else { for (let i = 0; i < this.roles.length; i++) { const permissions = this.roles[i].getPermissions(); for (let i = 0; i < permissions.length; i++) { const permission = permissions[i]; if (!perms.find((a) => a === permission)) { perms.push(permission); } } } } return perms; } /** * Update the member * * @param data New member data */ _patch(data) { Object.defineProperty(this, "roleIDs", { writable: true, configurable: true, }); __classPrivateFieldSet(this, _Member_rolesIDs, [], "f"); for (let i = 0; i < data.roles.length; i++) { const role = data.roles[i]; __classPrivateFieldGet(this, _Member_rolesIDs, "f").push(role.id); } } /** * Bans the member from the guild. * * @param [delete_message_seconds=0] Number of seconds to delete messages for. */ async ban(delete_message_seconds = 0) { await this.client.rest.put(Routes.GuildBan(__classPrivateFieldGet(this, _Member_guildID, "f"), this.id), { delete_message_seconds, }); } /** * Kicks the member from the guild. * * @param [delete_message_seconds=0] Number of seconds to delete messages for. */ async kick() { await this.client.rest.delete(Routes.GuildBan(__classPrivateFieldGet(this, _Member_guildID, "f"), this.id)); } /** * Sets the nickname of the member. * * @param nickname The new nickname for the member. */ async setNick(nickname) { await this.client.rest.patch(Routes.GuildMember(__classPrivateFieldGet(this, _Member_guildID, "f"), this.id === this.client.user.id ? "@me" : this.id), { nick: nickname, }); } /** * Timeout the member. * * @param communicationDisabledUntil The date until which the member's communication is re-enabled. */ async setCommunicationDisabled(communicationDisabledUntil) { await this.client.rest.patch(Routes.GuildMember(__classPrivateFieldGet(this, _Member_guildID, "f"), this.id === this.client.user.id ? "@me" : this.id), { communication_disabled_until: communicationDisabledUntil.toISOString(), }); } } _Member_guildID = new WeakMap(), _Member_rolesIDs = new WeakMap(); var _User_dmChannelId, _User_globalName; /** User object */ class User extends Base { constructor(data, client) { super(client); _User_dmChannelId.set(this, void 0); _User_globalName.set(this, void 0); this.username = data.username; this.id = data.id; __classPrivateFieldSet(this, _User_globalName, data.global_name, "f"); this.discriminator = data.discriminator; this.bot = data.bot; this.system = data.system; this.avatar = data.avatar; this.avatarDecoration = data.avatar_decoration_data; } toString() { return `<@${this.id}>`; } /** * Get the creation date of the user * * @returns The date when the user account was created */ get createdAt() { const discordEpoch = 1420070400000; const timestamp = ((BigInt(this.id) >> 22n) + BigInt(discordEpoch)); return new Date(Number(timestamp)); } /** * Get the display name of the user * * @returns The display name of the user if it exists, otherwise returns the username and discriminator */ get displayName() { if (!__classPrivateFieldGet(this, _User_globalName, "f")) { if (this.bot) { return `${this.username}#${this.discriminator}`; } else { return this.username; } } return __classPrivateFieldGet(this, _User_globalName, "f"); } /** * Get the avatar URL of the user * * @param options Avatar URL options * @returns The url of the user's avatar */ getAvatarURL(options) { let animated = options?.animated || false; return `https://cdn.discordapp.com/avatars/${this.id}/${this.avatar}.${animated ? "webp" : "png"}?size=${options?.size || 512}`; } /** * Get the DM channel of the user * * @returns A channel object */ async getDmChannel() { if (__classPrivateFieldGet(this, _User_dmChannelId, "f")) { return this.client.channels.get(__classPrivateFieldGet(this, _User_dmChannelId, "f")); } else { const request = await this.client.rest.post(Routes.DMChannel(), { recipient_id: this.id, }, false); this.client.channels.cache(new Channel(request, this.client)); __classPrivateFieldSet(this, _User_dmChannelId, request.id, "f"); return this.client.channels.get(request.id); } } /** * Send the user a message * * @param content The content of the message * @returns A message object */ async send(content) { const channel = await this.getDmChannel(); return await channel.send(content); } /** * Update the user * * @param data The new data of the user */ _patch(data) { this.username = data.username; __classPrivateFieldSet(this, _User_globalName, data.global_name, "f"); this.avatar = data.avatar; this.avatarDecoration = data.avatar_decoration_data; } } _User_dmChannelId = new WeakMap(), _User_globalName = new WeakMap(); /** Text input styles enum */ var TextInputStyles; (function (TextInputStyles) { TextInputStyles[TextInputStyles["SHORT"] = 1] = "SHORT"; TextInputStyles[TextInputStyles["PARAGRAPH"] = 2] = "PARAGRAPH"; })(TextInputStyles || (TextInputStyles = {})); /** Collector object */ class Collector { constructor(message, client, options) { this.listeners = []; this.messageID = message.id; this.client = client; this.type = options?.component_type || [exports.ComponentTypes.BUTTON]; this.filter = options?.filter; if (options?.timeout) { this.timeout = options?.timeout; this.timer = setTimeout(() => { this.end(); }, options.timeout); } } /** * Listen for events * @param event Event name * @param callback The event callback */ on(event, callback) { this.listeners.push({ event, callback, }); } /** * End the collector and execute the end event */ end() { const endListener = this.listeners.find((a) => a.event === "end"); if (endListener) endListener.callback(); for (let i = 0; i < this.client.collectors.length; i++) { const collector = this.client.collectors[i]; if (collector.messageID === this.messageID) { this.client.collectors.splice(i, 1); break; } } } /** * Reset the collector's timer */ resetTimer() { if (this.timeout) { clearTimeout(this.timer); this.timer = setTimeout(() => { this.end(); }, this.timeout); } else { console.warn("This collector does not have a timer."); } } off(event) { for (let i = 0; i < this.listeners.length; i++) { const listener = this.listeners[i]; if (listener.event === event) { this.listeners.splice(i, 1); break; } } } /** * Emit an event * @param event Event name * @param type Component type * @param args Event arguments */ emit(event, type, ...args) { if (!this.type.includes(type)) return; for (let i = 0; i < this.listeners.length; i++) { const listener = this.listeners[i]; if (listener.event === event) { listener.callback(...args); break; } } } } /** Modal collector object */ class ModalCollector { constructor(customID, client, options) { this.listeners = []; this.customID = customID; this.client = client; this.filter = options?.filter; if (options?.timeout) { this.timeout = options?.timeout; this.timer = setTimeout(() => { this.end(); }, options.timeout); } } /** * Listen for events * @param event Event name * @param callback The event callback */ on(event, callback) { this.listeners.push({ event, callback, }); } /** * End the collector and execute the end event */ end() { const endListener = this.listeners.find((a) => a.event === "end"); if (endListener) endListener.callback(null); for (let i = 0; i < this.client.modalCollectors.length; i++) { const collector = this.client.modalCollectors[i]; if (collector.customID === this.customID) { this.client.modalCollectors.splice(i, 1); break; } } } /** * Reset the collector's timer */ resetTimer() { if (this.timeout) { clearTimeout(this.timer); this.timer = setTimeout(() => { this.end(); }, this.timeout); } else { console.warn("This collector does not have a timer."); } } off(event) { for (let i = 0; i < this.listeners.length; i++) { const listener = this.listeners[i]; if (listener.event === event) { this.listeners.splice(i, 1); break; } } } /** * Emit an event * @param event Event name * @param args Event arguments */ emit(event, interaction) { for (let i = 0; i < this.listeners.length; i++) { const listener = this.listeners[i]; if (listener.event === event) { listener.callback(interaction); break; } } } } var _Guild_icon, _Guild_channelIDs; /** Guild object */ class Guild extends Base { constructor(data, client) { super(client); _Guild_icon.set(this, void 0); _Guild_channelIDs.set(this, []); this.members = new Manager(); this.id = data.id; this.name = data.name; this.ownerID = data.owner_id; this.memberCount = data.member_count; this.joinedAt = new Date(data.joined_at); __classPrivateFieldSet(this, _Guild_icon, data.icon, "f"); for (let i = 0; i < data.members.length; i++) { let member = data.members[i]; member.guild_id = this.id; this.members.cache(new Member(member, client)); } for (let i = 0; i < data.channels.length; i++) { const channel = data.channels[i]; __classPrivateFieldGet(this, _Guild_channelIDs, "f").push(channel.id); } } get iconURL() { return `https://cdn.discordapp.com/icons/${this.id}/${__classPrivateFieldGet(this, _Guild_icon, "f")}.png`; } /** * Get the creation date of the guild * * @returns The date when the guild was created */ get createdAt() { const discordEpoch = 1420070400000; const timestamp = ((BigInt(this.id) >> 22n) + BigInt(discordEpoch)); return new Date(Number(timestamp)); } /** * Get the current user's member object in this guild * @returns The member object */ get me() { return this.members.get(this.client.user.id); } /** * Get the roles in the guild * @returns An array of roles */ get roles() { return this.client.roles.array.filter((a) => a.guild_id === this.id); } /** * Get the channels in the guild * @returns An array of channels */ get channels() { const channels = []; for (let i = 0; i < __classPrivateFieldGet(this, _Guild_channelIDs, "f").length; i++) { const channelID = __classPrivateFieldGet(this, _Guild_channelIDs, "f")[i]; channels.push(this.client.channels.get(channelID)); } return channels; } /** * Leave the guild */ async leave() { await this.client.rest.delete(Routes.GuildRoute(this.id)); } } _Guild_icon = new WeakMap(), _Guild_channelIDs = new WeakMap(); var _Interaction_channelID, _Interaction_userID, _ButtonInteraction_custom_id; /** Interaction object */ class Interaction extends Base { constructor(data, client) { super(client); _Interaction_channelID.set(this, void 0); _Interaction_userID.set(this, void 0); this.acknowledged = false; this.interactionID = data.id; this.token = data.token; this.name = data.data.name; this.id = data.data.id; this.guildID = data.guild_id; if (data.member) { const guildExists = this.client.guilds.get(this.guildID); if (guildExists) { data.member.guild_id = this.guildID; this.client.guilds.get(this.guildID).members.cache(new Member(data.member, client)); } __classPrivateFieldSet(this, _Interaction_userID, data.member.user.id, "f"); } else { this.client.users.cache(new User(data.user, client)); __classPrivateFieldSet(this, _Interaction_userID, data.user.id, "f"); } this.description = data.description; this.type = data.type; __classPrivateFieldSet(this, _Interaction_channelID, data.channel_id, "f"); if (!this.client.channels.get(__classPrivateFieldGet(this, _Interaction_channelID, "f"))) { this.client.channels.cache(new Channel(data.channel, client)); } this.callbackURL = `${client.baseURL}interactions/${this.interactionID}/${this.token}/callback`; } /** * Get the guild of the interaction * @returns A guild object */ get guild() { return this.client.guilds.get(this.guildID); } /** * Get the channel of the interaction * @returns A channel object */ get channel() { return this.client.channels.get(__classPrivateFieldGet(this, _Interaction_channelID, "f")); } /** * Get the user of the interaction * @returns A user object */ get user() { return this.client.users.get(__classPrivateFieldGet(this, _Interaction_userID, "f")); } /** * Get the member of the interaction * @returns A member object */ get member() { return (this.client.guilds.get(this.guildID).members.get(__classPrivateFieldGet(this, _Interaction_userID, "f")) ?? null); } /** * Retrieves the original message sent through the webhook. * * @return {Promise<Message>} The original message as a `Message` object. * @throws {Error} If the request fails with a 400 status code. */ async getOriginalMessage() { return await this.client.rest.get(Routes.OriginalMessage(this.client.user.id, this.token)); } /** * Sends a reply message to the interaction. * * @param {string | ContentOptions} content - The content of the message. It can be a string or an object with optional properties like embeds, components, and file. * @param {number | undefined} deleteAfter - The number of milliseconds to wait before deleting the message. * @return {Promise<Message>} A promise that resolves to the sent message as a `Message` object. * @throws {Error} If the request fails with a 400 status code. */ async reply(content, deleteAfter) { if (this.acknowledged) { return this.followUp(content); } this.acknowledged = true; const msg = await this.client.rest.respondToInteraction(4, content, this.token, this.interactionID); if (deleteAfter) { setTimeout(() => { msg.delete({ throwError: false }); }, deleteAfter); } return msg; } async sendModal(content) { console$1.assert(!this.acknowledged, "Interaction has already been acknowledged"); this.acknowledged = true; await this.client.rest.post(Routes.InteractionCallback(this.interactionID, this.token), { type: 9, data: content.toJson(), }); } /** * Defer the reply to an interaction. * * @param {Object} options - Optional parameters for the deferral. * @param {boolean} options.ephemeral - Whether the reply should be ephemeral. * @return {Promise<void>} - A promise that resolves when the deferral is complete. */ async defer(options) { this.acknowledged = true; await this.client.rest.deferInteraction(this.interactionID, this.token, options); } /** * Edits the message with the given content. * * @param {string | ContentOptions} content - The content to edit the message with. It can be a string or an object with properties like content, embeds, components, ephemeral, and file. * @return {Promise<Message>} A promise that resolves to the edited message. * @throws {Error} If there is an error editing the message. */ async edit(content) { return await this.client.rest.editInteractionMessage(this.token, content); } /** * Sends a follow up with the given content * * @param content - The content to send a follow up with * @return {Promise<Message>} A promise that resolves to the sent message. * @throws {Error} If there is an error sending a follow up. */ async followUp(content) { return this.client.rest.followUpInteraction(this.token, content); } /** * Delete the interaction message */ async delete() { await this.client.rest.delete(Routes.OriginalMessage(this.client.user.id, this.token)); } } _Interaction_channelID = new WeakMap(), _Interaction_userID = new WeakMap(); /** Slash command interaction object */ class SlashCommandInteraction extends Interaction { constructor(data, client) { super(data, client); this.options = data.data.options; this.resolved = data.data.resolved; } /** * Returns whether the slash command has a sub command group or not. */ get hasSubCommandGroup() { if (Array.isArray(this.options)) { return (this.options.length && this.options[0].type == exports.ApplicationCommandOptionTypes.SUB_COMMAND_GROUP && this.options[0].options[0].type == exports.ApplicationCommandOptionTypes.SUB_COMMAND); } else return false; } /** * Returns sub command from the sub comand group */ get subCommandFromGroup() { if (!this.hasSubCommandGroup) return undefined; return new SubCommand(this.options[0].options[0]); } /** * Returns whether the slash command has a sub command or not. */ get hasSubCommand() { if (Array.isArray(this.options)) { return (this.options.length && this.options[0].type == exports.ApplicationCommandOptionTypes.SUB_COMMAND); } else return false; } /** * Returns sub command from the sub comand group */ get subCommand() { if (!this.hasSubCommand) return undefined; return new SubCommand(this.options[0]); } /** * Get the string option * @param name Name of the option * @returns Option data */ getString(name) { if (this.options) { return this.options.find((a) => a.type === exports.ApplicationCommandOptionTypes.STRING && a.name === name); } else return undefined; } /** * Get the user option * @param name Name of the option * @returns Option data */ getUser(name) { if (this.options) { return this.options.find((a) => a.type === exports.ApplicationCommandOptionTypes.USER && a.name === name); } else return undefined; } /** * Get the boolean option * @param name Name of the option * @returns Option data */ getBoolean(name) { if (this.options) { return this.options.find((a) => a.type === exports.ApplicationCommandOptionTypes.BOOLEAN && a.name === name); } else return undefined; } /** * Get the integer option * @param name Name of the option * @returns Option data */ getNumber(name) { if (this.options) { return this.options.find((a) => a.type === exports.ApplicationCommandOptionTypes.INTEGER && a.name === name)[0]; } else return undefined; } /** * Get the attachment option * @param name Name of the option * @returns Option data */ getAttachment(name) { const attachmentId = this.options.find((a) => a.type === exports.ApplicationCommandOptionTypes.ATTACHMENT && a.name === name); if (!attachmentId) return undefined; return this.resolved.attachments[attachmentId.value]; } } /** Button interaction object */ class ButtonInteraction extends Interaction { constructor(data, client) { super(data, client); _ButtonInteraction_custom_id.set(this, void 0); this.message = new Message(data.message, client); __classPrivateFieldSet(this, _ButtonInteraction_custom_id, data.data.custom_id, "f"); } /** * Gets the custom ID of the button component * @returns The custom ID string that was set when creating the button */ get customID() { return __classPrivateFieldGet(this, _ButtonInteraction_custom_id, "f"); } /** * Defer the interaction by sending a response with a type of 6. * * @return {Promise<void>} A promise that resolves when the defer request is successful. * @throws {Error} If the defer request returns a status of 400. */ async defer() { this.acknowledged = true; await this.client.rest.post(Routes.InteractionCallback(this.interactionID, this.token), { type: 6, }); } /** * Updates the content of a message with embeds, components, and files. * * @param {string | ContentOptions} content - The new content of the message or options for the message. * @return {Promise<Message>} A promise that resolves to the updated message. */ async update(content) { this.acknowledged = true; await this.client.rest.updateInteraction(this.token, this.interactionID, content); } } _ButtonInteraction_custom_id = new WeakMap(); class ModalInteraction extends Interaction { constructor(data, client) { super(data, client); this.data = { custom_id: data.data.custom_id, components: [] }; for (let i = 0; i < data.data.components.length; i++) { const component = data.data.components[i]; this.data.components.push({ type: component.type, data: { type: component.components[0].type, custom_id: component.components[0].custom_id, value: component.components[0].value } }); } } /** * Gets the custom ID of the modal component * @returns The custom ID string that was set when creating the modal */ get customID() { return this.data.custom_id; } } /** String select menu interaction */ class StringSelectMenuInteraction extends Interaction { constructor(data, client) { super(data, client); this.data = data.data; } /** * Gets the custom ID of the string select menu component * @returns The custom ID string that was set when creating the menu */ get customID() { return this.data.custom_id; } /** * Gets the selected values from the string select menu * @returns An array of strings containing the values of the selected options */ get values() { return this.data.values; } /** * Defer the interaction by sending a response with a type of 6. * * @return {Promise<void>} A promise that resolves when the defer request is successful. * @throws {Error} If the defer request returns a status of 400. */ async defer() { this.acknowledged = true; await this.client.rest.post(Routes.InteractionCallback(this.interactionID, this.token), { type: 6, }); } /** * Updates the content of a message with embeds, components, and files. * * @param {string | ContentOptions} content - The new content of the message or options for the message. * @return {Promise<Message>} A promise that resolves to the updated message. */ async update(content) { this.acknowledged = true; await this.client.rest.updateInteraction(this.token, this.interactionID, content); } } /** Message context interaction */ class MessageContextInteraction extends Interaction { constructor(data, client) { super(data, client); this.target_id = data.data.target_id; data.data.resolved.messages[this.target_id].guild_id = this.guildID; this.message = new Message(data.data.resolved.messages[this.target_id], client); } } /** User context interaction */ class UserContextInteraction extends Interaction { constructor(data, client) { super(data, client); this.target = { user: undefined, member: undefined, }; this.target_id = data.data.target_id; this.target.user = client.users.get(this.target_id) || client.users.cache(new User(data.data.resolved.users[this.target_id], this.client)); this.target.member = this.guild.members.get(this.target_id) || client.guilds.get(this.guildID).members.cache(new Member(data.data.resolved.members[this.target_id], client)); } } /** Sub Command object */ class SubCommand { constructor(data) { this.name = data.name; this.options = data.options; } /** * Get the string option * @param name Name of the option * @returns Option data */ getString(name) { if (this.options) { return this.options.find((a) => a.type === exports.ApplicationCommandOptionTypes.STRING && a.name === name); } else return undefined; } /** * Get the boolean option * @param name Name of the option * @returns Option data */ getBoolean(name) { if (this.options) { return this.options.find((a) => a.type === exports.ApplicationCommandOptionTypes.BOOLEAN && a.name === name); } else return undefined; } /** * Get the integer option * @param name Name of the option * @returns Option data */ getNumber(name) { if (this.options) { return this.options.find((a) => a.type === exports.ApplicationCommandOptionTypes.INTEGER && a.name === name); } else return undefined; } } /** Role object */ class Role extends Base { constructor(options, client) { super(client); Object.assign(this, options); } /** * Get the guild of the role * * @returns A guild object */ get guild() { return this.client.guilds.get(this.guild_id); } /** * Get the permissions of the role * * @returns An array of permissions */ getPermissions() { return PermissionCalculator(Number(this.permissions)); } /** * Check if the role has a specific permission * * @param permission The permission name * @returns Whether the role has this permission or not */ hasPermission(permission) { const permissionArray = this.getPermissions(); if (permissionArray.find((a) => a === permission)) return true; else return false; } /** * Update the role * * @param data The new data of the role */ _patch(data) { Object.assign(this, data); } toJson() { return { id: this.id, name: this.name, color: this.color, hoist: this.hoist, icon: this.icon, unicode_emoji: this.unicode_emoji, position: this.position, permissions: this.permissions, managed: this.managed, mentionable: this.mentionable, tags: { bot_id: this.tags?.bot_id, integration_id: this.tags?.integration_id, }, flags: this.flags, guild_id: this.guild_id, }; } } var _Message_authorID, _Message_mentionsIDs, _Message_messageSnapshots; /** Forwarded message object */ class MessageSnapshot { constructor(data) { (this.type = data.message.type), (this.content = data.message.content), (this.attachments = data.message.attachments); this.timestamp = new Date(data.message.timestamp).getTime(); this.editedTimestamp = new Date(data.message.edited_timestamp); } } /** Message object */ class Message extends Base { constructor(data, client) { super(client); _Message_authorID.set(this, void 0); _Message_mentionsIDs.set(this, []); _Message_messageSnapshots.set(this, void 0); this.id = data.id; this.channelID = data.channel_id; if (!this.client.channels.get(this.channelID)) { this.client.channels.cache(new Channel(data.channel, client)); } if (data.author) { this.client.users.cache(new User(data.author, client)); } if (data.guild_id && data.member) { data.member.user = data.author; data.member.guild_id = data.guild_id; this.client.guilds .get(data.guild_id) .members.cache(new Member(data.member, client)); } this.guildID = data.guild_id ?? null; __classPrivateFieldSet(this, _Message_authorID, data.author ? data.author.id : null, "f"); this.referencedMessage = data.referenced_message ? new Message(data.referenced_message, client) : null; __classPrivateFieldSet(this, _Message_messageSnapshots, data.message_snapshots ? data.message_snapshots : [], "f"); this.content = data.content; this.timestamp = new Date(data.timestamp); this.editedTimestamp = data.edited_timestamp ? new Date(data.edited_timestamp) : null; if (data.mentions.length) { for (let i = 0; i < data.mentions.length; i++) { const mention = data.mentions[i]; this.client.users.cache(new User(mention, client)); if (data.guild_id && mention.member) { mention.member.user = mention; mention.member.guild_id = data.guild_id; this.client.guilds .get(data.guild_id) .members.cache(new Member(mention.member, client)); } __classPrivateFieldGet(this, _Message_mentionsIDs, "f").push(mention.id); } } this.mentionEveryone = data.mention_everyone; this.pinned = data.pinned; this.type = data.type; this.attachments = data.attachments; this.embeds = data.embeds; } /** * Get the link of the message */ get jumpLink() { return `https://discord.com/channels/${this.guildID ?? "@me"}/${this.channelID}/${this.id}`; } /** * Returns if the message is forwarded */ get forwarded() { return Boolean(__classPrivateFieldGet(this, _Message_messageSnapshots, "f").length); } /** * Returns the forwarded message if it exists */ get forwardedMessage() { return Boolean(__classPrivateFieldGet(this, _Message_messageSnapshots, "f").length) ? new MessageSnapshot(__classPrivateFieldGet(this, _Message_messageSnapshots, "f")[0]) : null; } /** * Get all the mentioned users in the message * * @returns An array of users */ get mentions() { const users = []; for (let i = 0; i < __classPrivateFieldGet(this, _Message_mentionsIDs, "f").length; i++) { const userID = __classPrivateFieldGet(this, _Message_mentionsIDs, "f")[i]; const user = this.client.users.get(userID); if (user) users.push(user); } return users; } /** * Get the channel of the message * * @returns A channel object */ get channel() { return this.client.channels.get(this.channelID) ?? null; } /** * Get the author of the message * * @returns A user object */ get author() { return this.client.users.get(__classPrivateFieldGet(this, _Message_authorID, "f")) ?? null; } /** * Get the member object of the author of the message * * @returns A member object */ get member() { return (this.client.guilds.get(this.guildID)?.members.get(__classPrivateFieldGet(this, _Message_authorID, "f")) ?? null); } /** * Get the guild the message was sent in * * @returns A guild object */ get guild() { return this.client.guilds.get(this.guildID) ?? null; } /** * Get the content of the message */ toString() { return this.content; } /** * Create a collector for this message * * @param options Collector options * @returns A collector object */ createComponentCollector(options) { const index = this.client.collectors.push(new Collector(this, this.client, { ...options, component_type: options?.component_type ? options.component_type : undefined })) - 1; return this.client.collectors[index]; } /** * Get all the collectors associated with this message * * @returns An array of collectors */ get componentCollectors() { return this.client.collectors.filter((collector) => collector.messageID == this.id); } /** * Sends a reply message. * * @param {string | ContentOptions} content - The content of the message or options for the message. * @param {number} [deleteAfter] - The number of milliseconds to wait before deleting the message. * @return {Promise<Message>} A promise that resolves to the sent message. */ async reply(content, deleteAfter) { const msg = await this.client.rest.sendReplyChannelMessage(content, this.channelID, this.id, this.guildID); if (deleteAfter) { setTimeout(() => { msg.delete({ throwError: false }); }, deleteAfter); } return msg; } /** * Edits the content of a message.