diff --git a/src/structures/ClientApplication.js b/src/structures/ClientApplication.js index aaefe1a2fd48..04971ea0dce3 100644 --- a/src/structures/ClientApplication.js +++ b/src/structures/ClientApplication.js @@ -30,7 +30,7 @@ class ClientApplication extends Application { this.flags = 'flags' in data ? new ApplicationFlags(data.flags) : this.flags; /** - * The app's cover image + * The hash of the application's cover image * @type {?string} */ this.cover = data.cover_image ?? this.cover ?? null; diff --git a/src/structures/GuildChannel.js b/src/structures/GuildChannel.js index c2bf5e367038..167b8dbc9d3c 100644 --- a/src/structures/GuildChannel.js +++ b/src/structures/GuildChannel.js @@ -472,6 +472,14 @@ class GuildChannel extends Channel { }); } + /** + * Data that can be resolved to an Application. This can be: + * * An Application + * * An Activity with associated Application + * * A Snowflake + * @typedef {Application|Snowflake} ApplicationResolvable + */ + /** * Creates an invite to this guild channel. * @param {Object} [options={}] Options for the invite @@ -480,6 +488,11 @@ class GuildChannel extends Channel { * @param {number} [options.maxAge=86400] How long the invite should last (in seconds, 0 for forever) * @param {number} [options.maxUses=0] Maximum number of uses * @param {boolean} [options.unique=false] Create a unique invite, or use an existing one with similar settings + * @param {UserResolvable} [options.targetUser] The user whose stream to display for this invite, + * required if `targetType` is 1, the user must be streaming in the channel + * @param {ApplicationResolvable} [options.targetApplication] The embedded application to open for this invite, + * required if `targetType` is 2, the application must have the `EMBEDDED` flag + * @param {InviteTargetType} [options.targetType] The type of the target for this voice channel invite * @param {string} [options.reason] Reason for creating this * @returns {Promise} * @example @@ -488,7 +501,16 @@ class GuildChannel extends Channel { * .then(invite => console.log(`Created an invite with a code of ${invite.code}`)) * .catch(console.error); */ - createInvite({ temporary = false, maxAge = 86400, maxUses = 0, unique, reason } = {}) { + createInvite({ + temporary = false, + maxAge = 86400, + maxUses = 0, + unique, + targetUser, + targetApplication, + targetType, + reason, + } = {}) { return this.client.api .channels(this.id) .invites.post({ @@ -497,6 +519,9 @@ class GuildChannel extends Channel { max_age: maxAge, max_uses: maxUses, unique, + target_user_id: this.client.users.resolveID(targetUser), + target_application_id: targetApplication?.id ?? targetApplication?.applicationID ?? targetApplication, + target_type: targetType, }, reason, }) diff --git a/src/structures/IntegrationApplication.js b/src/structures/IntegrationApplication.js index d6372bfd0a22..b820331bccde 100644 --- a/src/structures/IntegrationApplication.js +++ b/src/structures/IntegrationApplication.js @@ -15,6 +15,48 @@ class IntegrationApplication extends Application { * @type {?User} */ this.bot = data.bot ? this.client.users.add(data.bot) : this.bot ?? null; + + /** + * The url of the app's terms of service + * @type {?string} + */ + this.termsOfServiceURL = data.terms_of_service_url ?? this.termsOfServiceURL ?? null; + + /** + * The url of the app's privacy policy + * @type {?string} + */ + this.privacyPolicyURL = data.privacy_policy_url ?? this.privacyPolicyURL ?? null; + + /** + * The Array of RPC origin urls + * @type {string[]} + */ + this.rpcOrigins = data.rpc_origins ?? this.rpcOrigins ?? []; + + /** + * The application summary + * @type {?string} + */ + this.summary = data.summary ?? this.summary ?? null; + + /** + * Whether the application can be default hooked by the client + * @type {?boolean} + */ + this.hook = data.hook ?? this.hook ?? null; + + /** + * The hash of the application's cover image + * @type {?string} + */ + this.cover = data.cover_image ?? this.cover ?? null; + + /** + * The hex-encoded key for verification in interactions and the GameSDK's GetTicket + * @type {?string} + */ + this.verifyKey = data.verify_key ?? this.verifyKey ?? null; } } diff --git a/src/structures/Invite.js b/src/structures/Invite.js index f252253a61eb..50a5660aafdd 100644 --- a/src/structures/Invite.js +++ b/src/structures/Invite.js @@ -1,6 +1,7 @@ 'use strict'; const Base = require('./Base'); +const IntegrationApplication = require('./IntegrationApplication'); const { Endpoints } = require('../util/Constants'); const Permissions = require('../util/Permissions'); @@ -71,22 +72,31 @@ class Invite extends Base { this.inviter = data.inviter ? this.client.users.add(data.inviter) : null; /** - * The target user for this invite + * The user whose stream to display for this voice channel stream invite * @type {?User} */ this.targetUser = data.target_user ? this.client.users.add(data.target_user) : null; /** - * The type of the target user: + * The embedded application to open for this voice channel embedded application invite + * @type {?IntegrationApplication} + */ + this.targetApplication = data.target_application + ? new IntegrationApplication(this.client, data.target_application) + : null; + + /** + * The type of the invite target: * * 1: STREAM - * @typedef {number} TargetUser + * * 2: EMBEDDED_APPLICATION + * @typedef {number} TargetType */ /** - * The target user type - * @type {?TargetUser} + * The target type + * @type {?TargetType} */ - this.targetUserType = typeof data.target_user_type === 'number' ? data.target_user_type : null; + this.targetType = typeof data.target_type === 'number' ? data.target_type : null; /** * The channel the invite is for diff --git a/src/structures/interfaces/Application.js b/src/structures/interfaces/Application.js index c8b198fbb62b..af335a3ed3c8 100644 --- a/src/structures/interfaces/Application.js +++ b/src/structures/interfaces/Application.js @@ -75,7 +75,7 @@ class Application extends Base { * @param {ImageURLOptions} [options={}] Options for the Image URL * @returns {?string} URL to the cover image */ - coverImage({ format, size } = {}) { + coverURL({ format, size } = {}) { if (!this.cover) return null; return Endpoints.CDN(this.client.options.http.cdn).AppIcon(this.id, this.cover, { format, size }); } diff --git a/typings/index.d.ts b/typings/index.d.ts index 88be93f89d3a..d21c79798e1d 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -32,6 +32,11 @@ declare enum InteractionTypes { APPLICATION_COMMAND = 2, } +declare enum InviteTargetType { + STREAM = 1, + EMBEDDED_APPLICATION = 2, +} + declare enum OverwriteTypes { role = 0, member = 1, @@ -153,7 +158,7 @@ declare module 'discord.js' { public icon: string | null; public id: Snowflake; public name: string | null; - public coverImage(options?: ImageURLOptions): string | null; + public coverURL(options?: ImageURLOptions): string | null; public fetchAssets(): Promise; public iconURL(options?: ImageURLOptions): string | null; public toJSON(): object; @@ -178,6 +183,8 @@ declare module 'discord.js' { private static transformOption(option: ApplicationCommandOptionData, received?: boolean): object; } + type ApplicationResolvable = Application | Activity | Snowflake; + export class ApplicationFlags extends BitField { public static FLAGS: Record; public static resolve(bit?: BitFieldResolvable): number; @@ -1034,6 +1041,13 @@ declare module 'discord.js' { export class IntegrationApplication extends Application { public bot: User | null; + public termsOfServiceURL: string | null; + public privacyPolicyURL: string | null; + public rpcOrigins: string[]; + public summary: string | null; + public hook: boolean | null; + public cover: string | null; + public verifyKey: string | null; } export class Intents extends BitField { @@ -1077,8 +1091,9 @@ declare module 'discord.js' { public maxUses: number | null; public memberCount: number; public presenceCount: number; + public targetApplication: IntegrationApplication | null; public targetUser: User | null; - public targetUserType: TargetUser | null; + public targetType: InviteTargetType | null; public temporary: boolean | null; public readonly url: string; public uses: number | null; @@ -3091,6 +3106,9 @@ declare module 'discord.js' { maxUses?: number; unique?: boolean; reason?: string; + targetApplication?: ApplicationResolvable; + targetUser?: UserResolvable; + targetType?: InviteTargetType; } type InviteResolvable = string; @@ -3560,8 +3578,6 @@ declare module 'discord.js' { type SystemMessageType = Exclude; - type TargetUser = number; - interface TypingData { user: User | PartialUser; since: Date;