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;