From 2f734e74c5cf4ab2f2f3bdc6b9c2c22d8b697939 Mon Sep 17 00:00:00 2001 From: Qjuh <76154676+Qjuh@users.noreply.github.com> Date: Tue, 20 May 2025 18:12:39 +0200 Subject: [PATCH] feat: backport entrypoint command --- .../src/client/actions/InteractionCreate.js | 4 + packages/discord.js/src/index.js | 1 + .../src/managers/ApplicationCommandManager.js | 1 + .../src/structures/ApplicationCommand.js | 24 +++++- .../src/structures/BaseInteraction.js | 10 +++ .../src/structures/CommandInteraction.js | 1 + .../structures/MessageComponentInteraction.js | 1 + .../src/structures/ModalSubmitInteraction.js | 1 + .../PrimaryEntryPointCommandInteraction.js | 11 +++ .../interfaces/InteractionResponses.js | 26 ++++++ packages/discord.js/src/util/APITypes.js | 5 ++ packages/discord.js/typings/index.d.ts | 70 +++++++++++---- packages/discord.js/typings/index.test-d.ts | 86 +++++++++++++++++++ 13 files changed, 220 insertions(+), 21 deletions(-) create mode 100644 packages/discord.js/src/structures/PrimaryEntryPointCommandInteraction.js diff --git a/packages/discord.js/src/client/actions/InteractionCreate.js b/packages/discord.js/src/client/actions/InteractionCreate.js index 434fb0c0689c..ee04fa20bc08 100644 --- a/packages/discord.js/src/client/actions/InteractionCreate.js +++ b/packages/discord.js/src/client/actions/InteractionCreate.js @@ -9,6 +9,7 @@ const ChatInputCommandInteraction = require('../../structures/ChatInputCommandIn const MentionableSelectMenuInteraction = require('../../structures/MentionableSelectMenuInteraction'); const MessageContextMenuCommandInteraction = require('../../structures/MessageContextMenuCommandInteraction'); const ModalSubmitInteraction = require('../../structures/ModalSubmitInteraction'); +const PrimaryEntryPointCommandInteraction = require('../../structures/PrimaryEntryPointCommandInteraction'); const RoleSelectMenuInteraction = require('../../structures/RoleSelectMenuInteraction'); const StringSelectMenuInteraction = require('../../structures/StringSelectMenuInteraction'); const UserContextMenuCommandInteraction = require('../../structures/UserContextMenuCommandInteraction'); @@ -38,6 +39,9 @@ class InteractionCreateAction extends Action { if (channel && !channel.isTextBased()) return; InteractionClass = MessageContextMenuCommandInteraction; break; + case ApplicationCommandType.PrimaryEntryPoint: + InteractionClass = PrimaryEntryPointCommandInteraction; + break; default: client.emit( Events.Debug, diff --git a/packages/discord.js/src/index.js b/packages/discord.js/src/index.js index 243f1af41228..a431f41eb16f 100644 --- a/packages/discord.js/src/index.js +++ b/packages/discord.js/src/index.js @@ -180,6 +180,7 @@ exports.PartialGroupDMChannel = require('./structures/PartialGroupDMChannel'); exports.PermissionOverwrites = require('./structures/PermissionOverwrites'); exports.Poll = require('./structures/Poll').Poll; exports.PollAnswer = require('./structures/PollAnswer').PollAnswer; +exports.PrimaryEntryPointCommandInteraction = require('./structures/PrimaryEntryPointCommandInteraction'); exports.Presence = require('./structures/Presence').Presence; exports.ReactionCollector = require('./structures/ReactionCollector'); exports.ReactionEmoji = require('./structures/ReactionEmoji'); diff --git a/packages/discord.js/src/managers/ApplicationCommandManager.js b/packages/discord.js/src/managers/ApplicationCommandManager.js index 8f6ce53106d4..9a8fd2e9d7bc 100644 --- a/packages/discord.js/src/managers/ApplicationCommandManager.js +++ b/packages/discord.js/src/managers/ApplicationCommandManager.js @@ -261,6 +261,7 @@ class ApplicationCommandManager extends CachedManager { dm_permission: command.dmPermission ?? command.dm_permission, integration_types: command.integrationTypes ?? command.integration_types, contexts: command.contexts, + handler: command.handler, }; } } diff --git a/packages/discord.js/src/structures/ApplicationCommand.js b/packages/discord.js/src/structures/ApplicationCommand.js index 37eff9e46d5c..9490fab93063 100644 --- a/packages/discord.js/src/structures/ApplicationCommand.js +++ b/packages/discord.js/src/structures/ApplicationCommand.js @@ -174,6 +174,18 @@ class ApplicationCommand extends Base { this.contexts ??= null; } + if ('handler' in data) { + /** + * Determines whether the interaction is handled by the app's interactions handler or by Discord. + * Only available for {@link ApplicationCommandType.PrimaryEntryPoint} commands on + * applications with the {@link ApplicationFlags.Embedded} flag (i.e, those that have an Activity) + * @type {?EntryPointCommandHandlerType} + */ + this.handler = data.handler; + } else { + this.handler ??= null; + } + if ('version' in data) { /** * Autoincrementing version identifier updated during substantial record changes @@ -216,15 +228,20 @@ class ApplicationCommand extends Base { * @property {string} name The name of the command, must be in all lowercase if type is * {@link ApplicationCommandType.ChatInput} * @property {Object} [nameLocalizations] The localizations for the command name - * @property {string} description The description of the command, if type is {@link ApplicationCommandType.ChatInput} + * @property {string} description The description of the command, + * if type is {@link ApplicationCommandType.ChatInput} or {@link ApplicationCommandType.PrimaryEntryPoint} * @property {boolean} [nsfw] Whether the command is age-restricted * @property {Object} [descriptionLocalizations] The localizations for the command description, - * if type is {@link ApplicationCommandType.ChatInput} + * if type is {@link ApplicationCommandType.ChatInput} or {@link ApplicationCommandType.PrimaryEntryPoint} * @property {ApplicationCommandType} [type=ApplicationCommandType.ChatInput] The type of the command * @property {ApplicationCommandOptionData[]} [options] Options for the command * @property {?PermissionResolvable} [defaultMemberPermissions] The bitfield used to determine the default permissions * a member needs in order to run the command * @property {boolean} [dmPermission] Whether the command is enabled in DMs + * @property {ApplicationIntegrationType[]} [integrationTypes] Installation contexts where the command is available + * @property {InteractionContextType[]} [contexts] Interaction contexts where the command can be used + * @property {EntryPointCommandHandlerType} [handler] Whether the interaction is handled by the app's + * interactions handler or by Discord. */ /** @@ -419,7 +436,8 @@ class ApplicationCommand extends Base { this.descriptionLocalizations ?? {}, ) || !isEqual(command.integrationTypes ?? command.integration_types ?? [], this.integrationTypes ?? []) || - !isEqual(command.contexts ?? [], this.contexts ?? []) + !isEqual(command.contexts ?? [], this.contexts ?? []) || + ('handler' in command && command.handler !== this.handler) ) { return false; } diff --git a/packages/discord.js/src/structures/BaseInteraction.js b/packages/discord.js/src/structures/BaseInteraction.js index 4e7ad59e421d..68817b33165e 100644 --- a/packages/discord.js/src/structures/BaseInteraction.js +++ b/packages/discord.js/src/structures/BaseInteraction.js @@ -225,6 +225,16 @@ class BaseInteraction extends Base { ); } + /** + * Indicates whether this interaction is a {@link PrimaryEntryPointCommandInteraction} + * @returns {boolean} + */ + isPrimaryEntryPointCommand() { + return ( + this.type === InteractionType.ApplicationCommand && this.commandType === ApplicationCommandType.PrimaryEntryPoint + ); + } + /** * Indicates whether this interaction is a {@link MessageComponentInteraction} * @returns {boolean} diff --git a/packages/discord.js/src/structures/CommandInteraction.js b/packages/discord.js/src/structures/CommandInteraction.js index 0d435deeb446..2951a55f296d 100644 --- a/packages/discord.js/src/structures/CommandInteraction.js +++ b/packages/discord.js/src/structures/CommandInteraction.js @@ -152,6 +152,7 @@ class CommandInteraction extends BaseInteraction { editReply() {} deleteReply() {} followUp() {} + launchActivity() {} showModal() {} sendPremiumRequired() {} awaitModalSubmit() {} diff --git a/packages/discord.js/src/structures/MessageComponentInteraction.js b/packages/discord.js/src/structures/MessageComponentInteraction.js index f27050c15431..852cf8a98301 100644 --- a/packages/discord.js/src/structures/MessageComponentInteraction.js +++ b/packages/discord.js/src/structures/MessageComponentInteraction.js @@ -97,6 +97,7 @@ class MessageComponentInteraction extends BaseInteraction { followUp() {} deferUpdate() {} update() {} + launchActivity() {} showModal() {} sendPremiumRequired() {} awaitModalSubmit() {} diff --git a/packages/discord.js/src/structures/ModalSubmitInteraction.js b/packages/discord.js/src/structures/ModalSubmitInteraction.js index ba94190436da..0b23b9ab817f 100644 --- a/packages/discord.js/src/structures/ModalSubmitInteraction.js +++ b/packages/discord.js/src/structures/ModalSubmitInteraction.js @@ -119,6 +119,7 @@ class ModalSubmitInteraction extends BaseInteraction { deferUpdate() {} update() {} sendPremiumRequired() {} + launchActivity() {} } InteractionResponses.applyToClass(ModalSubmitInteraction, 'showModal'); diff --git a/packages/discord.js/src/structures/PrimaryEntryPointCommandInteraction.js b/packages/discord.js/src/structures/PrimaryEntryPointCommandInteraction.js new file mode 100644 index 000000000000..a95fa0818c90 --- /dev/null +++ b/packages/discord.js/src/structures/PrimaryEntryPointCommandInteraction.js @@ -0,0 +1,11 @@ +'use strict'; + +const CommandInteraction = require('./CommandInteraction.js'); + +/** + * Represents a primary entry point command interaction. + * @extends {CommandInteraction} + */ +class PrimaryEntryPointCommandInteraction extends CommandInteraction {} + +module.exports = PrimaryEntryPointCommandInteraction; diff --git a/packages/discord.js/src/structures/interfaces/InteractionResponses.js b/packages/discord.js/src/structures/interfaces/InteractionResponses.js index 8ef61ebe7d89..30c41073876d 100644 --- a/packages/discord.js/src/structures/interfaces/InteractionResponses.js +++ b/packages/discord.js/src/structures/interfaces/InteractionResponses.js @@ -69,6 +69,12 @@ class InteractionResponses { * This option is deprecated. Use `withResponse` or fetch the response instead. */ + /** + * Options for launching activity in response to a {@link BaseInteraction} + * @typedef {Object} LaunchActivityOptions + * @property {boolean} [withResponse] Whether to return an {@link InteractionCallbackResponse} as the response + */ + /** * Options for showing a modal in response to a {@link BaseInteraction} * @typedef {Object} ShowModalOptions @@ -370,6 +376,25 @@ class InteractionResponses { : new InteractionResponse(this, this.message.interactionMetadata?.id); } + /** + * Launches this application's activity, if enabled + * @param {LaunchActivityOptions} [options={}] Options for launching the activity + * @returns {Promise} + */ + async launchActivity({ withResponse } = {}) { + if (this.deferred || this.replied) throw new DiscordjsError(ErrorCodes.InteractionAlreadyReplied); + const response = await this.client.rest.post(Routes.interactionCallback(this.id, this.token), { + query: makeURLSearchParams({ with_response: withResponse ?? false }), + body: { + type: InteractionResponseType.LaunchActivity, + }, + auth: false, + }); + this.replied = true; + + return withResponse ? new InteractionCallbackResponse(this.client, response) : undefined; + } + /** * Shows a modal component * @param {ModalBuilder|ModalComponentData|APIModalInteractionResponseCallbackData} modal The modal to show @@ -450,6 +475,7 @@ class InteractionResponses { 'followUp', 'deferUpdate', 'update', + 'launchActivity', 'showModal', 'sendPremiumRequired', 'awaitModalSubmit', diff --git a/packages/discord.js/src/util/APITypes.js b/packages/discord.js/src/util/APITypes.js index 2fc71ad4c36e..b20dc26f99a1 100644 --- a/packages/discord.js/src/util/APITypes.js +++ b/packages/discord.js/src/util/APITypes.js @@ -370,6 +370,11 @@ * @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/EntitlementType} */ +/** + * @external EntryPointCommandHandlerType + * @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/EntryPointCommandHandlerType} + */ + /** * @external ForumLayoutType * @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/ForumLayoutType} diff --git a/packages/discord.js/typings/index.d.ts b/packages/discord.js/typings/index.d.ts index 659b73ad20f7..9dbeab3f6f22 100644 --- a/packages/discord.js/typings/index.d.ts +++ b/packages/discord.js/typings/index.d.ts @@ -213,6 +213,7 @@ import { SeparatorSpacingSize, APIFileComponent, APIMessageTopLevelComponent, + EntryPointCommandHandlerType, } from 'discord-api-types/v10'; import { ChildProcess } from 'node:child_process'; import { EventEmitter } from 'node:events'; @@ -480,6 +481,7 @@ export class ApplicationCommand extends Base { public get manager(): ApplicationCommandManager; public id: Snowflake; public integrationTypes: ApplicationIntegrationType[] | null; + public handler: EntryPointCommandHandlerType | null; public name: string; public nameLocalizations: LocalizationMap | null; public nameLocalized: string | null; @@ -583,23 +585,6 @@ export type BooleanCache = Cached extends 'cached' ? t export abstract class CommandInteraction extends BaseInteraction { public type: InteractionType.ApplicationCommand; public get command(): ApplicationCommand | ApplicationCommand<{ guild: GuildResolvable }> | null; - public options: Omit< - CommandInteractionOptionResolver, - | 'getMessage' - | 'getFocused' - | 'getMentionable' - | 'getRole' - | 'getUser' - | 'getMember' - | 'getAttachment' - | 'getNumber' - | 'getInteger' - | 'getString' - | 'getChannel' - | 'getBoolean' - | 'getSubcommandGroup' - | 'getSubcommand' - >; public channelId: Snowflake; public commandId: Snowflake; public commandName: string; @@ -632,6 +617,9 @@ export abstract class CommandInteraction e public reply( options: string | MessagePayload | InteractionReplyOptions, ): Promise>>; + public launchActivity(options: LaunchActivityOptions & { withResponse: true }): Promise; + public launchActivity(options?: LaunchActivityOptions & { withResponse?: false }): Promise; + public launchActivity(options?: LaunchActivityOptions): Promise; public showModal( modal: | JSONEncodable @@ -1439,6 +1427,23 @@ export class CommandInteractionOptionResolver extends CommandInteraction { + public options: Omit< + CommandInteractionOptionResolver, + | 'getMessage' + | 'getFocused' + | 'getMentionable' + | 'getRole' + | 'getUser' + | 'getMember' + | 'getAttachment' + | 'getNumber' + | 'getInteger' + | 'getString' + | 'getChannel' + | 'getBoolean' + | 'getSubcommandGroup' + | 'getSubcommand' + >; public commandType: ApplicationCommandType.Message | ApplicationCommandType.User; public targetId: Snowflake; public inGuild(): this is ContextMenuCommandInteraction<'raw' | 'cached'>; @@ -1447,6 +1452,15 @@ export class ContextMenuCommandInteraction private resolveContextMenuOptions(data: APIApplicationCommandInteractionData): CommandInteractionOption[]; } +export class PrimaryEntryPointCommandInteraction< + Cached extends CacheType = CacheType, +> extends CommandInteraction { + public commandType: ApplicationCommandType.PrimaryEntryPoint; + public inGuild(): this is PrimaryEntryPointCommandInteraction<'raw' | 'cached'>; + public inCachedGuild(): this is PrimaryEntryPointCommandInteraction<'cached'>; + public inRawGuild(): this is PrimaryEntryPointCommandInteraction<'raw'>; +} + // tslint:disable-next-line no-empty-interface export interface DMChannel extends Omit< @@ -2062,6 +2076,7 @@ export type Interaction = | ChatInputCommandInteraction | MessageContextMenuCommandInteraction | UserContextMenuCommandInteraction + | PrimaryEntryPointCommandInteraction | AnySelectMenuInteraction | ButtonInteraction | AutocompleteInteraction @@ -2111,6 +2126,7 @@ export class BaseInteraction extends Base public isChatInputCommand(): this is ChatInputCommandInteraction; public isCommand(): this is CommandInteraction; public isContextMenuCommand(): this is ContextMenuCommandInteraction; + public isPrimaryEntryPointCommand(): this is PrimaryEntryPointCommandInteraction; public isMessageComponent(): this is MessageComponentInteraction; public isMessageContextMenuCommand(): this is MessageContextMenuCommandInteraction; public isModalSubmit(): this is ModalSubmitInteraction; @@ -2538,6 +2554,9 @@ export class MessageComponentInteraction e public update( options: string | MessagePayload | InteractionUpdateOptions, ): Promise>>; + public launchActivity(options: LaunchActivityOptions & { withResponse: true }): Promise; + public launchActivity(options?: LaunchActivityOptions & { withResponse?: false }): Promise; + public launchActivity(options?: LaunchActivityOptions): Promise; public showModal( modal: | JSONEncodable @@ -2784,6 +2803,9 @@ export class ModalSubmitInteraction extend public deferUpdate(options?: InteractionDeferUpdateOptions): Promise>>; /** @deprecated Sending a premium-style button is the new Discord behaviour. */ public sendPremiumRequired(): Promise; + public launchActivity(options: LaunchActivityOptions & { withResponse: true }): Promise; + public launchActivity(options?: LaunchActivityOptions & { withResponse?: false }): Promise; + public launchActivity(options?: LaunchActivityOptions): Promise; public inGuild(): this is ModalSubmitInteraction<'raw' | 'cached'>; public inCachedGuild(): this is ModalSubmitInteraction<'cached'>; public inRawGuild(): this is ModalSubmitInteraction<'raw'>; @@ -5271,10 +5293,18 @@ export interface ChatInputApplicationCommandData extends BaseApplicationCommandD options?: readonly ApplicationCommandOptionData[]; } +export interface PrimaryEntryPointCommandData extends BaseApplicationCommandData { + description?: string; + descriptionLocalizations?: LocalizationMap; + type: ApplicationCommandType.PrimaryEntryPoint; + handler?: EntryPointCommandHandlerType; +} + export type ApplicationCommandData = | UserApplicationCommandData | MessageApplicationCommandData - | ChatInputApplicationCommandData; + | ChatInputApplicationCommandData + | PrimaryEntryPointCommandData; export interface ApplicationCommandChannelOptionData extends BaseApplicationCommandOptionsData { type: CommandOptionChannelResolvableType; @@ -7376,6 +7406,10 @@ export interface ShowModalOptions { withResponse?: boolean; } +export interface LaunchActivityOptions { + withResponse?: boolean; +} + export { Snowflake }; export type StageInstanceResolvable = StageInstance | Snowflake; diff --git a/packages/discord.js/typings/index.test-d.ts b/packages/discord.js/typings/index.test-d.ts index c3f97a035b14..8e9520503578 100644 --- a/packages/discord.js/typings/index.test-d.ts +++ b/packages/discord.js/typings/index.test-d.ts @@ -218,6 +218,7 @@ import { PollData, UserManager, InteractionCallbackResponse, + PrimaryEntryPointCommandInteraction, GuildScheduledEventRecurrenceRuleOptions, ThreadOnlyChannel, SectionComponentData, @@ -229,6 +230,7 @@ import { SeparatorComponentData, FileComponentData, ContainerComponentData, + InteractionResponse, } from '.'; import { expectAssignable, @@ -1889,6 +1891,11 @@ client.on('interactionCreate', async interaction => { expectType>(interaction.update({ content: 'a', withResponse: true })); expectType>(interaction.deferUpdate({ withResponse: true })); expectType>>(interaction.followUp({ content: 'a' })); + expectType>(interaction.launchActivity({ withResponse: true })); + expectType>(interaction.launchActivity({ withResponse: false })); + expectType>( + interaction.launchActivity({ withResponse: booleanValue }), + ); } else if (interaction.inRawGuild()) { expectAssignable(interaction); expectType(interaction.component); @@ -1905,6 +1912,11 @@ client.on('interactionCreate', async interaction => { expectType>(interaction.update({ content: 'a', withResponse: true })); expectType>(interaction.deferUpdate({ withResponse: true })); expectType>>(interaction.followUp({ content: 'a' })); + expectType>(interaction.launchActivity({ withResponse: true })); + expectType>(interaction.launchActivity({ withResponse: false })); + expectType>( + interaction.launchActivity({ withResponse: booleanValue }), + ); } else if (interaction.inGuild()) { expectAssignable(interaction); expectType(interaction.component); @@ -1921,6 +1933,11 @@ client.on('interactionCreate', async interaction => { expectType>(interaction.update({ content: 'a', withResponse: true })); expectType>(interaction.deferUpdate({ withResponse: true })); expectType>(interaction.followUp({ content: 'a' })); + expectType>(interaction.launchActivity({ withResponse: true })); + expectType>(interaction.launchActivity({ withResponse: false })); + expectType>( + interaction.launchActivity({ withResponse: booleanValue }), + ); } } @@ -1960,6 +1977,11 @@ client.on('interactionCreate', async interaction => { expectType>>(interaction.editReply({ content: 'a' })); expectType>>(interaction.fetchReply()); expectType>>(interaction.followUp({ content: 'a' })); + expectType>(interaction.launchActivity({ withResponse: true })); + expectType>(interaction.launchActivity({ withResponse: false })); + expectType>( + interaction.launchActivity({ withResponse: booleanValue }), + ); } else if (interaction.inRawGuild()) { expectAssignable(interaction); expectType(interaction.guild); @@ -1970,6 +1992,11 @@ client.on('interactionCreate', async interaction => { expectType>>(interaction.editReply({ content: 'a' })); expectType>>(interaction.fetchReply()); expectType>>(interaction.followUp({ content: 'a' })); + expectType>(interaction.launchActivity({ withResponse: true })); + expectType>(interaction.launchActivity({ withResponse: false })); + expectType>( + interaction.launchActivity({ withResponse: booleanValue }), + ); } else if (interaction.inGuild()) { expectAssignable(interaction); expectType(interaction.guild); @@ -1980,6 +2007,11 @@ client.on('interactionCreate', async interaction => { expectType>(interaction.editReply({ content: 'a' })); expectType>(interaction.fetchReply()); expectType>(interaction.followUp({ content: 'a' })); + expectType>(interaction.launchActivity({ withResponse: true })); + expectType>(interaction.launchActivity({ withResponse: false })); + expectType>( + interaction.launchActivity({ withResponse: booleanValue }), + ); } } @@ -2164,6 +2196,57 @@ client.on('interactionCreate', async interaction => { interaction.options.getMessage('name'); } + if ( + interaction.type === InteractionType.ApplicationCommand && + interaction.commandType === ApplicationCommandType.PrimaryEntryPoint + ) { + expectType(interaction); + + // @ts-expect-error No options on primary entry point commands + interaction.options; + if (interaction.inCachedGuild()) { + expectAssignable(interaction); + expectAssignable(interaction.guild); + expectAssignable>(interaction); + expectType>(interaction.reply({ content: 'a', withResponse: true })); + expectType>(interaction.deferReply({ withResponse: true })); + expectType>>(interaction.deferReply()); + expectType>>(interaction.reply({ content: 'a', withResponse: false })); + expectType>>(interaction.deferReply({ withResponse: false })); + expectType>>(interaction.editReply({ content: 'a' })); + expectType>>(interaction.fetchReply()); + expectType>>(interaction.followUp({ content: 'a' })); + expectType>(interaction.launchActivity({ withResponse: true })); + expectType>(interaction.launchActivity({ withResponse: false })); + } else if (interaction.inRawGuild()) { + expectAssignable(interaction); + expectType(interaction.guild); + expectType>(interaction.reply({ content: 'a', withResponse: true })); + expectType>(interaction.deferReply({ withResponse: true })); + expectType>>(interaction.deferReply()); + expectType>>(interaction.reply({ content: 'a', withResponse: false })); + expectType>>(interaction.deferReply({ withResponse: false })); + expectType>>(interaction.editReply({ content: 'a' })); + expectType>>(interaction.fetchReply()); + expectType>>(interaction.followUp({ content: 'a' })); + expectType>(interaction.launchActivity({ withResponse: true })); + expectType>(interaction.launchActivity({ withResponse: false })); + } else if (interaction.inGuild()) { + expectAssignable(interaction); + expectType(interaction.guild); + expectType>(interaction.reply({ content: 'a', withResponse: true })); + expectType>(interaction.deferReply({ withResponse: true })); + expectType>(interaction.deferReply()); + expectType>(interaction.reply({ content: 'a', withResponse: false })); + expectType>(interaction.deferReply({ withResponse: false })); + expectType>(interaction.editReply({ content: 'a' })); + expectType>(interaction.fetchReply()); + expectType>(interaction.followUp({ content: 'a' })); + expectType>(interaction.launchActivity({ withResponse: true })); + expectType>(interaction.launchActivity({ withResponse: false })); + } + } + if (interaction.isRepliable()) { expectAssignable(interaction); interaction.reply('test'); @@ -2192,6 +2275,7 @@ client.on('interactionCreate', async interaction => { expectType>>(interaction.deferUpdate({ fetchReply: true })); expectType>(interaction.deferUpdate({ withResponse: true })); expectType>>(interaction.followUp({ content: 'a' })); + expectType>(interaction.launchActivity({ withResponse: true })); } else if (interaction.inRawGuild()) { expectAssignable(interaction); expectType(interaction.guild); @@ -2204,6 +2288,7 @@ client.on('interactionCreate', async interaction => { expectType>>(interaction.deferUpdate({ fetchReply: true })); expectType>(interaction.deferUpdate({ withResponse: true })); expectType>>(interaction.followUp({ content: 'a' })); + expectType>(interaction.launchActivity({ withResponse: true })); } else if (interaction.inGuild()) { expectAssignable(interaction); expectType(interaction.guild); @@ -2216,6 +2301,7 @@ client.on('interactionCreate', async interaction => { expectType>(interaction.deferUpdate({ fetchReply: true })); expectType>(interaction.deferUpdate({ withResponse: true })); expectType>(interaction.followUp({ content: 'a' })); + expectType>(interaction.launchActivity({ withResponse: true })); } }