From 529007804448a1b3c9086071a0c6200e3f46f684 Mon Sep 17 00:00:00 2001 From: Fleny Date: Sun, 26 May 2024 21:14:11 +0200 Subject: [PATCH] fix(bot,types,utils)!: change avatar decoration url link (#3621) * Change the avatarDecorationUrl link * Add User#avatarDecorationData & Member#avatarDecorationData * Fix type error * Fix format error --------- Co-authored-by: Awesome Stickz --- packages/bot/src/transformers.ts | 23 +++++++++++++++++-- .../src/transformers/avatarDecorationData.ts | 18 +++++++++++++++ packages/bot/src/transformers/index.ts | 1 + packages/bot/src/transformers/member.ts | 7 +++++- .../bot/src/transformers/reverse/member.ts | 5 ++++ packages/bot/src/transformers/user.ts | 9 ++++---- packages/types/src/discord.ts | 14 +++++++++-- packages/utils/src/images.ts | 4 ++-- 8 files changed, 70 insertions(+), 11 deletions(-) create mode 100644 packages/bot/src/transformers/avatarDecorationData.ts diff --git a/packages/bot/src/transformers.ts b/packages/bot/src/transformers.ts index f5d23099c..e3439ba04 100644 --- a/packages/bot/src/transformers.ts +++ b/packages/bot/src/transformers.ts @@ -12,6 +12,7 @@ import type { DiscordAuditLogEntry, DiscordAutoModerationActionExecution, DiscordAutoModerationRule, + DiscordAvatarDecorationData, DiscordChannel, DiscordCreateApplicationCommand, DiscordEmbed, @@ -77,11 +78,13 @@ import { transformApplicationCommandToDiscordApplicationCommand, transformApplicationToDiscordApplication, transformAttachmentToDiscordAttachment, + transformAvatarDecorationData, transformComponentToDiscordComponent, transformEmbedToDiscordEmbed, transformMemberToDiscordMember, transformTeamToDiscordTeam, transformUserToDiscordUser, + type AvatarDecorationData, } from './transformers/index.js' import { transformIntegration, type Integration } from './transformers/integration.js' import { transformInteraction, transformInteractionDataOption, type Interaction, type InteractionDataOption } from './transformers/interaction.js' @@ -181,6 +184,7 @@ export interface Transformers { sku: (bot: Bot, payload: DiscordSku, sku: Sku) => any poll: (bot: Bot, payload: DiscordPoll, poll: Poll) => any pollMedia: (bot: Bot, payload: DiscordPollMedia, pollMedia: PollMedia) => any + avatarDecorationData: (bot: Bot, payload: DiscordAvatarDecorationData, avatarDecorationData: AvatarDecorationData) => any } desiredProperties: { attachment: { @@ -344,6 +348,7 @@ export interface Transformers { deaf: boolean mute: boolean pending: boolean + avatarDecorationData: boolean } message: { activity: boolean @@ -473,7 +478,11 @@ export interface Transformers { verified: boolean email: boolean banner: boolean - avatarDecoration: boolean + avatarDecorationData: boolean + } + avatarDecorationData: { + asset: boolean + skuId: boolean } webhook: { id: boolean @@ -628,6 +637,7 @@ export interface Transformers { sku: (bot: Bot, payload: DiscordSku) => Sku poll: (bot: Bot, payload: DiscordPoll) => Poll pollMedia: (bot: Bot, payload: DiscordPollMedia) => PollMedia + avatarDecorationData: (bot: Bot, payload: DiscordAvatarDecorationData) => AvatarDecorationData } export interface CreateTransformerOptions { @@ -790,6 +800,9 @@ export function createTransformers(options: Partial, opts?: Create pollMedia(bot, payload, pollMedia) { return pollMedia }, + avatarDecorationData(bot, payload, avatarDecorationData) { + return avatarDecorationData + }, }, desiredProperties: { attachment: { @@ -953,6 +966,7 @@ export function createTransformers(options: Partial, opts?: Create deaf: opts?.defaultDesiredPropertiesValue ?? false, mute: opts?.defaultDesiredPropertiesValue ?? false, pending: opts?.defaultDesiredPropertiesValue ?? false, + avatarDecorationData: opts?.defaultDesiredPropertiesValue ?? false, }, message: { activity: opts?.defaultDesiredPropertiesValue ?? false, @@ -1082,7 +1096,11 @@ export function createTransformers(options: Partial, opts?: Create verified: opts?.defaultDesiredPropertiesValue ?? false, email: opts?.defaultDesiredPropertiesValue ?? false, banner: opts?.defaultDesiredPropertiesValue ?? false, - avatarDecoration: opts?.defaultDesiredPropertiesValue ?? false, + avatarDecorationData: opts?.defaultDesiredPropertiesValue ?? false, + }, + avatarDecorationData: { + asset: opts?.defaultDesiredPropertiesValue ?? false, + skuId: opts?.defaultDesiredPropertiesValue ?? false, }, webhook: { id: opts?.defaultDesiredPropertiesValue ?? false, @@ -1237,5 +1255,6 @@ export function createTransformers(options: Partial, opts?: Create sku: options.sku ?? transformSku, poll: options.poll ?? transformPoll, pollMedia: options.pollMedia ?? transformPollMedia, + avatarDecorationData: options.avatarDecorationData ?? transformAvatarDecorationData, } } diff --git a/packages/bot/src/transformers/avatarDecorationData.ts b/packages/bot/src/transformers/avatarDecorationData.ts new file mode 100644 index 000000000..73c13fbf2 --- /dev/null +++ b/packages/bot/src/transformers/avatarDecorationData.ts @@ -0,0 +1,18 @@ +import { iconHashToBigInt, type Bot, type DiscordAvatarDecorationData } from '../index.js' + +export function transformAvatarDecorationData(bot: Bot, payload: DiscordAvatarDecorationData): AvatarDecorationData { + const data = {} as AvatarDecorationData + const props = bot.transformers.desiredProperties.avatarDecorationData + + if (props.asset && payload.asset) data.asset = iconHashToBigInt(payload.asset) + if (props.skuId && payload.sku_id) data.skuId = bot.transformers.snowflake(payload.sku_id) + + return data +} + +export interface AvatarDecorationData { + /** the avatar decoration hash */ + asset: bigint + /** id of the avatar decoration's SKU */ + skuId: bigint +} diff --git a/packages/bot/src/transformers/index.ts b/packages/bot/src/transformers/index.ts index 4a034475b..e111dad95 100644 --- a/packages/bot/src/transformers/index.ts +++ b/packages/bot/src/transformers/index.ts @@ -8,6 +8,7 @@ export * from './attachment.js' export * from './auditLogEntry.js' export * from './automodActionExecution.js' export * from './automodRule.js' +export * from './avatarDecorationData.js' export * from './channel.js' export * from './component.js' export * from './embed.js' diff --git a/packages/bot/src/transformers/member.ts b/packages/bot/src/transformers/member.ts index 6e7552938..ed7f2504e 100644 --- a/packages/bot/src/transformers/member.ts +++ b/packages/bot/src/transformers/member.ts @@ -1,8 +1,9 @@ import type { BigString, DiscordMember } from '@discordeno/types' import { iconHashToBigInt } from '@discordeno/utils' import type { Bot } from '../bot.js' -import { MemberToggles } from './toggles/member.js' +import type { AvatarDecorationData } from './avatarDecorationData.js' import { Permissions } from './toggles/Permissions.js' +import { MemberToggles } from './toggles/member.js' import type { User } from './user.js' const baseMember: Partial & BaseMember = { @@ -35,6 +36,8 @@ export function transformMember(bot: Bot, payload: DiscordMember, guildId: BigSt if (props.deaf || props.mute || props.pending) { member.toggles = new MemberToggles(payload) } + if (props.avatarDecorationData && payload.avatar_decoration_data) + member.avatarDecorationData = bot.transformers.avatarDecorationData(bot, payload.avatar_decoration_data) return bot.transformers.customizers.member(bot, payload, member) } @@ -71,4 +74,6 @@ export interface Member extends BaseMember { permissions?: Permissions /** when the user's timeout will expire and the user will be able to communicate in the guild again (set null to remove timeout), null or a time in the past if the user is not timed out */ communicationDisabledUntil?: number + /** data for the member's guild avatar decoration */ + avatarDecorationData: AvatarDecorationData } diff --git a/packages/bot/src/transformers/reverse/member.ts b/packages/bot/src/transformers/reverse/member.ts index 947bc5de0..17b0a16d6 100644 --- a/packages/bot/src/transformers/reverse/member.ts +++ b/packages/bot/src/transformers/reverse/member.ts @@ -35,5 +35,10 @@ export function transformMemberToDiscordMember(bot: Bot, payload: Member): Disco deaf: payload.toggles?.deaf, mute: payload.toggles?.mute, pending: payload.toggles?.pending, + avatar_decoration_data: { + asset: iconBigintToHash(payload.avatarDecorationData.asset), + sku_id: bot.transformers.reverse.snowflake(payload.avatarDecorationData.skuId), + }, + user: payload.user ? bot.transformers.reverse.user(bot, payload.user) : undefined, } } diff --git a/packages/bot/src/transformers/user.ts b/packages/bot/src/transformers/user.ts index ca1fa04b7..898cdc909 100644 --- a/packages/bot/src/transformers/user.ts +++ b/packages/bot/src/transformers/user.ts @@ -1,6 +1,6 @@ import type { DiscordUser, PremiumTypes } from '@discordeno/types' import { iconHashToBigInt } from '@discordeno/utils' -import { ToggleBitfield, UserToggles, type Bot } from '../index.js' +import { ToggleBitfield, UserToggles, type AvatarDecorationData, type Bot } from '../index.js' const baseUser: Partial & BaseUser = { get tag() { @@ -39,8 +39,9 @@ export function transformUser(bot: Bot, payload: DiscordUser): User { if (props.premiumType && payload.premium_type) user.premiumType = payload.premium_type if (props.avatar && payload.avatar) user.avatar = iconHashToBigInt(payload.avatar) if (props.banner && payload.banner) user.banner = iconHashToBigInt(payload.banner) - if (props.avatarDecoration && payload.avatar_decoration) user.avatarDecoration = iconHashToBigInt(payload.avatar_decoration) if (props.accentColor && payload.accent_color) user.accentColor = payload.accent_color + if (props.avatarDecorationData && payload.avatar_decoration_data) + user.avatarDecorationData = bot.transformers.avatarDecorationData(bot, payload.avatar_decoration_data) return bot.transformers.customizers.user(bot, payload, user) } @@ -85,6 +86,6 @@ export interface User extends BaseUser { email?: string /** the user's banner, or null if unset */ banner?: bigint - /** the user's avatar decoration, or null if unset */ - avatarDecoration?: bigint + /** data for the user's avatar decoration */ + avatarDecorationData?: AvatarDecorationData } diff --git a/packages/types/src/discord.ts b/packages/types/src/discord.ts index a81b92634..8744a3897 100644 --- a/packages/types/src/discord.ts +++ b/packages/types/src/discord.ts @@ -78,8 +78,8 @@ export interface DiscordUser { email?: string | null /** the user's banner, or null if unset */ banner?: string - /** the user's avatar decoration, or null if unset */ - avatar_decoration?: string + /** data for the user's avatar decoration */ + avatar_decoration_data?: DiscordAvatarDecorationData } /** https://discord.com/developers/docs/topics/oauth2#shared-resources-oauth2-scopes */ @@ -329,6 +329,16 @@ export interface DiscordMember { permissions?: string /** when the user's timeout will expire and the user will be able to communicate in the guild again (set null to remove timeout), null or a time in the past if the user is not timed out */ communication_disabled_until?: string | null + /** data for the member's guild avatar decoration */ + avatar_decoration_data?: DiscordAvatarDecorationData | null +} + +/** https://discord.com/developers/docs/resources/user#avatar-decoration-data-object */ +export interface DiscordAvatarDecorationData { + /** the avatar decoration hash */ + asset: string + /** id of the avatar decoration's SKU */ + sku_id: string } /** https://discord.com/developers/docs/resources/application#application-object */ diff --git a/packages/utils/src/images.ts b/packages/utils/src/images.ts index 1ce6b2d60..0920af308 100644 --- a/packages/utils/src/images.ts +++ b/packages/utils/src/images.ts @@ -44,8 +44,8 @@ export function avatarUrl( : `https://cdn.discordapp.com/embed/avatars/${discriminator === '0' ? (BigInt(userId) >> BigInt(22)) % BigInt(6) : Number(discriminator) % 5}.png` } -export function avatarDecorationUrl(userId: BigString, avatarDecoration: BigString): string { - return `https://cdn.discordapp.com/avatar-decorations/${userId}/${ +export function avatarDecorationUrl(avatarDecoration: BigString): string { + return `https://cdn.discordapp.com/avatar-decoration-presets/${ typeof avatarDecoration === 'string' ? avatarDecoration : iconBigintToHash(avatarDecoration) }.png` }