@confis/discordapiwrapper
Version:
A fast and lightweight discord api wrapper.
1,417 lines (1,400 loc) • 146 kB
JavaScript
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)) {
__classPrivateFieldGet(this, _Manager_cache, "f").push(data);
return __classPrivateFieldGet(this, _Manager_cache, "f").find((a) => a.id === data.id);
}
else {
__classPrivateFieldGet(this, _Manager_cache, "f").push(...data);
}
}
/**
* 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();
/**
* 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 _Message_cachedAuthor, _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_cachedAuthor.set(this, void 0);
_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));
}
this.guildID = data.guild_id;
__classPrivateFieldSet(this, _Message_authorID, data.author ? data.author.id : null, "f");
__classPrivateFieldSet(this, _Message_cachedAuthor, data.author, "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) {
for (let i = 0; i < data.mentions.length; i++) {
__classPrivateFieldGet(this, _Message_mentionsIDs, "f").push(data.mentions[i].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}/${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() {
if (__classPrivateFieldGet(this, _Message_cachedAuthor, "f")) {
return new User(__classPrivateFieldGet(this, _Message_cachedAuthor, "f"), this.client);
}
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);
}
/**
* 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.
*
* @param {string | ContentOptions} content - The new content of the message. It can be a string or an object with
* the following properties:
* - content: The new content of the message.
* - file: An optional file to attach to the message. It can be a single file or an array of files.
* - embeds: An optional array of embeds to include in the message.
* - components: An optional array of components to include in the message.
* @return {Promise<Message>} A promise that resolves to the edited message.
* @throws {Error} If the message is not owned by the bot.
*/
async edit(content) {
if (this.author.id !== this.client.user.id)
throw new Error("This message cannot be editted as it's not owned by the bot.");
return await this.client.rest.editMessage(this.id, this.channelID, content);
}
/**
* Deletes this message from the channel.
*
* @param options - Optional configuration for deletion
* @param options.throwError - Whether to throw an error if deletion fails (default: true)
* @return {Promise<void>} A promise that resolves when the message is deleted
* @throws {Error} If throwError is true and the deletion request fails
*/
async delete(options = { throwError: true }) {
if (options.throwError) {
await this.client.rest.delete(Routes.Message(this.channelID, this.id));
}
else {
try {
await this.client.rest.delete(Routes.Message(this.channelID, this.id));
}
catch { }
}
}
/**
* React to a message with an emoji.
*
* @return {Promise<void>} - A Promise that resolves when the reaction has been successfully added.
* @throws {Error} - If the request to react to the message fails, an Error is thrown with the error message.
* @param emoji The emoji to react with.
*/
async react(emoji) {
if (emoji.startsWith("<:") && emoji.endsWith(">")) {
const splitted = emoji.split(":");
emoji = `${splitted[1]}:${splitted[2].replace(">", "")}`;
}
await this.client.rest.put(Routes.Reaction(this.channelID, this.id, emoji), {});
}
/**
* Remove the bot's reaction from the message.
*
* @return {Promise<void>} - A Promise that resolves when the reaction has been successfully removed.
* @throws {Error} - If the request to remove the reaction from the message fails, an Error is thrown with the error message.
* @param emoji The emoji to remove its reaction.
*/
async removeReaction(emoji) {
if (emoji.startsWith("<:") && emoji.endsWith(">")) {
const splitted = emoji.split(":");
emoji = `${splitted[1]}:${splitted[2].replace(">", "")}`;
}
await this.client.rest.delete(Routes.Reaction(this.channelID, this.id, emoji));
}
/**
* Remove a user's reaction from the message.
*
* @return {Promise<void>} - A Promise that resolves when the reaction has been successfully removed.
* @throws {Error} - If the request to remove the reaction from the message fails, an Error is thrown with the error message.
* @param emoji The emoji to remove its reaction.
* @param userID The user ID
*/
async deleteUserReaction(emoji, userID) {
if (emoji.startsWith("<:") && emoji.endsWith(">")) {
const splitted = emoji.split(":");
emoji = `${splitted[1]}:${splitted[2].replace(">", "")}`;
}
await this.client.rest.delete(Routes.UserReaction(this.channelID, this.id, emoji, userID));
}
/**
* Get all of the reactions of an emoji in the message.
*
* @param emoji The emoji to get the reactions of.
* @returns An array of users.
*/
async getReactions(emoji) {
if (emoji.startsWith("<:") && emoji.endsWith(">")) {
const splitted = emoji.split(":");
emoji = `${splitted[1]}:${splitted[2].replace(">", "")}`;
}
const data = await this.client.rest.get(Routes.GetReaction(this.channelID, this.id, emoji));
const users = [];
for (let i = 0; i < data.length; i++) {
const user = data[i];
users.push(new User(user, this.client));
}
return users;
}
}
_Message_cachedAuthor = new WeakMap(), _Message_authorID = new WeakMap(), _Message_mentionsIDs = new WeakMap(), _Message_messageSnapshots = new WeakMap();
/** Webhook message object */
class WebhookMessage extends Message {
constructor(data, client) {
super(data, client);
this.webhookID = data.webhook_id;
this.authorData = data.author;
}
}
var _Channel_guild_id;
/** Channel object */
class Channel extends Base {
constructor(data, client) {
super(client);
_Channel_guild_id.set(this, void 0);
this.id = data.id;
this.type = data.type;
this.position = data.position;
this.name = data.name;
this.permissions = data.permission_overwrites;
this.parent = data.parent_id;
this.topic = data.topic;
__classPrivateFieldSet(this, _Channel_guild_id, data.guild_id, "f");
}
/**
* Get the guild of this channel
* @returns A guild object
*/
get guild() {
return this.client.guilds.get(__classPrivateFieldGet(this, _Channel_guild_id, "f"));
}
/**
* Send a typing indicator to the channel
*/
async sendTyping() {
await this.client.rest.post(Routes.ChannelTyping(this.id), {});
}
/**
* Send a message to the channel
* @param content The content of the message
* @returns A message object
*/
async send(content) {
return await this.client.rest.sendChannelMessage(content, this.id);
}
/**
* Get all webhooks in the channel
* @returns An array of webhook objects
*/
async getWebhooks() {
const webhooks = [];
const data = await this.client.rest.get(Routes.ChannelWebhooks(this.id));
for (let i = 0; i < data.length; i++) {
webhooks.push(data[i]);
}
return webhooks;
}
/**
* Get a message from the channel by its ID.
*
* @param id ID of the message to get.
* @returns A message object.
*/
async getMessage(id) {
const data = await this.client.rest.get(Routes.Message(this.id, id));
return new Message(data, this.client);
}
/**
* Fetches messages from the channel
*
* @param limit - The number of messages to fetch (minimum: 1, default: 50, max: 100)
* @returns A Promise that resolves to an array of Message objects
* @throws {AssertionError} If limit is greater than 100 or less than 1
*
* @example
* ```typescript
* // Get the last 50 messages
* const messages = await channel.getMessages();
*
* // Get the last 10 messages
* const messages = await channel.getMessages(10);
* ```
*/
async getMessages(limit = 50) {
assert(limit <= 100, "Limit must be less than or equal to 100");
assert(limit >= 1, "Limit must be greater than or equal to 1");
const messages = await this.client.rest.get(`${Routes.SendChannelMessage(this.id)}?limit=${limit}`);
return messages.map((m) => new Message(m, this.client));
}
/**
* Update the channel
*
* @param data The new data of the channel
*/
_patch(data) {
Object.assign(this, data);
}
}
_Channel_guild_id = new WeakMap();
/** 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 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)
__classPrivateFieldSet(this, _Interaction_userID, data.member.user.id, "f");
else
__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) ||
new User(data.data.resolved.users[this.target_id], this.client);
this.target.member =
this.guild.members.get(this.target_id) ||
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;
}
}
/**
* 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;
}
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.joined_at = new Date(data.joined_at).getTime();
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.Gu