diff --git a/src/client/rest/RESTMethods.js b/src/client/rest/RESTMethods.js
index 44715c182..d0e9df3ef 100644
--- a/src/client/rest/RESTMethods.js
+++ b/src/client/rest/RESTMethods.js
@@ -499,6 +499,10 @@ class RESTMethods {
.then(data => this.client.actions.GuildMemberGet.handle(guild, data).member);
}
+ getGuild(guild) {
+ return this.rest.makeRequest('get', Endpoints.Guild(guild), true);
+ }
+
getGuildMember(guild, userID, cache) {
return this.rest.makeRequest('get', Endpoints.Guild(guild).Member(userID), true).then(data => {
if (cache) return this.client.actions.GuildMemberGet.handle(guild, data).member;
@@ -886,23 +890,6 @@ class RESTMethods {
.then(() => user);
}
- updateChannelPositions(guildID, channels) {
- const data = new Array(channels.length);
- for (let i = 0; i < channels.length; i++) {
- data[i] = {
- id: this.client.resolver.resolveChannelID(channels[i].channel),
- position: channels[i].position,
- };
- }
-
- return this.rest.makeRequest('patch', Endpoints.Guild(guildID).channels, true, data).then(() =>
- this.client.actions.GuildChannelsPositionUpdate.handle({
- guild_id: guildID,
- channels,
- }).guild
- );
- }
-
updateEmbed(guildID, embed, reason) {
return this.rest.makeRequest('patch', Endpoints.Guild(guildID).embed, true, {
enabled: embed.enabled,
diff --git a/src/structures/Guild.js b/src/structures/Guild.js
index 308dd57cb..b3084d5ac 100644
--- a/src/structures/Guild.js
+++ b/src/structures/Guild.js
@@ -184,6 +184,61 @@ class Guild {
this.defaultMessageNotifications = Constants.DefaultMessageNotifications[data.default_message_notifications] ||
data.default_message_notifications;
+ /**
+ * The hash of the guild banner
+ * @type {?string}
+ */
+ this.banner = data.banner;
+
+ /**
+ * The description of the guild, if any
+ * @type {?string}
+ */
+ this.description = data.description;
+
+ /**
+ * The embed channel ID, if enabled
+ * @type {?string}
+ * @name Guild#embedChannelID
+ */
+ if (typeof data.embed_channel_id !== 'undefined') this.embedChannelID = data.embed_channel_id;
+
+ /**
+ * The maximum amount of members the guild can have
+ * You will need to fetch the guild using {@link Guild#fetch} if you want to receive this parameter
+ * @type {?number}
+ * @name Guild#maximumMembers
+ */
+ if (typeof data.max_members !== 'undefined') this.maximumMembers = data.max_members || 250000;
+
+ /**
+ * The maximum amount of presences the guild can have
+ * You will need to fetch the guild using {@link Guild#fetch} if you want to receive this parameter
+ * @type {?number}
+ * @name Guild#maximumPresences
+ */
+ if (typeof data.max_presences !== 'undefined') this.maximumPresences = data.max_presences || 5000;
+
+ /**
+ * Whether widget images are enabled on this guild
+ * @type {?boolean}
+ * @name Guild#widgetEnabled
+ */
+ if (typeof data.widget_enabled !== 'undefined') this.widgetEnabled = data.widget_enabled;
+
+ /**
+ * The widget channel ID, if enabled
+ * @type {?string}
+ * @name Guild#widgetChannelID
+ */
+ if (typeof data.widget_channel_id !== 'undefined') this.widgetChannelID = data.widget_channel_id;
+
+ /**
+ * The vanity URL code of the guild, if any
+ * @type {?string}
+ */
+ this.vanityURLCode = data.vanity_url_code;
+
this.id = data.id;
this.available = !data.unavailable;
this.features = data.features || this.features || [];
@@ -272,6 +327,24 @@ class Guild {
return new Date(this.createdTimestamp);
}
+ /**
+ * Embed channel for this guild
+ * @type {?TextChannel}
+ * @readonly
+ */
+ get embedChannel() {
+ return this.channels.get(this.embedChannelID) || null;
+ }
+
+ /**
+ * Widget channel for this guild
+ * @type {?TextChannel}
+ * @readonly
+ */
+ get widgetChannel() {
+ return this.channels.get(this.widgetChannelID) || null;
+ }
+
/**
* The time the client user joined the guild
* @type {Date}
@@ -300,6 +373,16 @@ class Guild {
return Constants.Endpoints.Guild(this).Icon(this.client.options.http.cdn, this.icon);
}
+ /**
+ * The URL to this guild's banner.
+ * @type {?string}
+ * @readonly
+ */
+ get bannerURL() {
+ if (!this.banner) return null;
+ return Constants.Endpoints.Guild(this).Banner(this.client.options.http.cdn, this.banner);
+ }
+
/**
* The acronym that shows up in place of a guild icon.
* @type {string}
@@ -473,6 +556,18 @@ class Guild {
return this.client.resolver.resolveGuildMember(this, user);
}
+ /**
+ * Fetches this guild.
+ * @returns {Promise}
+ */
+ fetch() {
+ return this.client.rest.methods.getGuild(this).then(data => {
+ this.setup(data);
+
+ return this;
+ });
+ }
+
/**
* An object containing information about a guild member's ban.
* @typedef {Object} BanInfo
@@ -1115,7 +1210,25 @@ class Guild {
* .catch(console.error);
*/
setChannelPositions(channelPositions) {
- return this.client.rest.methods.updateChannelPositions(this.id, channelPositions);
+ channelPositions = channelPositions.map(({ channel, position }) => ({ id: channel.id || channel, position }));
+ return this.client.rest.methods.setChannelPositions(this.id, channelPositions);
+ }
+
+ /**
+ * The data needed for updating a role's position.
+ * @typedef {Object} RolePosition
+ * @property {RoleResolvable} role Role to update
+ * @property {number} position New position for the role
+ */
+
+ /**
+ * Batch-updates the guild's role's positions.
+ * @param {RolePosition[]} rolePositions Role positions to update
+ * @returns {Promise}
+ */
+ setRolePositions(rolePositions) {
+ rolePositions = rolePositions.map(({ role, position }) => ({ id: role.id || role, position }));
+ return this.client.rest.methods.setRolePositions(this.id, rolePositions);
}
/**
@@ -1396,7 +1509,7 @@ class Guild {
Util.moveElementInArray(updatedChannels, channel, position, relative);
- updatedChannels = updatedChannels.map((r, i) => ({ id: r.id, position: i }));
+ updatedChannels = updatedChannels.map((c, i) => ({ id: c.id, position: i }));
return this.client.rest.methods.setChannelPositions(this.id, updatedChannels);
}
diff --git a/src/util/Constants.js b/src/util/Constants.js
index 9110c42dc..3787818b6 100644
--- a/src/util/Constants.js
+++ b/src/util/Constants.js
@@ -152,6 +152,7 @@ const Endpoints = exports.Endpoints = {
auditLogs: `${base}/audit-logs`,
Emoji: emojiID => `${base}/emojis/${emojiID}`,
Icon: (root, hash) => Endpoints.CDN(root).Icon(guildID, hash),
+ Banner: (root, hash) => Endpoints.CDN(root).Banner(guildID, hash),
Splash: (root, hash) => Endpoints.CDN(root).Splash(guildID, hash),
Role: roleID => `${base}/roles/${roleID}`,
Member: memberID => {
@@ -210,6 +211,7 @@ const Endpoints = exports.Endpoints = {
Asset: name => `${root}/assets/${name}`,
Avatar: (userID, hash) => `${root}/avatars/${userID}/${hash}.${hash.startsWith('a_') ? 'gif' : 'png?size=2048'}`,
Icon: (guildID, hash) => `${root}/icons/${guildID}/${hash}.jpg`,
+ Banner: (guildID, hash) => `${root}/banners/${guildID}/${hash}.jpg`,
AppIcon: (clientID, hash) => `${root}/app-icons/${clientID}/${hash}.png`,
AppAsset: (clientID, hash) => `${root}/app-assets/${clientID}/${hash}.png`,
GDMIcon: (channelID, hash) => `${root}/channel-icons/${channelID}/${hash}.jpg?size=2048`,
diff --git a/typings/index.d.ts b/typings/index.d.ts
index 989d1bdc3..8e48a99dd 100644
--- a/typings/index.d.ts
+++ b/typings/index.d.ts
@@ -482,6 +482,9 @@ declare module 'discord.js' {
public afkTimeout: number;
public applicationID: string;
public available: boolean;
+ public banner: string | null;
+ public readonly bannerURL: string | null;
+ public description: string | null;
public channels: Collection;
public defaultMessageNotifications: DefaultMessageNotifications | number;
public readonly client: Client;
@@ -489,6 +492,8 @@ declare module 'discord.js' {
public readonly createdTimestamp: number;
public readonly defaultChannel: TextChannel;
public readonly defaultRole: Role;
+ public readonly embedChannel: TextChannel | null;
+ public embedChannelID: Snowflake | null;
public embedEnabled: boolean;
public emojis: Collection;
public explicitContentFilter: number;
@@ -499,6 +504,8 @@ declare module 'discord.js' {
public readonly joinedAt: Date;
public joinedTimestamp: number;
public large: boolean;
+ public maximumMembers?: number;
+ public maximumPresences?: number;
public readonly me: GuildMember;
public memberCount: number;
public members: Collection;
@@ -518,9 +525,13 @@ declare module 'discord.js' {
public readonly suppressEveryone: boolean;
public readonly systemChannel: GuildChannel;
public systemChannelID: Snowflake;
+ public vanityURLCode: string;
public readonly verified: boolean;
public verificationLevel: number;
public readonly voiceConnection: VoiceConnection;
+ public readonly widgetChannel: TextChannel | null;
+ public widgetChannelID?: Snowflake;
+ public widgetEnabled?: boolean;
public acknowledge(): Promise;
public addMember(user: UserResolvable, options: AddGuildMemberOptions): Promise;
public allowDMs(allow: boolean): Promise;
@@ -533,6 +544,7 @@ declare module 'discord.js' {
public deleteEmoji(emoji: Emoji | string, reason?: string): Promise;
public edit(data: GuildEditData, reason?: string): Promise;
public equals(guild: Guild): boolean;
+ public fetch(): Promise;
public fetchAuditLogs(options?: GuildAuditLogsFetchOptions): Promise;
public fetchBan(user: UserResolvable): Promise;
public fetchBans(withReasons?: false): Promise>;
@@ -562,6 +574,7 @@ declare module 'discord.js' {
public setPosition(position: number, relative?: boolean): Promise;
public setRegion(region: string, reason?: string): Promise;
public setRolePosition(role: string | Role, position: number, relative?: boolean): Promise;
+ public setRolePositions(rolePositions: RolePosition[]): Promise;
public setSplash(splash: Base64Resolvable, reason?: string): Promise;
public setSystemChannel(systemChannel: ChannelResolvable, reason?: string): Promise;
public setVerificationLevel(verificationLevel: number, reason?: string): Promise;
@@ -2103,6 +2116,11 @@ declare module 'discord.js' {
mentionable?: boolean;
};
+ type RolePosition = {
+ role: RoleResolvable;
+ position: number;
+ };
+
type RoleResolvable = Role | string;
type Snowflake = string;