@confis/discordapiwrapper
Version:
A fast and lightweight discord api wrapper.
1,265 lines (1,247 loc) • 60 kB
JavaScript
var axios = require('axios');
require('ws');
var assert = require('assert');
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;
};
/**
* 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_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.
*
* @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_authorID = new WeakMap(), _Message_mentionsIDs = new WeakMap(), _Message_messageSnapshots = new WeakMap();
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 || [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;
}
}
}
}
/**
* 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,
};
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();
/** Enum for types of webhook */
var WebhookTypes;
(function (WebhookTypes) {
WebhookTypes[WebhookTypes["INCOMING"] = 1] = "INCOMING";
WebhookTypes[WebhookTypes["CHANNEL_FOLLOWER"] = 2] = "CHANNEL_FOLLOWER";
WebhookTypes[WebhookTypes["APPLICATION"] = 3] = "APPLICATION";
})(WebhookTypes || (WebhookTypes = {}));
/** Enum for types of interaction contexts */
var InteractionContextTypes;
(function (InteractionContextTypes) {
InteractionContextTypes[InteractionContextTypes["GUILD"] = 0] = "GUILD";
InteractionContextTypes[InteractionContextTypes["BOT_DM"] = 1] = "BOT_DM";
InteractionContextTypes[InteractionContextTypes["PRIVATE_CHANNEL"] = 2] = "PRIVATE_CHANNEL";
})(InteractionContextTypes || (InteractionContextTypes = {}));
/** Enum for types of interaction integration */
var InteractionIntegrationTypes;
(function (InteractionIntegrationTypes) {
InteractionIntegrationTypes[InteractionIntegrationTypes["GUILD_INSTALL"] = 0] = "GUILD_INSTALL";
InteractionIntegrationTypes[InteractionIntegrationTypes["USER_INSTALL"] = 1] = "USER_INSTALL";
})(InteractionIntegrationTypes || (InteractionIntegrationTypes = {}));
/** Enum for types of message */
var APIMessageTypes;
(function (APIMessageTypes) {
APIMessageTypes[APIMessageTypes["DEFAULT"] = 0] = "DEFAULT";
APIMessageTypes[APIMessageTypes["RECIPIENT_ADD"] = 1] = "RECIPIENT_ADD";
APIMessageTypes[APIMessageTypes["RECIPIENT_REMOVE"] = 2] = "RECIPIENT_REMOVE";
APIMessageTypes[APIMessageTypes["CALL"] = 3] = "CALL";
APIMessageTypes[APIMessageTypes["CHANNEL_NAME_CHANGE"] = 4] = "CHANNEL_NAME_CHANGE";
APIMessageTypes[APIMessageTypes["CHANNEL_ICON_CHANGE"] = 5] = "CHANNEL_ICON_CHANGE";
APIMessageTypes[APIMessageTypes["CHANNEL_PINNED_MESSAGE"] = 6] = "CHANNEL_PINNED_MESSAGE";
APIMessageTypes[APIMessageTypes["USER_JOIN"] = 7] = "USER_JOIN";
APIMessageTypes[APIMessageTypes["GUILD_BOOST"] = 8] = "GUILD_BOOST";
APIMessageTypes[APIMessageTypes["GUILD_BOOST_TIER_1"] = 9] = "GUILD_BOOST_TIER_1";
APIMessageTypes[APIMessageTypes["GUILD_BOOST_TIER_2"] = 10] = "GUILD_BOOST_TIER_2";
APIMessageTypes[APIMessageTypes["GUILD_BOOST_TIER_3"] = 11] = "GUILD_BOOST_TIER_3";
APIMessageTypes[APIMessageTypes["CHANNEL_FOLLOW_ADD"] = 12] = "CHANNEL_FOLLOW_ADD";
APIMessageTypes[APIMessageTypes["GUILD_DISCOVERY_DISQUALIFIED"] = 14] = "GUILD_DISCOVERY_DISQUALIFIED";
APIMessageTypes[APIMessageTypes["GUILD_DISCOVERY_REQUALIFIED"] = 15] = "GUILD_DISCOVERY_REQUALIFIED";
APIMessageTypes[APIMessageTypes["GUILD_DISCOVERY_GRACE_PERIOD_INITIAL_WARNING"] = 16] = "GUILD_DISCOVERY_GRACE_PERIOD_INITIAL_WARNING";
APIMessageTypes[APIMessageTypes["GUILD_DISCOVERY_GRACE_PERIOD_FINAL_WARNING"] = 17] = "GUILD_DISCOVERY_GRACE_PERIOD_FINAL_WARNING";
APIMessageTypes[APIMessageTypes["THREAD_CREATED"] = 18] = "THREAD_CREATED";
APIMessageTypes[APIMessageTypes["REPLY"] = 19] = "REPLY";
APIMessageTypes[APIMessageTypes["CHAT_INPUT_COMMAND"] = 20] = "CHAT_INPUT_COMMAND";
APIMessageTypes[APIMessageTypes["THREAD_STARTER_MESSAGE"] = 21] = "THREAD_STARTER_MESSAGE";
APIMessageTypes[APIMessageTypes["GUILD_INVITE_REMINDER"] = 22] = "GUILD_INVITE_REMINDER";
APIMessageTypes[APIMessageTypes["CONTEXT_MENU_COMMAND"] = 23] = "CONTEXT_MENU_COMMAND";
APIMessageTypes[APIMessageTypes["AUTO_MODERATION_ACTION"] = 24] = "AUTO_MODERATION_ACTION";
APIMessageTypes[APIMessageTypes["ROLE_SUBSCRIPTION_PURCHASE"] = 25] = "ROLE_SUBSCRIPTION_PURCHASE";
APIMessageTypes[APIMessageTypes["INTERACTION_PREMIUM_UPSELL"] = 26] = "INTERACTION_PREMIUM_UPSELL";
APIMessageTypes[APIMessageTypes["STAGE_START"] = 27] = "STAGE_START";
APIMessageTypes[APIMessageTypes["STAGE_END"] = 28] = "STAGE_END";
APIMessageTypes[APIMessageTypes["STAGE_SPEAKER"] = 29] = "STAGE_SPEAKER";
APIMessageTypes[APIMessageTypes["STAGE_TOPIC"] = 31] = "STAGE_TOPIC";
APIMessageTypes[APIMessageTypes["GUILD_APPLICATION_PREMIUM_SUBSCRIPTION"] = 32] = "GUILD_APPLICATION_PREMIUM_SUBSCRIPTION";
APIMessageTypes[APIMessageTypes["GUILD_INCIDENT_ALERT_MODE_ENABLED"] = 36] = "GUILD_INCIDENT_ALERT_MODE_ENABLED";
APIMessageTypes[APIMessageTypes["GUILD_INCIDENT_ALERT_MODE_DISABLED"] = 37] = "GUILD_INCIDENT_ALERT_MODE_DISABLED";
APIMessageTypes[APIMessageTypes["GUILD_INCIDENT_REPORT_RAID"] = 38] = "GUILD_INCIDENT_REPORT_RAID";
APIMessageTypes[APIMessageTypes["GUILD_INCIDENT_REPORT_FALSE_ALARM"] = 39] = "GUILD_INCIDENT_REPORT_FALSE_ALARM";
APIMessageTypes[APIMessageTypes["PURCHASE_NOTIFICATION"] = 44] = "PURCHASE_NOTIFICATION";
APIMessageTypes[APIMessageTypes["POLL_RESULT"] = 46] = "POLL_RESULT";
})(APIMessageTypes || (APIMessageTypes = {}));
/**
* Enum for types of application commands
*/
var ApplicationCommandTypes;
(function (ApplicationCommandTypes) {
ApplicationCommandTypes[ApplicationCommandTypes["CHAT_INPUT"] = 1] = "CHAT_INPUT";
ApplicationCommandTypes[ApplicationCommandTypes["USER"] = 2] = "USER";
ApplicationCommandTypes[ApplicationCommandTypes["MESSAGE"] = 3] = "MESSAGE";
})(ApplicationCommandTypes || (ApplicationCommandTypes = {}));
/**
* Enum for types of interactions
*/
var InteractionTypes;
(function (InteractionTypes) {
InteractionTypes[InteractionTypes["PING"] = 1] = "PING";
InteractionTypes[InteractionTypes["APPLICATION_COMMAND"] = 2] = "APPLICATION_COMMAND";
InteractionTypes[InteractionTypes["MESSAGE_COMPONENT"] = 3] = "MESSAGE_COMPONENT";
InteractionTypes[InteractionTypes["APPLICATION_COMMAND_AUTOCOMPLETE"] = 4] = "APPLICATION_COMMAND_AUTOCOMPLETE";
InteractionTypes[InteractionTypes["MODAL_SUBMIT"] = 5] = "MODAL_SUBMIT";
})(InteractionTypes || (InteractionTypes = {}));
/**
* Enum for types of components
*/
var ComponentTypes;
(function (ComponentTypes) {
ComponentTypes[ComponentTypes["ACTION_ROW"] = 1] = "ACTION_ROW";
ComponentTypes[ComponentTypes["BUTTON"] = 2] = "BUTTON";
ComponentTypes[ComponentTypes["STRING_SELECT"] = 3] = "STRING_SELECT";
ComponentTypes[ComponentTypes["TEXT_INPUT"] = 4] = "TEXT_INPUT";
})(ComponentTypes || (ComponentTypes = {}));
/**
* Enum for types of button styles
*/
var ButtonStyles;
(function (ButtonStyles) {
ButtonStyles[ButtonStyles["PRIMARY"] = 1] = "PRIMARY";
ButtonStyles[ButtonStyles["SECONDARY"] = 2] = "SECONDARY";
ButtonStyles[ButtonStyles["SUCCESS"] = 3] = "SUCCESS";
ButtonStyles[ButtonStyles["DANGER"] = 4] = "DANGER";
ButtonStyles[ButtonStyles["LINK"] = 5] = "LINK";
})(ButtonStyles || (ButtonStyles = {}));
/**
* Enum for types of activity
*/
var ActivityTypes;
(function (ActivityTypes) {
ActivityTypes[ActivityTypes["GAME"] = 0] = "GAME";
ActivityTypes[ActivityTypes["STREAMING"] = 1] = "STREAMING";
ActivityTypes[ActivityTypes["LISTENING"] = 2] = "LISTENING";
ActivityTypes[ActivityTypes["WATCHING"] = 3] = "WATCHING";
ActivityTypes[ActivityTypes["CUSTOM"] = 4] = "CUSTOM";
ActivityTypes[ActivityTypes["COMPETING"] = 5] = "COMPETING";
})(ActivityTypes || (ActivityTypes = {}));
/**
* Enum for types of application command options
*/
var ApplicationCommandOptionTypes;
(function (ApplicationCommandOptionTypes) {
ApplicationCommandOptionTypes[ApplicationCommandOptionTypes["SUB_COMMAND"] = 1] = "SUB_COMMAND";
ApplicationCommandOptionTypes[ApplicationCommandOptionTypes["SUB_COMMAND_GROUP"] = 2] = "SUB_COMMAND_GROUP";
ApplicationCommandOptionTypes[ApplicationCommandOptionTypes["STRING"] = 3] = "STRING";
ApplicationCommandOptionTypes[ApplicationCommandOptionTypes["INTEGER"] = 4] = "INTEGER";
ApplicationCommandOptionTypes[ApplicationCommandOptionTypes["BOOLEAN"] = 5] = "BOOLEAN";
ApplicationCommandOptionTypes[ApplicationCommandOptionTypes["USER"] = 6] = "USER";
ApplicationCommandOptionTypes[ApplicationCommandOptionTypes["CHANNEL"] = 7] = "CHANNEL";
ApplicationCommandOptionTypes[ApplicationCommandOptionTypes["ROLE"] = 8] = "ROLE";
ApplicationCommandOptionTypes[ApplicationCommandOptionTypes["MENTIONABLE"] = 9] = "MENTIONABLE";
ApplicationCommandOptionTypes[ApplicationCommandOptionTypes["NUMBER"] = 10] = "NUMBER";
ApplicationCommandOptionTypes[ApplicationCommandOptionTypes["ATTACHMENT"] = 11] = "ATTACHMENT";
})(ApplicationCommandOptionTypes || (ApplicationCommandOptionTypes = {}));
/**
* Enum for types of channels
*/
var ChannelTypes;
(function (ChannelTypes) {
ChannelTypes[ChannelTypes["TEXT"] = 0] = "TEXT";
ChannelTypes[ChannelTypes["DM"] = 1] = "DM";
ChannelTypes[ChannelTypes["CATEGORY"] = 4] = "CATEGORY";
})(ChannelTypes || (ChannelTypes = {}));
var OverwriteObjectTypes;
(function (OverwriteObjectTypes) {
OverwriteObjectTypes[OverwriteObjectTypes["ROLE"] = 0] = "ROLE";
OverwriteObjectTypes[OverwriteObjectTypes["MEMBER"] = 1] = "MEMBER";
})(OverwriteObjectTypes || (OverwriteObjectTypes = {}));
/** Enum of types of messages */
var MessageTypes;
(function (MessageTypes) {
MessageTypes[MessageTypes["DEFAULT"] = 0] = "DEFAULT";
MessageTypes[MessageTypes["USER_JOIN"] = 7] = "USER_JOIN";
MessageTypes[MessageTypes["REPLY"] = 19] = "REPLY";
})(MessageTypes || (MessageTypes = {}));
/** Bot Intents */
var Intents;
(function (Intents) {
Intents[Intents["GUILDS"] = 1] = "GUILDS";
Intents[Intents["GUILD_MEMBERS"] = 2] = "GUILD_MEMBERS";
Intents[Intents["GUILD_BANS"] = 4] = "GUILD_BANS";
Intents[Intents["GUILD_EMOJIS_AND_STICKERS"] = 8] = "GUILD_EMOJIS_AND_STICKERS";
Intents[Intents["GUILD_INTEGRATIONS"] = 16] = "GUILD_INTEGRATIONS";
Intents[Intents["GUILD_WEBHOOKS"] = 32] = "GUILD_WEBHOOKS";
Intents[Intents["GUILD_INVITES"] = 64] = "GUILD_INVITES";
Intents[Intents["GUILD_VOICE_STATES"] = 128] = "GUILD_VOICE_STATES";
Intents[Intents["GUILD_PRESENCES"] = 256] = "GUILD_PRESENCES";
Intents[Intents["GUILD_MESSAGES"] = 512] = "GUILD_MESSAGES";
Intents[Intents["GUILD_MESSAGE_REACTIONS"] = 1024] = "GUILD_MESSAGE_REACTIONS";
Intents[Intents["GUILD_MESSAGE_TYPING"] = 2048] = "GUILD_MESSAGE_TYPING";
Intents[Intents["DIRECT_MESSAGES"] = 4096] = "DIRECT_MESSAGES";
Intents[Intents["DIRECT_MESSAGE_REACTIONS"] = 8192] = "DIRECT_MESSAGE_REACTIONS";
Intents[Intents["DIRECT_MESSAGE_TYPING"] = 16384] = "DIRECT_MESSAGE_TYPING";
Intents[Intents["MESSAGE_CONTENT"] = 32768] = "MESSAGE_CONTENT";
Intents[Intents["GUILD_SCHEDULED_EVENTS"] = 65536] = "GUILD_SCHEDULED_EVENTS";
Intents[Intents["ALL"] = 131071] = "ALL";
})(Intents || (Intents = {}));
/** Text input styles enum */
var TextInputStyles;
(function (TextInputStyles) {
TextInputStyles[TextInputStyles["SHORT"] = 1] = "SHORT";
TextInputStyles[TextInputStyles["PARAGRAPH"] = 2] = "PARAGRAPH";
})(TextInputStyles || (TextInputStyles = {}));
var _Rest_client, _Rest_pendingRequests, _Rest_requestQueue, _Rest_maxConcurrentRequests, _Rest_activeRequests;
/**
* Converts a JSON object to a Blob object.
*
* @param json - The JSON object to convert.
* @returns The Blob object.
*/
function JSONToBlob(json) {
return new Blob([JSON.stringify(json)], {
type: "application/json",
});
}
/**
* Converts a JSONCache object to a FormData object, including any files.
*
* @param json - The JSONCache object to convert.
* @param files - The files to include in the FormData object.
* @returns The FormData object.
*/
function JSONToFormDataWithFile(json, ...files) {
if (!files.length)
return json;
const formData = new FormData();
json.attachments = [];
formData.set("payload_json", JSONToBlob(json), "");
for (let i = 0; i < files.length; i++) {
const file = files[i];
json.attachments.push({
id: i,
filename: file.name,
});
formData.set(`files[${i}]`, new Blob([file.buffer]), file.name);
}
return formData;
}
/**
* Waits for a specified amount of time.
*
* @param ms - The amount of time to wait in milliseconds.
* @returns A Promise that resolves after the specified time.
*/
async function wait(ms) {
return new Promise((res) => setTimeout(res, ms));
}
/**
* The REST API client for interacting with Discord's API.
*/
class Rest {
constructor(client) {
_Rest_client.set(this, void 0);
_Rest_pendingRequests.set(this, new Map());
_Rest_requestQueue.set(this, []);
_Rest_maxConcurrentRequests.set(this, 5);
_Rest_activeRequests.set(this, 0);
// Optimize axios instance
this.axiosInstance = axios.create({
timeout: 15000,
maxRedirects: 5,
headers: {
'Connection': 'keep-alive',
'Keep-Alive': 'timeout=5, max=1000'
}
});
__classPrivateFieldSet(this, _Rest_client, client, "f");
}
async processQueue() {
var _a, _b;
if (__classPrivateFieldGet(this, _Rest_activeRequests, "f") >= __classPrivateFieldGet(this, _Rest_maxConcurrentRequests, "f") || __classPrivateFieldGet(this, _Rest_requestQueue, "f").length === 0) {
return;
}
__classPrivateFieldSet(this, _Rest_activeRequests, (_a = __classPrivateFieldGet(this, _Rest_activeRequests, "f"), _a++, _a), "f");
const request = __classPrivateFieldGet(this, _Rest_requestQueue, "f").shift();
try {
await request();
}
finally {
__classPrivateFieldSet(this, _Rest_activeRequests, (_b = __classPrivateFieldGet(this, _Rest_activeRequests, "f"), _b--, _b), "f");
this.processQueue();
}
}
async executeRequest(key, requestFn) {
if (__classPrivateFieldGet(this, _Rest_pendingRequests, "f").has(key)) {
return __classPrivateFieldGet(this, _Rest_pendingRequests, "f").get(key);
}
const promise = new Promise((resolve, reject) => {
__classPrivateFieldGet(this, _Rest_requestQueue, "f").push(async () => {
try {
const result = await requestFn();
resolve(result);
}
catch (error) {
reject(error);
}
});
});
__classPrivateFieldGet(this, _Rest_pendingRequests, "f").set(key, promise);
this.processQueue();
return promise.finally(() => {
__classPrivateFieldGet(this, _Rest_pendingRequests, "f").delete(key);
});
}
/**
* Deletes a resource from the Discord API.
*
* @param route - The route to delete.
* @returns The deleted resource.
*/
async delete(route) {
const requestKey = `DELETE:${route}`;
return this.executeRequest(requestKey, async () => {
const response = await this.axiosInstance.delete(route, {
headers: __classPrivateFieldGet(this, _Rest_client, "f").getHeaders(),
validateStatus: () => true,
});
if (![200, 204].includes(response.status)) {
if (response.data.retry_after !== undefined) {
await wait(response.data.retry_after * 1000);
return this.delete(route);
}
throw new Error(response.data.message);
}
return response.data;
});
}
/**
* Sends a POST request to the Discord API.
*
* @param route - The route to send the request to.
* @param data - The data to send with the request.
* @param formData - Whether the data is in FormData format.
* @returns The response data.
*/
async post(route, data, formData) {
const requestKey = `POST:${route}`;
return this.executeRequest(requestKey, async () => {
const headers = __classPrivateFieldGet(this, _Rest_client, "f").getHeaders(formData ? "multipart/form-data" : "application/json");
try {
const response = await axios.post(route, data, {
headers,
validateStatus: null
});
if (response.status === 429) {
await wait(response.data.retry_after * 1000);
return this.post(route, data, formData);
}
if (response.status >= 400) {
throw new Error(response.data.message || 'Request failed');
}
return response.data;
}
catch (error) {
if (error.response?.status === 429) {
await wait(error.response.data.retry_after * 1000);
return this.post(route, data, formData);
}
throw error;
}
});
}
/**
* Sends a GET request to the Discord API.
*
* @param route - The route to send the request to.
* @returns The response data.
*/
async get(route) {
const requestKey = `GET:${route}`;
return this.executeRequest(requestKey, async () => {
const response = await this.axiosInstance.get(route, {
headers: __classPrivateFieldGet(this, _Rest_client, "f").getHeaders(),
validateStatus: () => true,
});
if (![200, 204].includes(response.status)) {
if (response.data.retry_after !== undefined) {
await wait(response.data.retry_after * 1000);
return this.get(route);
}
throw new Error(response.data.message);
}
return response.data;
});
}
/**
* Sends a PATCH request to the Discord API.
*
* @param route - The route to send the request to.
* @param payload - The data to send with the request.
* @param formData - Whether the data is in FormData format.
* @returns The response data.
*/
async patch(route, payload, formData) {
const requestKey = `PATCH:${route}`;
return this.executeRequest(requestKey, async () => {
const response = await this.axiosInstance.patch(route, payload, {
headers: __classPrivateFieldGet(this, _Rest_client, "f").getHeaders(formData ? "multipart/form-data" : "application/json"),
validateStatus: () => true,
});
if (![200, 204].includes(response.status)) {
if (response.data.retry_after !== undefined) {
await wait(response.data.retry_after * 1000);
return this.patch(route, payload, formData);
}
throw new Error(response.data.message);
}
return response.data;
});
}
/**
* Sends a PUT request to the Discord API.
*
* @param route - The route to send the request to.
* @param payload - The data to send with the request.
* @param formData - Whether the data is in FormData format.
* @returns The response data.
*/
async put(route, payload, formData) {
const requestKey = `PUT:${route}`;
r