From 7f1ffc83717f2dc848b37946ff0e45bbc1f947d9 Mon Sep 17 00:00:00 2001 From: almeidx Date: Sun, 5 Apr 2026 19:27:13 +0100 Subject: [PATCH 1/2] feat(ClientApplication): add fetchActivityInstance method --- .../src/structures/ClientApplication.js | 43 +++++++++++++++++++ packages/discord.js/src/util/APITypes.js | 5 +++ packages/discord.js/typings/index.d.ts | 17 ++++++++ 3 files changed, 65 insertions(+) diff --git a/packages/discord.js/src/structures/ClientApplication.js b/packages/discord.js/src/structures/ClientApplication.js index 072286a8e4f1..e7d7844fd90c 100644 --- a/packages/discord.js/src/structures/ClientApplication.js +++ b/packages/discord.js/src/structures/ClientApplication.js @@ -446,6 +446,49 @@ class ClientApplication extends Application { const skus = await this.client.rest.get(Routes.skus(this.id)); return skus.reduce((coll, sku) => coll.set(sku.id, new SKU(this.client, sku)), new Collection()); } + + /** + * Represents the location of an activity instance. + * + * @typedef {Object} ActivityLocation + * @property {string} id Unique identifier for the location + * @property {ActivityLocationKind} kind The kind of location + * @property {Snowflake} channelId The id of the channel + * @property {?Snowflake} guildId The id of the guild + */ + + /** + * Represents an activity instance. + * + * @typedef {Object} ActivityInstanceData + * @property {Snowflake} applicationId The application id + * @property {string} instanceId The activity instance id + * @property {Snowflake} launchId Unique identifier for the launch + * @property {ActivityLocation} location The location the instance is running in + * @property {Snowflake[]} users The ids of the users connected to the instance + */ + + /** + * Fetches an activity instance for this application. + * + * @param {string} instanceId The id of the activity instance + * @returns {Promise} + */ + async fetchActivityInstance(instanceId) { + const data = await this.client.rest.get(Routes.applicationActivityInstance(this.id, instanceId)); + return { + applicationId: data.application_id, + instanceId: data.instance_id, + launchId: data.launch_id, + location: { + id: data.location.id, + kind: data.location.kind, + channelId: data.location.channel_id, + guildId: data.location.guild_id ?? null, + }, + users: data.users, + }; + } } exports.ClientApplication = ClientApplication; diff --git a/packages/discord.js/src/util/APITypes.js b/packages/discord.js/src/util/APITypes.js index 1e11f869279b..75638dbd185d 100644 --- a/packages/discord.js/src/util/APITypes.js +++ b/packages/discord.js/src/util/APITypes.js @@ -5,6 +5,11 @@ * @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/ActivityFlags} */ +/** + * @external ActivityLocationKind + * @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/ActivityLocationKind} + */ + /** * @external ActivityType * @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/ActivityType} diff --git a/packages/discord.js/typings/index.d.ts b/packages/discord.js/typings/index.d.ts index be0aeac86f0f..6057f0ea2417 100644 --- a/packages/discord.js/typings/index.d.ts +++ b/packages/discord.js/typings/index.d.ts @@ -9,6 +9,7 @@ import { WebSocketManager, WebSocketManagerOptions } from '@discordjs/ws'; import { AsyncEventEmitter } from '@vladfrangu/async_event_emitter'; import { ActivityFlags, + ActivityLocationKind, ActivityType, APIActionRowComponent, APIApplicationCommand, @@ -1004,6 +1005,7 @@ export class ClientApplication extends Application { public roleConnectionsVerificationURL: string | null; public edit(options: ClientApplicationEditOptions): Promise; public fetch(): Promise; + public fetchActivityInstance(instanceId: string): Promise; public fetchRoleConnectionMetadataRecords(): Promise; public fetchSKUs(): Promise>; public editRoleConnectionMetadataRecords( @@ -7402,6 +7404,21 @@ export interface ClientApplicationInstallParams { scopes: readonly OAuth2Scopes[]; } +export interface ActivityLocation { + channelId: Snowflake; + guildId: Snowflake | null; + id: string; + kind: ActivityLocationKind; +} + +export interface ActivityInstanceData { + applicationId: Snowflake; + instanceId: string; + launchId: Snowflake; + location: ActivityLocation; + users: readonly Snowflake[]; +} + export type Serialized = Value extends bigint | symbol | (() => any) ? never : Value extends boolean | number | string | undefined From a3f9fbfd409cbde911ed16791042444a322a2831 Mon Sep 17 00:00:00 2001 From: almeidx Date: Tue, 7 Apr 2026 21:23:19 +0100 Subject: [PATCH 2/2] refactor: requested changes --- packages/discord.js/src/index.js | 2 + .../src/structures/ActivityInstance.js | 52 +++++++++++++++ .../src/structures/ActivityLocation.js | 65 +++++++++++++++++++ .../src/structures/ClientApplication.js | 37 +---------- packages/discord.js/typings/index.d.ts | 38 ++++++----- 5 files changed, 144 insertions(+), 50 deletions(-) create mode 100644 packages/discord.js/src/structures/ActivityInstance.js create mode 100644 packages/discord.js/src/structures/ActivityLocation.js diff --git a/packages/discord.js/src/index.js b/packages/discord.js/src/index.js index 3a344e146989..51ea4f6fd918 100644 --- a/packages/discord.js/src/index.js +++ b/packages/discord.js/src/index.js @@ -103,6 +103,8 @@ exports.VoiceStateManager = require('./managers/VoiceStateManager.js').VoiceStat // Structures exports.ActionRow = require('./structures/ActionRow.js').ActionRow; exports.Activity = require('./structures/Presence.js').Activity; +exports.ActivityInstance = require('./structures/ActivityInstance.js').ActivityInstance; +exports.ActivityLocation = require('./structures/ActivityLocation.js').ActivityLocation; exports.AnnouncementChannel = require('./structures/AnnouncementChannel.js').AnnouncementChannel; exports.AnonymousGuild = require('./structures/AnonymousGuild.js').AnonymousGuild; exports.AuthorizingIntegrationOwners = diff --git a/packages/discord.js/src/structures/ActivityInstance.js b/packages/discord.js/src/structures/ActivityInstance.js new file mode 100644 index 000000000000..3e27f0a5b1e4 --- /dev/null +++ b/packages/discord.js/src/structures/ActivityInstance.js @@ -0,0 +1,52 @@ +'use strict'; + +const { ActivityLocation } = require('./ActivityLocation.js'); +const { Base } = require('./Base.js'); + +/** + * Represents an activity instance. + * + * @extends {Base} + */ +class ActivityInstance extends Base { + constructor(client, data) { + super(client); + + /** + * The id of the application + * + * @type {Snowflake} + */ + this.applicationId = data.application_id; + + /** + * The activity instance id + * + * @type {string} + */ + this.instanceId = data.instance_id; + + /** + * The unique identifier for the launch + * + * @type {Snowflake} + */ + this.launchId = data.launch_id; + + /** + * The location the instance is running in + * + * @type {ActivityLocation} + */ + this.location = new ActivityLocation(client, data.location); + + /** + * The ids of the users connected to the instance + * + * @type {Snowflake[]} + */ + this.users = data.users; + } +} + +exports.ActivityInstance = ActivityInstance; diff --git a/packages/discord.js/src/structures/ActivityLocation.js b/packages/discord.js/src/structures/ActivityLocation.js new file mode 100644 index 000000000000..684b8c9df014 --- /dev/null +++ b/packages/discord.js/src/structures/ActivityLocation.js @@ -0,0 +1,65 @@ +'use strict'; + +const { Base } = require('./Base.js'); + +/** + * Represents the location of an activity instance. + * + * @extends {Base} + */ +class ActivityLocation extends Base { + constructor(client, data) { + super(client); + + /** + * The unique identifier for the location + * + * @type {string} + */ + this.id = data.id; + + /** + * The kind of location + * + * @type {ActivityLocationKind} + */ + this.kind = data.kind; + + /** + * The id of the channel + * + * @type {Snowflake} + */ + this.channelId = data.channel_id; + + /** + * The id of the guild + * + * @type {?Snowflake} + */ + this.guildId = data.guild_id ?? null; + } + + /** + * The channel of this activity location + * + * @type {?Channel} + * @readonly + */ + get channel() { + return this.client.channels.cache.get(this.channelId) ?? null; + } + + /** + * The guild of this activity location + * + * @type {?Guild} + * @readonly + */ + get guild() { + if (!this.guildId) return null; + return this.client.guilds.cache.get(this.guildId) ?? null; + } +} + +exports.ActivityLocation = ActivityLocation; diff --git a/packages/discord.js/src/structures/ClientApplication.js b/packages/discord.js/src/structures/ClientApplication.js index e7d7844fd90c..a4249d2f8ce6 100644 --- a/packages/discord.js/src/structures/ClientApplication.js +++ b/packages/discord.js/src/structures/ClientApplication.js @@ -9,6 +9,7 @@ const { SubscriptionManager } = require('../managers/SubscriptionManager.js'); const { ApplicationFlagsBitField } = require('../util/ApplicationFlagsBitField.js'); const { resolveImage } = require('../util/DataResolver.js'); const { PermissionsBitField } = require('../util/PermissionsBitField.js'); +const { ActivityInstance } = require('./ActivityInstance.js'); const { ApplicationRoleConnectionMetadata } = require('./ApplicationRoleConnectionMetadata.js'); const { SKU } = require('./SKU.js'); const { Team } = require('./Team.js'); @@ -447,47 +448,15 @@ class ClientApplication extends Application { return skus.reduce((coll, sku) => coll.set(sku.id, new SKU(this.client, sku)), new Collection()); } - /** - * Represents the location of an activity instance. - * - * @typedef {Object} ActivityLocation - * @property {string} id Unique identifier for the location - * @property {ActivityLocationKind} kind The kind of location - * @property {Snowflake} channelId The id of the channel - * @property {?Snowflake} guildId The id of the guild - */ - - /** - * Represents an activity instance. - * - * @typedef {Object} ActivityInstanceData - * @property {Snowflake} applicationId The application id - * @property {string} instanceId The activity instance id - * @property {Snowflake} launchId Unique identifier for the launch - * @property {ActivityLocation} location The location the instance is running in - * @property {Snowflake[]} users The ids of the users connected to the instance - */ - /** * Fetches an activity instance for this application. * * @param {string} instanceId The id of the activity instance - * @returns {Promise} + * @returns {Promise} */ async fetchActivityInstance(instanceId) { const data = await this.client.rest.get(Routes.applicationActivityInstance(this.id, instanceId)); - return { - applicationId: data.application_id, - instanceId: data.instance_id, - launchId: data.launch_id, - location: { - id: data.location.id, - kind: data.location.kind, - channelId: data.location.channel_id, - guildId: data.location.guild_id ?? null, - }, - users: data.users, - }; + return new ActivityInstance(this.client, data); } } diff --git a/packages/discord.js/typings/index.d.ts b/packages/discord.js/typings/index.d.ts index 6057f0ea2417..ddd06359558b 100644 --- a/packages/discord.js/typings/index.d.ts +++ b/packages/discord.js/typings/index.d.ts @@ -9,6 +9,8 @@ import { WebSocketManager, WebSocketManagerOptions } from '@discordjs/ws'; import { AsyncEventEmitter } from '@vladfrangu/async_event_emitter'; import { ActivityFlags, + APIActivityInstance, + APIActivityLocation, ActivityLocationKind, ActivityType, APIActionRowComponent, @@ -247,6 +249,25 @@ export class Activity { public toString(): string; } +export class ActivityInstance extends Base { + private constructor(client: Client, data: APIActivityInstance); + public applicationId: Snowflake; + public instanceId: string; + public launchId: Snowflake; + public location: ActivityLocation; + public users: Snowflake[]; +} + +export class ActivityLocation extends Base { + private constructor(client: Client, data: APIActivityLocation); + public id: string; + public kind: ActivityLocationKind; + public channelId: Snowflake; + public guildId: Snowflake | null; + public get channel(): Channel | null; + public get guild(): Guild | null; +} + export type ActivityFlagsString = keyof typeof ActivityFlags; export interface BaseComponentData { @@ -1005,7 +1026,7 @@ export class ClientApplication extends Application { public roleConnectionsVerificationURL: string | null; public edit(options: ClientApplicationEditOptions): Promise; public fetch(): Promise; - public fetchActivityInstance(instanceId: string): Promise; + public fetchActivityInstance(instanceId: string): Promise; public fetchRoleConnectionMetadataRecords(): Promise; public fetchSKUs(): Promise>; public editRoleConnectionMetadataRecords( @@ -7404,21 +7425,6 @@ export interface ClientApplicationInstallParams { scopes: readonly OAuth2Scopes[]; } -export interface ActivityLocation { - channelId: Snowflake; - guildId: Snowflake | null; - id: string; - kind: ActivityLocationKind; -} - -export interface ActivityInstanceData { - applicationId: Snowflake; - instanceId: string; - launchId: Snowflake; - location: ActivityLocation; - users: readonly Snowflake[]; -} - export type Serialized = Value extends bigint | symbol | (() => any) ? never : Value extends boolean | number | string | undefined