discord.js-selfbot-v13/src/structures/GuildTemplate.js

238 lines
5.7 KiB
JavaScript
Raw Normal View History

2022-03-19 10:37:45 +00:00
'use strict';
const { setTimeout, clearTimeout } = require('node:timers');
const { RouteBases, Routes } = require('discord-api-types/v9');
const Base = require('./Base');
const DataResolver = require('../util/DataResolver');
const Events = require('../util/Events');
/**
* Represents the template for a guild.
* @extends {Base}
*/
class GuildTemplate extends Base {
constructor(client, data) {
super(client);
this._patch(data);
}
_patch(data) {
if ('code' in data) {
/**
* The unique code of this template
* @type {string}
*/
this.code = data.code;
}
if ('name' in data) {
/**
* The name of this template
* @type {string}
*/
this.name = data.name;
}
if ('description' in data) {
/**
* The description of this template
* @type {?string}
*/
this.description = data.description;
}
if ('usage_count' in data) {
/**
* The amount of times this template has been used
* @type {number}
*/
this.usageCount = data.usage_count;
}
if ('creator_id' in data) {
/**
* The id of the user that created this template
* @type {Snowflake}
*/
this.creatorId = data.creator_id;
}
if ('creator' in data) {
/**
* The user that created this template
* @type {User}
*/
this.creator = this.client.users._add(data.creator);
}
if ('created_at' in data) {
/**
* The timestamp of when this template was created at
* @type {number}
*/
this.createdTimestamp = Date.parse(data.created_at);
}
if ('updated_at' in data) {
/**
* The timestamp of when this template was last synced to the guild
* @type {number}
*/
this.updatedTimestamp = Date.parse(data.updated_at);
}
if ('source_guild_id' in data) {
/**
* The id of the guild that this template belongs to
* @type {Snowflake}
*/
this.guildId = data.source_guild_id;
}
if ('serialized_source_guild' in data) {
/**
* The data of the guild that this template would create
* @type {APIGuild}
*/
this.serializedGuild = data.serialized_source_guild;
}
/**
* Whether this template has unsynced changes
* @type {?boolean}
*/
this.unSynced = 'is_dirty' in data ? Boolean(data.is_dirty) : null;
return this;
}
/**
* Creates a guild based on this template.
* <warn>This is only available to bots in fewer than 10 guilds.</warn>
* @param {string} name The name of the guild
* @param {BufferResolvable|Base64Resolvable} [icon] The icon for the guild
* @returns {Promise<Guild>}
*/
async createGuild(name, icon) {
const { client } = this;
const data = await client.rest.post(Routes.template(this.code), {
body: {
name,
icon: await DataResolver.resolveImage(icon),
},
});
if (client.guilds.cache.has(data.id)) return client.guilds.cache.get(data.id);
return new Promise(resolve => {
const resolveGuild = guild => {
client.off(Events.GuildCreate, handleGuild);
client.decrementMaxListeners();
resolve(guild);
};
const handleGuild = guild => {
if (guild.id === data.id) {
clearTimeout(timeout);
resolveGuild(guild);
}
};
client.incrementMaxListeners();
client.on(Events.GuildCreate, handleGuild);
const timeout = setTimeout(() => resolveGuild(client.guilds._add(data)), 10_000).unref();
});
}
/**
* Options used to edit a guild template.
* @typedef {Object} EditGuildTemplateOptions
* @property {string} [name] The name of this template
* @property {string} [description] The description of this template
*/
/**
* Updates the metadata of this template.
* @param {EditGuildTemplateOptions} [options] Options for editing the template
* @returns {Promise<GuildTemplate>}
*/
async edit({ name, description } = {}) {
const data = await this.client.api.guilds(this.guildId).templates(this.code).patch({ body: { name, description } });
return this._patch(data);
}
/**
* Deletes this template.
* @returns {Promise<GuildTemplate>}
*/
async delete() {
await this.client.api.guilds(this.guildId).templates(this.code).delete();
return this;
}
/**
* Syncs this template to the current state of the guild.
* @returns {Promise<GuildTemplate>}
*/
async sync() {
const data = await this.client.api.guilds(this.guildId).templates(this.code).put();
return this._patch(data);
}
/**
* The time when this template was created at
* @type {Date}
* @readonly
*/
get createdAt() {
return new Date(this.createdTimestamp);
}
/**
* The time when this template was last synced to the guild
* @type {Date}
* @readonly
*/
get updatedAt() {
return new Date(this.updatedTimestamp);
}
/**
* The guild that this template belongs to
* @type {?Guild}
* @readonly
*/
get guild() {
return this.client.guilds.resolve(this.guildId);
}
/**
* The URL of this template
* @type {string}
* @readonly
*/
get url() {
return `${RouteBases.template}/${this.code}`;
}
/**
* When concatenated with a string, this automatically returns the template's code instead of the template object.
* @returns {string}
* @example
* // Logs: Template: FKvmczH2HyUf
* console.log(`Template: ${guildTemplate}!`);
*/
toString() {
return this.code;
}
}
/**
* Regular expression that globally matches guild template links
* @type {RegExp}
*/
GuildTemplate.GUILD_TEMPLATES_PATTERN = /discord(?:app)?\.(?:com\/template|new)\/([\w-]{2,255})/gi;
module.exports = GuildTemplate;