mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-18 04:23:31 +01:00
feat: add support for role icons (#6633)
This commit is contained in:
@@ -4,6 +4,7 @@ const { Collection } = require('@discordjs/collection');
|
|||||||
const CachedManager = require('./CachedManager');
|
const CachedManager = require('./CachedManager');
|
||||||
const { TypeError } = require('../errors');
|
const { TypeError } = require('../errors');
|
||||||
const Role = require('../structures/Role');
|
const Role = require('../structures/Role');
|
||||||
|
const DataResolver = require('../util/DataResolver');
|
||||||
const Permissions = require('../util/Permissions');
|
const Permissions = require('../util/Permissions');
|
||||||
const { resolveColor, setPosition } = require('../util/Util');
|
const { resolveColor, setPosition } = require('../util/Util');
|
||||||
|
|
||||||
@@ -104,6 +105,10 @@ class RoleManager extends CachedManager {
|
|||||||
* @property {PermissionResolvable} [permissions] The permissions for the new role
|
* @property {PermissionResolvable} [permissions] The permissions for the new role
|
||||||
* @property {number} [position] The position of the new role
|
* @property {number} [position] The position of the new role
|
||||||
* @property {boolean} [mentionable] Whether or not the new role should be mentionable
|
* @property {boolean} [mentionable] Whether or not the new role should be mentionable
|
||||||
|
* @property {?(BufferResolvable|Base64Resolvable|EmojiResolvable)} [icon] The icon for the role
|
||||||
|
* <warn>The `EmojiResolvable` should belong to the same guild as the role.
|
||||||
|
* If not, pass the emoji's URL directly</warn>
|
||||||
|
* @property {?string} [unicodeEmoji] The unicode emoji for the role
|
||||||
* @property {string} [reason] The reason for creating this role
|
* @property {string} [reason] The reason for creating this role
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -128,9 +133,14 @@ class RoleManager extends CachedManager {
|
|||||||
* .catch(console.error);
|
* .catch(console.error);
|
||||||
*/
|
*/
|
||||||
async create(options = {}) {
|
async create(options = {}) {
|
||||||
let { name, color, hoist, permissions, position, mentionable, reason } = options;
|
let { name, color, hoist, permissions, position, mentionable, reason, icon, unicodeEmoji } = options;
|
||||||
color &&= resolveColor(color);
|
color &&= resolveColor(color);
|
||||||
if (typeof permissions !== 'undefined') permissions = new Permissions(permissions);
|
if (typeof permissions !== 'undefined') permissions = new Permissions(permissions);
|
||||||
|
if (icon) {
|
||||||
|
const guildEmojiURL = this.guild.emojis.resolve(icon)?.url;
|
||||||
|
icon = guildEmojiURL ? await DataResolver.resolveImage(guildEmojiURL) : await DataResolver.resolveImage(icon);
|
||||||
|
if (typeof icon !== 'string') icon = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
const data = await this.client.api.guilds(this.guild.id).roles.post({
|
const data = await this.client.api.guilds(this.guild.id).roles.post({
|
||||||
data: {
|
data: {
|
||||||
@@ -139,6 +149,8 @@ class RoleManager extends CachedManager {
|
|||||||
hoist,
|
hoist,
|
||||||
permissions,
|
permissions,
|
||||||
mentionable,
|
mentionable,
|
||||||
|
icon,
|
||||||
|
unicode_emoji: unicodeEmoji,
|
||||||
},
|
},
|
||||||
reason,
|
reason,
|
||||||
});
|
});
|
||||||
@@ -182,12 +194,21 @@ class RoleManager extends CachedManager {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let icon = data.icon;
|
||||||
|
if (icon) {
|
||||||
|
const guildEmojiURL = this.guild.emojis.resolve(icon)?.url;
|
||||||
|
icon = guildEmojiURL ? await DataResolver.resolveImage(guildEmojiURL) : await DataResolver.resolveImage(icon);
|
||||||
|
if (typeof icon !== 'string') icon = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
const _data = {
|
const _data = {
|
||||||
name: data.name,
|
name: data.name,
|
||||||
color: typeof data.color === 'undefined' ? undefined : resolveColor(data.color),
|
color: typeof data.color === 'undefined' ? undefined : resolveColor(data.color),
|
||||||
hoist: data.hoist,
|
hoist: data.hoist,
|
||||||
permissions: typeof data.permissions === 'undefined' ? undefined : new Permissions(data.permissions),
|
permissions: typeof data.permissions === 'undefined' ? undefined : new Permissions(data.permissions),
|
||||||
mentionable: data.mentionable,
|
mentionable: data.mentionable,
|
||||||
|
icon,
|
||||||
|
unicode_emoji: data.unicodeEmoji,
|
||||||
};
|
};
|
||||||
|
|
||||||
const d = await this.client.api.guilds(this.guild.id).roles(role.id).patch({ data: _data, reason });
|
const d = await this.client.api.guilds(this.guild.id).roles(role.id).patch({ data: _data, reason });
|
||||||
|
|||||||
@@ -186,6 +186,7 @@ class Guild extends AnonymousGuild {
|
|||||||
* * THREE_DAY_THREAD_ARCHIVE
|
* * THREE_DAY_THREAD_ARCHIVE
|
||||||
* * SEVEN_DAY_THREAD_ARCHIVE
|
* * SEVEN_DAY_THREAD_ARCHIVE
|
||||||
* * PRIVATE_THREADS
|
* * PRIVATE_THREADS
|
||||||
|
* * ROLE_ICONS
|
||||||
* @typedef {string} Features
|
* @typedef {string} Features
|
||||||
* @see {@link https://discord.com/developers/docs/resources/guild#guild-object-guild-features}
|
* @see {@link https://discord.com/developers/docs/resources/guild#guild-object-guild-features}
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -91,6 +91,18 @@ class Role extends Base {
|
|||||||
*/
|
*/
|
||||||
this.deleted = false;
|
this.deleted = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The icon hash of the role
|
||||||
|
* @type {?string}
|
||||||
|
*/
|
||||||
|
this.icon = data.icon;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The unicode emoji for the role
|
||||||
|
* @type {?string}
|
||||||
|
*/
|
||||||
|
this.unicodeEmoji = data.unicode_emoji;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The tags this role has
|
* The tags this role has
|
||||||
* @type {?Object}
|
* @type {?Object}
|
||||||
@@ -191,6 +203,10 @@ class Role extends Base {
|
|||||||
* @property {number} [position] The position of the role
|
* @property {number} [position] The position of the role
|
||||||
* @property {PermissionResolvable} [permissions] The permissions of the role
|
* @property {PermissionResolvable} [permissions] The permissions of the role
|
||||||
* @property {boolean} [mentionable] Whether or not the role should be mentionable
|
* @property {boolean} [mentionable] Whether or not the role should be mentionable
|
||||||
|
* @property {?(BufferResolvable|Base64Resolvable|EmojiResolvable)} [icon] The icon for the role
|
||||||
|
* <warn>The `EmojiResolvable` should belong to the same guild as the role.
|
||||||
|
* If not, pass the emoji's URL directly</warn>
|
||||||
|
* @property {?string} [unicodeEmoji] The unicode emoji for the role
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -300,6 +316,33 @@ class Role extends Base {
|
|||||||
return this.edit({ mentionable }, reason);
|
return this.edit({ mentionable }, reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a new icon for the role.
|
||||||
|
* @param {?(BufferResolvable|Base64Resolvable|EmojiResolvable)} icon The icon for the role
|
||||||
|
* <warn>The `EmojiResolvable` should belong to the same guild as the role.
|
||||||
|
* If not, pass the emoji's URL directly</warn>
|
||||||
|
* @param {string} [reason] Reason for changing the role's icon
|
||||||
|
* @returns {Promise<Role>}
|
||||||
|
*/
|
||||||
|
setIcon(icon, reason) {
|
||||||
|
return this.edit({ icon }, reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a new unicode emoji for the role.
|
||||||
|
* @param {?string} unicodeEmoji The new unicode emoji for the role
|
||||||
|
* @param {string} [reason] Reason for changing the role's unicode emoji
|
||||||
|
* @returns {Promise<Role>}
|
||||||
|
* @example
|
||||||
|
* // Set a new unicode emoji for the role
|
||||||
|
* role.setUnicodeEmoji('🤖')
|
||||||
|
* .then(updated => console.log(`Set unicode emoji for the role to ${updated.unicodeEmoji}`))
|
||||||
|
* .catch(console.error);
|
||||||
|
*/
|
||||||
|
setUnicodeEmoji(unicodeEmoji, reason) {
|
||||||
|
return this.edit({ unicodeEmoji }, reason);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Options used to set position of a role.
|
* Options used to set position of a role.
|
||||||
* @typedef {Object} SetRolePositionOptions
|
* @typedef {Object} SetRolePositionOptions
|
||||||
@@ -350,6 +393,16 @@ class Role extends Base {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A link to the role's icon
|
||||||
|
* @param {StaticImageURLOptions} [options={}] Options for the image URL
|
||||||
|
* @returns {?string}
|
||||||
|
*/
|
||||||
|
iconURL({ format, size } = {}) {
|
||||||
|
if (!this.icon) return null;
|
||||||
|
return this.client.rest.cdn.RoleIcon(this.id, this.icon, format, size);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether this role equals another role. It compares all properties, so for most operations
|
* Whether this role equals another role. It compares all properties, so for most operations
|
||||||
* it is advisable to just compare `role.id === role2.id` as it is much faster and is often
|
* it is advisable to just compare `role.id === role2.id` as it is much faster and is often
|
||||||
@@ -366,7 +419,9 @@ class Role extends Base {
|
|||||||
this.hoist === role.hoist &&
|
this.hoist === role.hoist &&
|
||||||
this.position === role.position &&
|
this.position === role.position &&
|
||||||
this.permissions.bitfield === role.permissions.bitfield &&
|
this.permissions.bitfield === role.permissions.bitfield &&
|
||||||
this.managed === role.managed
|
this.managed === role.managed &&
|
||||||
|
this.icon === role.icon &&
|
||||||
|
this.unicodeEmoji === role.unicodeEmoji
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -73,6 +73,8 @@ exports.Endpoints = {
|
|||||||
TeamIcon: (teamId, hash, options) => makeImageUrl(`${root}/team-icons/${teamId}/${hash}`, options),
|
TeamIcon: (teamId, hash, options) => makeImageUrl(`${root}/team-icons/${teamId}/${hash}`, options),
|
||||||
Sticker: (stickerId, stickerFormat) =>
|
Sticker: (stickerId, stickerFormat) =>
|
||||||
`${root}/stickers/${stickerId}.${stickerFormat === 'LOTTIE' ? 'json' : 'png'}`,
|
`${root}/stickers/${stickerId}.${stickerFormat === 'LOTTIE' ? 'json' : 'png'}`,
|
||||||
|
RoleIcon: (roleId, hash, format = 'webp', size) =>
|
||||||
|
makeImageUrl(`${root}/role-icons/${roleId}/${hash}`, { size, format }),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
invite: (root, code) => `${root}/${code}`,
|
invite: (root, code) => `${root}/${code}`,
|
||||||
|
|||||||
11
typings/index.d.ts
vendored
11
typings/index.d.ts
vendored
@@ -1647,16 +1647,21 @@ export class Role extends Base {
|
|||||||
public rawPosition: number;
|
public rawPosition: number;
|
||||||
public tags: RoleTagData | null;
|
public tags: RoleTagData | null;
|
||||||
public comparePositionTo(role: RoleResolvable): number;
|
public comparePositionTo(role: RoleResolvable): number;
|
||||||
|
public icon: string | null;
|
||||||
|
public unicodeEmoji: string | null;
|
||||||
public delete(reason?: string): Promise<Role>;
|
public delete(reason?: string): Promise<Role>;
|
||||||
public edit(data: RoleData, reason?: string): Promise<Role>;
|
public edit(data: RoleData, reason?: string): Promise<Role>;
|
||||||
public equals(role: Role): boolean;
|
public equals(role: Role): boolean;
|
||||||
|
public iconURL(options?: StaticImageURLOptions): string | null;
|
||||||
public permissionsIn(channel: GuildChannel | Snowflake): Readonly<Permissions>;
|
public permissionsIn(channel: GuildChannel | Snowflake): Readonly<Permissions>;
|
||||||
public setColor(color: ColorResolvable, reason?: string): Promise<Role>;
|
public setColor(color: ColorResolvable, reason?: string): Promise<Role>;
|
||||||
public setHoist(hoist?: boolean, reason?: string): Promise<Role>;
|
public setHoist(hoist?: boolean, reason?: string): Promise<Role>;
|
||||||
public setMentionable(mentionable?: boolean, reason?: string): Promise<Role>;
|
public setMentionable(mentionable?: boolean, reason?: string): Promise<Role>;
|
||||||
public setName(name: string, reason?: string): Promise<Role>;
|
public setName(name: string, reason?: string): Promise<Role>;
|
||||||
public setPermissions(permissions: PermissionResolvable, reason?: string): Promise<Role>;
|
public setPermissions(permissions: PermissionResolvable, reason?: string): Promise<Role>;
|
||||||
|
public setIcon(icon: BufferResolvable | Base64Resolvable | EmojiResolvable | null, reason?: string): Promise<Role>;
|
||||||
public setPosition(position: number, options?: SetRolePositionOptions): Promise<Role>;
|
public setPosition(position: number, options?: SetRolePositionOptions): Promise<Role>;
|
||||||
|
public setUnicodeEmoji(unicodeEmoji: string | null, reason?: string): Promise<Role>;
|
||||||
public toJSON(): unknown;
|
public toJSON(): unknown;
|
||||||
public toString(): RoleMention;
|
public toString(): RoleMention;
|
||||||
|
|
||||||
@@ -2362,6 +2367,7 @@ export const Constants: {
|
|||||||
{ format, size }: { format: AllowedImageFormat; size: AllowedImageSize },
|
{ format, size }: { format: AllowedImageFormat; size: AllowedImageSize },
|
||||||
) => string;
|
) => string;
|
||||||
Sticker: (stickerId: Snowflake, stickerFormat: StickerFormatType) => string;
|
Sticker: (stickerId: Snowflake, stickerFormat: StickerFormatType) => string;
|
||||||
|
RoleIcon: (roleId: Snowflake, hash: string, format: AllowedImageFormat, size: AllowedImageSize) => string;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
WSCodes: {
|
WSCodes: {
|
||||||
@@ -4069,7 +4075,8 @@ export type GuildFeatures =
|
|||||||
| 'MORE_STICKERS'
|
| 'MORE_STICKERS'
|
||||||
| 'THREE_DAY_THREAD_ARCHIVE'
|
| 'THREE_DAY_THREAD_ARCHIVE'
|
||||||
| 'SEVEN_DAY_THREAD_ARCHIVE'
|
| 'SEVEN_DAY_THREAD_ARCHIVE'
|
||||||
| 'PRIVATE_THREADS';
|
| 'PRIVATE_THREADS'
|
||||||
|
| 'ROLE_ICONS';
|
||||||
|
|
||||||
export interface GuildMemberEditData {
|
export interface GuildMemberEditData {
|
||||||
nick?: string | null;
|
nick?: string | null;
|
||||||
@@ -4740,6 +4747,8 @@ export interface RoleData {
|
|||||||
position?: number;
|
position?: number;
|
||||||
permissions?: PermissionResolvable;
|
permissions?: PermissionResolvable;
|
||||||
mentionable?: boolean;
|
mentionable?: boolean;
|
||||||
|
icon?: BufferResolvable | Base64Resolvable | EmojiResolvable | null;
|
||||||
|
unicodeEmoji?: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type RoleMention = '@everyone' | `<@&${Snowflake}>`;
|
export type RoleMention = '@everyone' | `<@&${Snowflake}>`;
|
||||||
|
|||||||
Reference in New Issue
Block a user