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 072286a8e4f1..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'); @@ -446,6 +447,17 @@ 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()); } + + /** + * 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 new ActivityInstance(this.client, data); + } } 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..ddd06359558b 100644 --- a/packages/discord.js/typings/index.d.ts +++ b/packages/discord.js/typings/index.d.ts @@ -9,6 +9,9 @@ import { WebSocketManager, WebSocketManagerOptions } from '@discordjs/ws'; import { AsyncEventEmitter } from '@vladfrangu/async_event_emitter'; import { ActivityFlags, + APIActivityInstance, + APIActivityLocation, + ActivityLocationKind, ActivityType, APIActionRowComponent, APIApplicationCommand, @@ -246,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 { @@ -1004,6 +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 fetchRoleConnectionMetadataRecords(): Promise; public fetchSKUs(): Promise>; public editRoleConnectionMetadataRecords(