buddy

node MVC discord bot
Log | Files | Refs | README

GuildManager.js (8090B)


      1 'use strict';
      2 
      3 const BaseManager = require('./BaseManager');
      4 const Guild = require('../structures/Guild');
      5 const GuildChannel = require('../structures/GuildChannel');
      6 const GuildEmoji = require('../structures/GuildEmoji');
      7 const GuildMember = require('../structures/GuildMember');
      8 const Invite = require('../structures/Invite');
      9 const Role = require('../structures/Role');
     10 const {
     11   Events,
     12   VerificationLevels,
     13   DefaultMessageNotifications,
     14   ExplicitContentFilterLevels,
     15 } = require('../util/Constants');
     16 const DataResolver = require('../util/DataResolver');
     17 const Permissions = require('../util/Permissions');
     18 const { resolveColor } = require('../util/Util');
     19 
     20 /**
     21  * Manages API methods for Guilds and stores their cache.
     22  * @extends {BaseManager}
     23  */
     24 class GuildManager extends BaseManager {
     25   constructor(client, iterable) {
     26     super(client, iterable, Guild);
     27   }
     28 
     29   /**
     30    * The cache of this Manager
     31    * @type {Collection<Snowflake, Guild>}
     32    * @name GuildManager#cache
     33    */
     34 
     35   /**
     36    * Data that resolves to give a Guild object. This can be:
     37    * * A Guild object
     38    * * A GuildChannel object
     39    * * A GuildEmoji object
     40    * * A Role object
     41    * * A Snowflake
     42    * * An Invite object
     43    * @typedef {Guild|GuildChannel|GuildMember|GuildEmoji|Role|Snowflake|Invite} GuildResolvable
     44    */
     45 
     46   /**
     47    * Partial data for a Role.
     48    * @typedef {Object} PartialRoleData
     49    * @property {number} [id] The ID for this role, used to set channel overrides,
     50    * this is a placeholder and will be replaced by the API after consumption
     51    * @property {string} [name] The name of the role
     52    * @property {ColorResolvable} [color] The color of the role, either a hex string or a base 10 number
     53    * @property {boolean} [hoist] Whether or not the role should be hoisted
     54    * @property {number} [position] The position of the role
     55    * @property {PermissionResolvable|number} [permissions] The permissions of the role
     56    * @property {boolean} [mentionable] Whether or not the role should be mentionable
     57    */
     58 
     59   /**
     60    * Partial overwrite data.
     61    * @typedef {Object} PartialOverwriteData
     62    * @property {number|Snowflake} id The Role or User ID for this overwrite
     63    * @property {string} [type] The type of this overwrite
     64    * @property {PermissionResolvable} [allow] The permissions to allow
     65    * @property {PermissionResolvable} [deny] The permissions to deny
     66    */
     67 
     68   /**
     69    * Partial data for a Channel.
     70    * @typedef {Object} PartialChannelData
     71    * @property {number} [id] The ID for this channel, used to set its parent,
     72    * this is a placeholder and will be replaced by the API after consumption
     73    * @property {number} [parentID] The parent ID for this channel
     74    * @property {string} [type] The type of the channel
     75    * @property {string} name The name of the channel
     76    * @property {string} [topic] The topic of the text channel
     77    * @property {boolean} [nsfw] Whether the channel is NSFW
     78    * @property {number} [bitrate] The bitrate of the voice channel
     79    * @property {number} [userLimit] The user limit of the channel
     80    * @property {PartialOverwriteData} [permissionOverwrites]
     81    * Overwrites of the channel
     82    * @property {number} [rateLimitPerUser] The rate limit per user of the channel in seconds
     83    */
     84 
     85   /**
     86    * Resolves a GuildResolvable to a Guild object.
     87    * @method resolve
     88    * @memberof GuildManager
     89    * @instance
     90    * @param {GuildResolvable} guild The guild resolvable to identify
     91    * @returns {?Guild}
     92    */
     93   resolve(guild) {
     94     if (
     95       guild instanceof GuildChannel ||
     96       guild instanceof GuildMember ||
     97       guild instanceof GuildEmoji ||
     98       guild instanceof Role ||
     99       (guild instanceof Invite && guild.guild)
    100     ) {
    101       return super.resolve(guild.guild);
    102     }
    103     return super.resolve(guild);
    104   }
    105 
    106   /**
    107    * Resolves a GuildResolvable to a Guild ID string.
    108    * @method resolveID
    109    * @memberof GuildManager
    110    * @instance
    111    * @param {GuildResolvable} guild The guild resolvable to identify
    112    * @returns {?Snowflake}
    113    */
    114   resolveID(guild) {
    115     if (
    116       guild instanceof GuildChannel ||
    117       guild instanceof GuildMember ||
    118       guild instanceof GuildEmoji ||
    119       guild instanceof Role ||
    120       (guild instanceof Invite && guild.guild)
    121     ) {
    122       return super.resolveID(guild.guild.id);
    123     }
    124     return super.resolveID(guild);
    125   }
    126 
    127   /**
    128    * Creates a guild.
    129    * <warn>This is only available to bots in fewer than 10 guilds.</warn>
    130    * @param {string} name The name of the guild
    131    * @param {Object} [options] Options for the creating
    132    * @param {PartialChannelData[]} [options.channels] The channels for this guild
    133    * @param {DefaultMessageNotifications} [options.defaultMessageNotifications] The default message notifications
    134    * for the guild
    135    * @param {ExplicitContentFilterLevel} [options.explicitContentFilter] The explicit content filter level for the guild
    136    * @param {BufferResolvable|Base64Resolvable} [options.icon=null] The icon for the guild
    137    * @param {string} [options.region] The region for the server, defaults to the closest one available
    138    * @param {PartialRoleData[]} [options.roles] The roles for this guild,
    139    * the first element of this array is used to change properties of the guild's everyone role.
    140    * @param {VerificationLevel} [options.verificationLevel] The verification level for the guild
    141    * @returns {Promise<Guild>} The guild that was created
    142    */
    143   async create(
    144     name,
    145     {
    146       channels = [],
    147       defaultMessageNotifications,
    148       explicitContentFilter,
    149       icon = null,
    150       region,
    151       roles = [],
    152       verificationLevel,
    153     } = {},
    154   ) {
    155     icon = await DataResolver.resolveImage(icon);
    156     if (typeof verificationLevel !== 'undefined' && typeof verificationLevel !== 'number') {
    157       verificationLevel = VerificationLevels.indexOf(verificationLevel);
    158     }
    159     if (typeof defaultMessageNotifications !== 'undefined' && typeof defaultMessageNotifications !== 'number') {
    160       defaultMessageNotifications = DefaultMessageNotifications.indexOf(defaultMessageNotifications);
    161     }
    162     if (typeof explicitContentFilter !== 'undefined' && typeof explicitContentFilter !== 'number') {
    163       explicitContentFilter = ExplicitContentFilterLevels.indexOf(explicitContentFilter);
    164     }
    165     for (const channel of channels) {
    166       channel.parent_id = channel.parentID;
    167       delete channel.parentID;
    168       if (!channel.permissionOverwrites) continue;
    169       for (const overwrite of channel.permissionOverwrites) {
    170         if (overwrite.allow) overwrite.allow = Permissions.resolve(overwrite.allow);
    171         if (overwrite.deny) overwrite.deny = Permissions.resolve(overwrite.deny);
    172       }
    173       channel.permission_overwrites = channel.permissionOverwrites;
    174       delete channel.permissionOverwrites;
    175     }
    176     for (const role of roles) {
    177       if (role.color) role.color = resolveColor(role.color);
    178       if (role.permissions) role.permissions = Permissions.resolve(role.permissions);
    179     }
    180     return new Promise((resolve, reject) =>
    181       this.client.api.guilds
    182         .post({
    183           data: {
    184             name,
    185             region,
    186             icon,
    187             verification_level: verificationLevel,
    188             default_message_notifications: defaultMessageNotifications,
    189             explicit_content_filter: explicitContentFilter,
    190             channels,
    191             roles,
    192           },
    193         })
    194         .then(data => {
    195           if (this.client.guilds.cache.has(data.id)) return resolve(this.client.guilds.cache.get(data.id));
    196 
    197           const handleGuild = guild => {
    198             if (guild.id === data.id) {
    199               this.client.removeListener(Events.GUILD_CREATE, handleGuild);
    200               this.client.clearTimeout(timeout);
    201               resolve(guild);
    202             }
    203           };
    204           this.client.on(Events.GUILD_CREATE, handleGuild);
    205 
    206           const timeout = this.client.setTimeout(() => {
    207             this.client.removeListener(Events.GUILD_CREATE, handleGuild);
    208             resolve(this.client.guilds.add(data));
    209           }, 10000);
    210           return undefined;
    211         }, reject),
    212     );
    213   }
    214 }
    215 
    216 module.exports = GuildManager;