feat: backport entrypoint command (#10908)

This commit is contained in:
Qjuh
2025-05-27 21:50:26 +02:00
committed by GitHub
parent f2f757ce52
commit c0eae344c2
13 changed files with 220 additions and 21 deletions

View File

@@ -9,6 +9,7 @@ const ChatInputCommandInteraction = require('../../structures/ChatInputCommandIn
const MentionableSelectMenuInteraction = require('../../structures/MentionableSelectMenuInteraction'); const MentionableSelectMenuInteraction = require('../../structures/MentionableSelectMenuInteraction');
const MessageContextMenuCommandInteraction = require('../../structures/MessageContextMenuCommandInteraction'); const MessageContextMenuCommandInteraction = require('../../structures/MessageContextMenuCommandInteraction');
const ModalSubmitInteraction = require('../../structures/ModalSubmitInteraction'); const ModalSubmitInteraction = require('../../structures/ModalSubmitInteraction');
const PrimaryEntryPointCommandInteraction = require('../../structures/PrimaryEntryPointCommandInteraction');
const RoleSelectMenuInteraction = require('../../structures/RoleSelectMenuInteraction'); const RoleSelectMenuInteraction = require('../../structures/RoleSelectMenuInteraction');
const StringSelectMenuInteraction = require('../../structures/StringSelectMenuInteraction'); const StringSelectMenuInteraction = require('../../structures/StringSelectMenuInteraction');
const UserContextMenuCommandInteraction = require('../../structures/UserContextMenuCommandInteraction'); const UserContextMenuCommandInteraction = require('../../structures/UserContextMenuCommandInteraction');
@@ -38,6 +39,9 @@ class InteractionCreateAction extends Action {
if (channel && !channel.isTextBased()) return; if (channel && !channel.isTextBased()) return;
InteractionClass = MessageContextMenuCommandInteraction; InteractionClass = MessageContextMenuCommandInteraction;
break; break;
case ApplicationCommandType.PrimaryEntryPoint:
InteractionClass = PrimaryEntryPointCommandInteraction;
break;
default: default:
client.emit( client.emit(
Events.Debug, Events.Debug,

View File

@@ -180,6 +180,7 @@ exports.PartialGroupDMChannel = require('./structures/PartialGroupDMChannel');
exports.PermissionOverwrites = require('./structures/PermissionOverwrites'); exports.PermissionOverwrites = require('./structures/PermissionOverwrites');
exports.Poll = require('./structures/Poll').Poll; exports.Poll = require('./structures/Poll').Poll;
exports.PollAnswer = require('./structures/PollAnswer').PollAnswer; exports.PollAnswer = require('./structures/PollAnswer').PollAnswer;
exports.PrimaryEntryPointCommandInteraction = require('./structures/PrimaryEntryPointCommandInteraction');
exports.Presence = require('./structures/Presence').Presence; exports.Presence = require('./structures/Presence').Presence;
exports.ReactionCollector = require('./structures/ReactionCollector'); exports.ReactionCollector = require('./structures/ReactionCollector');
exports.ReactionEmoji = require('./structures/ReactionEmoji'); exports.ReactionEmoji = require('./structures/ReactionEmoji');

View File

@@ -261,6 +261,7 @@ class ApplicationCommandManager extends CachedManager {
dm_permission: command.dmPermission ?? command.dm_permission, dm_permission: command.dmPermission ?? command.dm_permission,
integration_types: command.integrationTypes ?? command.integration_types, integration_types: command.integrationTypes ?? command.integration_types,
contexts: command.contexts, contexts: command.contexts,
handler: command.handler,
}; };
} }
} }

View File

@@ -174,6 +174,18 @@ class ApplicationCommand extends Base {
this.contexts ??= null; this.contexts ??= null;
} }
if ('handler' in data) {
/**
* Determines whether the interaction is handled by the app's interactions handler or by Discord.
* <info>Only available for {@link ApplicationCommandType.PrimaryEntryPoint} commands on
* applications with the {@link ApplicationFlags.Embedded} flag (i.e, those that have an Activity)</info>
* @type {?EntryPointCommandHandlerType}
*/
this.handler = data.handler;
} else {
this.handler ??= null;
}
if ('version' in data) { if ('version' in data) {
/** /**
* Autoincrementing version identifier updated during substantial record changes * 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 * @property {string} name The name of the command, must be in all lowercase if type is
* {@link ApplicationCommandType.ChatInput} * {@link ApplicationCommandType.ChatInput}
* @property {Object<Locale, string>} [nameLocalizations] The localizations for the command name * @property {Object<Locale, string>} [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 {boolean} [nsfw] Whether the command is age-restricted
* @property {Object<Locale, string>} [descriptionLocalizations] The localizations for the command description, * @property {Object<Locale, string>} [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 {ApplicationCommandType} [type=ApplicationCommandType.ChatInput] The type of the command
* @property {ApplicationCommandOptionData[]} [options] Options for the command * @property {ApplicationCommandOptionData[]} [options] Options for the command
* @property {?PermissionResolvable} [defaultMemberPermissions] The bitfield used to determine the default permissions * @property {?PermissionResolvable} [defaultMemberPermissions] The bitfield used to determine the default permissions
* a member needs in order to run the command * a member needs in order to run the command
* @property {boolean} [dmPermission] Whether the command is enabled in DMs * @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 ?? {}, this.descriptionLocalizations ?? {},
) || ) ||
!isEqual(command.integrationTypes ?? command.integration_types ?? [], this.integrationTypes ?? []) || !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; return false;
} }

View File

@@ -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} * Indicates whether this interaction is a {@link MessageComponentInteraction}
* @returns {boolean} * @returns {boolean}

View File

@@ -152,6 +152,7 @@ class CommandInteraction extends BaseInteraction {
editReply() {} editReply() {}
deleteReply() {} deleteReply() {}
followUp() {} followUp() {}
launchActivity() {}
showModal() {} showModal() {}
sendPremiumRequired() {} sendPremiumRequired() {}
awaitModalSubmit() {} awaitModalSubmit() {}

View File

@@ -97,6 +97,7 @@ class MessageComponentInteraction extends BaseInteraction {
followUp() {} followUp() {}
deferUpdate() {} deferUpdate() {}
update() {} update() {}
launchActivity() {}
showModal() {} showModal() {}
sendPremiumRequired() {} sendPremiumRequired() {}
awaitModalSubmit() {} awaitModalSubmit() {}

View File

@@ -119,6 +119,7 @@ class ModalSubmitInteraction extends BaseInteraction {
deferUpdate() {} deferUpdate() {}
update() {} update() {}
sendPremiumRequired() {} sendPremiumRequired() {}
launchActivity() {}
} }
InteractionResponses.applyToClass(ModalSubmitInteraction, 'showModal'); InteractionResponses.applyToClass(ModalSubmitInteraction, 'showModal');

View File

@@ -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;

View File

@@ -69,6 +69,12 @@ class InteractionResponses {
* <warn>This option is deprecated. Use `withResponse` or fetch the response instead.</warn> * <warn>This option is deprecated. Use `withResponse` or fetch the response instead.</warn>
*/ */
/**
* 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} * Options for showing a modal in response to a {@link BaseInteraction}
* @typedef {Object} ShowModalOptions * @typedef {Object} ShowModalOptions
@@ -370,6 +376,25 @@ class InteractionResponses {
: new InteractionResponse(this, this.message.interactionMetadata?.id); : new InteractionResponse(this, this.message.interactionMetadata?.id);
} }
/**
* Launches this application's activity, if enabled
* @param {LaunchActivityOptions} [options={}] Options for launching the activity
* @returns {Promise<InteractionCallbackResponse|undefined>}
*/
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 * Shows a modal component
* @param {ModalBuilder|ModalComponentData|APIModalInteractionResponseCallbackData} modal The modal to show * @param {ModalBuilder|ModalComponentData|APIModalInteractionResponseCallbackData} modal The modal to show
@@ -450,6 +475,7 @@ class InteractionResponses {
'followUp', 'followUp',
'deferUpdate', 'deferUpdate',
'update', 'update',
'launchActivity',
'showModal', 'showModal',
'sendPremiumRequired', 'sendPremiumRequired',
'awaitModalSubmit', 'awaitModalSubmit',

View File

@@ -370,6 +370,11 @@
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/EntitlementType} * @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 * @external ForumLayoutType
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/ForumLayoutType} * @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/ForumLayoutType}

View File

@@ -213,6 +213,7 @@ import {
SeparatorSpacingSize, SeparatorSpacingSize,
APIFileComponent, APIFileComponent,
APIMessageTopLevelComponent, APIMessageTopLevelComponent,
EntryPointCommandHandlerType,
} from 'discord-api-types/v10'; } from 'discord-api-types/v10';
import { ChildProcess } from 'node:child_process'; import { ChildProcess } from 'node:child_process';
import { EventEmitter } from 'node:events'; import { EventEmitter } from 'node:events';
@@ -480,6 +481,7 @@ export class ApplicationCommand<PermissionsFetchType = {}> extends Base {
public get manager(): ApplicationCommandManager; public get manager(): ApplicationCommandManager;
public id: Snowflake; public id: Snowflake;
public integrationTypes: ApplicationIntegrationType[] | null; public integrationTypes: ApplicationIntegrationType[] | null;
public handler: EntryPointCommandHandlerType | null;
public name: string; public name: string;
public nameLocalizations: LocalizationMap | null; public nameLocalizations: LocalizationMap | null;
public nameLocalized: string | null; public nameLocalized: string | null;
@@ -583,23 +585,6 @@ export type BooleanCache<Cached extends CacheType> = Cached extends 'cached' ? t
export abstract class CommandInteraction<Cached extends CacheType = CacheType> extends BaseInteraction<Cached> { export abstract class CommandInteraction<Cached extends CacheType = CacheType> extends BaseInteraction<Cached> {
public type: InteractionType.ApplicationCommand; public type: InteractionType.ApplicationCommand;
public get command(): ApplicationCommand | ApplicationCommand<{ guild: GuildResolvable }> | null; public get command(): ApplicationCommand | ApplicationCommand<{ guild: GuildResolvable }> | null;
public options: Omit<
CommandInteractionOptionResolver<Cached>,
| 'getMessage'
| 'getFocused'
| 'getMentionable'
| 'getRole'
| 'getUser'
| 'getMember'
| 'getAttachment'
| 'getNumber'
| 'getInteger'
| 'getString'
| 'getChannel'
| 'getBoolean'
| 'getSubcommandGroup'
| 'getSubcommand'
>;
public channelId: Snowflake; public channelId: Snowflake;
public commandId: Snowflake; public commandId: Snowflake;
public commandName: string; public commandName: string;
@@ -632,6 +617,9 @@ export abstract class CommandInteraction<Cached extends CacheType = CacheType> e
public reply( public reply(
options: string | MessagePayload | InteractionReplyOptions, options: string | MessagePayload | InteractionReplyOptions,
): Promise<InteractionResponse<BooleanCache<Cached>>>; ): Promise<InteractionResponse<BooleanCache<Cached>>>;
public launchActivity(options: LaunchActivityOptions & { withResponse: true }): Promise<InteractionCallbackResponse>;
public launchActivity(options?: LaunchActivityOptions & { withResponse?: false }): Promise<undefined>;
public launchActivity(options?: LaunchActivityOptions): Promise<InteractionCallbackResponse | undefined>;
public showModal( public showModal(
modal: modal:
| JSONEncodable<APIModalInteractionResponseCallbackData> | JSONEncodable<APIModalInteractionResponseCallbackData>
@@ -1439,6 +1427,23 @@ export class CommandInteractionOptionResolver<Cached extends CacheType = CacheTy
} }
export class ContextMenuCommandInteraction<Cached extends CacheType = CacheType> extends CommandInteraction<Cached> { export class ContextMenuCommandInteraction<Cached extends CacheType = CacheType> extends CommandInteraction<Cached> {
public options: Omit<
CommandInteractionOptionResolver<Cached>,
| 'getMessage'
| 'getFocused'
| 'getMentionable'
| 'getRole'
| 'getUser'
| 'getMember'
| 'getAttachment'
| 'getNumber'
| 'getInteger'
| 'getString'
| 'getChannel'
| 'getBoolean'
| 'getSubcommandGroup'
| 'getSubcommand'
>;
public commandType: ApplicationCommandType.Message | ApplicationCommandType.User; public commandType: ApplicationCommandType.Message | ApplicationCommandType.User;
public targetId: Snowflake; public targetId: Snowflake;
public inGuild(): this is ContextMenuCommandInteraction<'raw' | 'cached'>; public inGuild(): this is ContextMenuCommandInteraction<'raw' | 'cached'>;
@@ -1447,6 +1452,15 @@ export class ContextMenuCommandInteraction<Cached extends CacheType = CacheType>
private resolveContextMenuOptions(data: APIApplicationCommandInteractionData): CommandInteractionOption<Cached>[]; private resolveContextMenuOptions(data: APIApplicationCommandInteractionData): CommandInteractionOption<Cached>[];
} }
export class PrimaryEntryPointCommandInteraction<
Cached extends CacheType = CacheType,
> extends CommandInteraction<Cached> {
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 // tslint:disable-next-line no-empty-interface
export interface DMChannel export interface DMChannel
extends Omit< extends Omit<
@@ -2062,6 +2076,7 @@ export type Interaction<Cached extends CacheType = CacheType> =
| ChatInputCommandInteraction<Cached> | ChatInputCommandInteraction<Cached>
| MessageContextMenuCommandInteraction<Cached> | MessageContextMenuCommandInteraction<Cached>
| UserContextMenuCommandInteraction<Cached> | UserContextMenuCommandInteraction<Cached>
| PrimaryEntryPointCommandInteraction<Cached>
| AnySelectMenuInteraction<Cached> | AnySelectMenuInteraction<Cached>
| ButtonInteraction<Cached> | ButtonInteraction<Cached>
| AutocompleteInteraction<Cached> | AutocompleteInteraction<Cached>
@@ -2111,6 +2126,7 @@ export class BaseInteraction<Cached extends CacheType = CacheType> extends Base
public isChatInputCommand(): this is ChatInputCommandInteraction<Cached>; public isChatInputCommand(): this is ChatInputCommandInteraction<Cached>;
public isCommand(): this is CommandInteraction<Cached>; public isCommand(): this is CommandInteraction<Cached>;
public isContextMenuCommand(): this is ContextMenuCommandInteraction<Cached>; public isContextMenuCommand(): this is ContextMenuCommandInteraction<Cached>;
public isPrimaryEntryPointCommand(): this is PrimaryEntryPointCommandInteraction<Cached>;
public isMessageComponent(): this is MessageComponentInteraction<Cached>; public isMessageComponent(): this is MessageComponentInteraction<Cached>;
public isMessageContextMenuCommand(): this is MessageContextMenuCommandInteraction<Cached>; public isMessageContextMenuCommand(): this is MessageContextMenuCommandInteraction<Cached>;
public isModalSubmit(): this is ModalSubmitInteraction<Cached>; public isModalSubmit(): this is ModalSubmitInteraction<Cached>;
@@ -2538,6 +2554,9 @@ export class MessageComponentInteraction<Cached extends CacheType = CacheType> e
public update( public update(
options: string | MessagePayload | InteractionUpdateOptions, options: string | MessagePayload | InteractionUpdateOptions,
): Promise<InteractionResponse<BooleanCache<Cached>>>; ): Promise<InteractionResponse<BooleanCache<Cached>>>;
public launchActivity(options: LaunchActivityOptions & { withResponse: true }): Promise<InteractionCallbackResponse>;
public launchActivity(options?: LaunchActivityOptions & { withResponse?: false }): Promise<undefined>;
public launchActivity(options?: LaunchActivityOptions): Promise<InteractionCallbackResponse | undefined>;
public showModal( public showModal(
modal: modal:
| JSONEncodable<APIModalInteractionResponseCallbackData> | JSONEncodable<APIModalInteractionResponseCallbackData>
@@ -2784,6 +2803,9 @@ export class ModalSubmitInteraction<Cached extends CacheType = CacheType> extend
public deferUpdate(options?: InteractionDeferUpdateOptions): Promise<InteractionResponse<BooleanCache<Cached>>>; public deferUpdate(options?: InteractionDeferUpdateOptions): Promise<InteractionResponse<BooleanCache<Cached>>>;
/** @deprecated Sending a premium-style button is the new Discord behaviour. */ /** @deprecated Sending a premium-style button is the new Discord behaviour. */
public sendPremiumRequired(): Promise<void>; public sendPremiumRequired(): Promise<void>;
public launchActivity(options: LaunchActivityOptions & { withResponse: true }): Promise<InteractionCallbackResponse>;
public launchActivity(options?: LaunchActivityOptions & { withResponse?: false }): Promise<undefined>;
public launchActivity(options?: LaunchActivityOptions): Promise<InteractionCallbackResponse | undefined>;
public inGuild(): this is ModalSubmitInteraction<'raw' | 'cached'>; public inGuild(): this is ModalSubmitInteraction<'raw' | 'cached'>;
public inCachedGuild(): this is ModalSubmitInteraction<'cached'>; public inCachedGuild(): this is ModalSubmitInteraction<'cached'>;
public inRawGuild(): this is ModalSubmitInteraction<'raw'>; public inRawGuild(): this is ModalSubmitInteraction<'raw'>;
@@ -5271,10 +5293,18 @@ export interface ChatInputApplicationCommandData extends BaseApplicationCommandD
options?: readonly ApplicationCommandOptionData[]; options?: readonly ApplicationCommandOptionData[];
} }
export interface PrimaryEntryPointCommandData extends BaseApplicationCommandData {
description?: string;
descriptionLocalizations?: LocalizationMap;
type: ApplicationCommandType.PrimaryEntryPoint;
handler?: EntryPointCommandHandlerType;
}
export type ApplicationCommandData = export type ApplicationCommandData =
| UserApplicationCommandData | UserApplicationCommandData
| MessageApplicationCommandData | MessageApplicationCommandData
| ChatInputApplicationCommandData; | ChatInputApplicationCommandData
| PrimaryEntryPointCommandData;
export interface ApplicationCommandChannelOptionData extends BaseApplicationCommandOptionsData { export interface ApplicationCommandChannelOptionData extends BaseApplicationCommandOptionsData {
type: CommandOptionChannelResolvableType; type: CommandOptionChannelResolvableType;
@@ -7376,6 +7406,10 @@ export interface ShowModalOptions {
withResponse?: boolean; withResponse?: boolean;
} }
export interface LaunchActivityOptions {
withResponse?: boolean;
}
export { Snowflake }; export { Snowflake };
export type StageInstanceResolvable = StageInstance | Snowflake; export type StageInstanceResolvable = StageInstance | Snowflake;

View File

@@ -218,6 +218,7 @@ import {
PollData, PollData,
UserManager, UserManager,
InteractionCallbackResponse, InteractionCallbackResponse,
PrimaryEntryPointCommandInteraction,
GuildScheduledEventRecurrenceRuleOptions, GuildScheduledEventRecurrenceRuleOptions,
ThreadOnlyChannel, ThreadOnlyChannel,
SectionComponentData, SectionComponentData,
@@ -229,6 +230,7 @@ import {
SeparatorComponentData, SeparatorComponentData,
FileComponentData, FileComponentData,
ContainerComponentData, ContainerComponentData,
InteractionResponse,
} from '.'; } from '.';
import { import {
expectAssignable, expectAssignable,
@@ -1889,6 +1891,11 @@ client.on('interactionCreate', async interaction => {
expectType<Promise<InteractionCallbackResponse>>(interaction.update({ content: 'a', withResponse: true })); expectType<Promise<InteractionCallbackResponse>>(interaction.update({ content: 'a', withResponse: true }));
expectType<Promise<InteractionCallbackResponse>>(interaction.deferUpdate({ withResponse: true })); expectType<Promise<InteractionCallbackResponse>>(interaction.deferUpdate({ withResponse: true }));
expectType<Promise<Message<true>>>(interaction.followUp({ content: 'a' })); expectType<Promise<Message<true>>>(interaction.followUp({ content: 'a' }));
expectType<Promise<InteractionCallbackResponse>>(interaction.launchActivity({ withResponse: true }));
expectType<Promise<undefined>>(interaction.launchActivity({ withResponse: false }));
expectType<Promise<InteractionCallbackResponse | undefined>>(
interaction.launchActivity({ withResponse: booleanValue }),
);
} else if (interaction.inRawGuild()) { } else if (interaction.inRawGuild()) {
expectAssignable<MessageComponentInteraction>(interaction); expectAssignable<MessageComponentInteraction>(interaction);
expectType<APIButtonComponent | APISelectMenuComponent>(interaction.component); expectType<APIButtonComponent | APISelectMenuComponent>(interaction.component);
@@ -1905,6 +1912,11 @@ client.on('interactionCreate', async interaction => {
expectType<Promise<InteractionCallbackResponse>>(interaction.update({ content: 'a', withResponse: true })); expectType<Promise<InteractionCallbackResponse>>(interaction.update({ content: 'a', withResponse: true }));
expectType<Promise<InteractionCallbackResponse>>(interaction.deferUpdate({ withResponse: true })); expectType<Promise<InteractionCallbackResponse>>(interaction.deferUpdate({ withResponse: true }));
expectType<Promise<Message<false>>>(interaction.followUp({ content: 'a' })); expectType<Promise<Message<false>>>(interaction.followUp({ content: 'a' }));
expectType<Promise<InteractionCallbackResponse>>(interaction.launchActivity({ withResponse: true }));
expectType<Promise<undefined>>(interaction.launchActivity({ withResponse: false }));
expectType<Promise<InteractionCallbackResponse | undefined>>(
interaction.launchActivity({ withResponse: booleanValue }),
);
} else if (interaction.inGuild()) { } else if (interaction.inGuild()) {
expectAssignable<MessageComponentInteraction>(interaction); expectAssignable<MessageComponentInteraction>(interaction);
expectType<MessageActionRowComponent | APIButtonComponent | APISelectMenuComponent>(interaction.component); expectType<MessageActionRowComponent | APIButtonComponent | APISelectMenuComponent>(interaction.component);
@@ -1921,6 +1933,11 @@ client.on('interactionCreate', async interaction => {
expectType<Promise<InteractionCallbackResponse>>(interaction.update({ content: 'a', withResponse: true })); expectType<Promise<InteractionCallbackResponse>>(interaction.update({ content: 'a', withResponse: true }));
expectType<Promise<InteractionCallbackResponse>>(interaction.deferUpdate({ withResponse: true })); expectType<Promise<InteractionCallbackResponse>>(interaction.deferUpdate({ withResponse: true }));
expectType<Promise<Message>>(interaction.followUp({ content: 'a' })); expectType<Promise<Message>>(interaction.followUp({ content: 'a' }));
expectType<Promise<InteractionCallbackResponse>>(interaction.launchActivity({ withResponse: true }));
expectType<Promise<undefined>>(interaction.launchActivity({ withResponse: false }));
expectType<Promise<InteractionCallbackResponse | undefined>>(
interaction.launchActivity({ withResponse: booleanValue }),
);
} }
} }
@@ -1960,6 +1977,11 @@ client.on('interactionCreate', async interaction => {
expectType<Promise<Message<true>>>(interaction.editReply({ content: 'a' })); expectType<Promise<Message<true>>>(interaction.editReply({ content: 'a' }));
expectType<Promise<Message<true>>>(interaction.fetchReply()); expectType<Promise<Message<true>>>(interaction.fetchReply());
expectType<Promise<Message<true>>>(interaction.followUp({ content: 'a' })); expectType<Promise<Message<true>>>(interaction.followUp({ content: 'a' }));
expectType<Promise<InteractionCallbackResponse>>(interaction.launchActivity({ withResponse: true }));
expectType<Promise<undefined>>(interaction.launchActivity({ withResponse: false }));
expectType<Promise<InteractionCallbackResponse | undefined>>(
interaction.launchActivity({ withResponse: booleanValue }),
);
} else if (interaction.inRawGuild()) { } else if (interaction.inRawGuild()) {
expectAssignable<ContextMenuCommandInteraction>(interaction); expectAssignable<ContextMenuCommandInteraction>(interaction);
expectType<null>(interaction.guild); expectType<null>(interaction.guild);
@@ -1970,6 +1992,11 @@ client.on('interactionCreate', async interaction => {
expectType<Promise<Message<false>>>(interaction.editReply({ content: 'a' })); expectType<Promise<Message<false>>>(interaction.editReply({ content: 'a' }));
expectType<Promise<Message<false>>>(interaction.fetchReply()); expectType<Promise<Message<false>>>(interaction.fetchReply());
expectType<Promise<Message<false>>>(interaction.followUp({ content: 'a' })); expectType<Promise<Message<false>>>(interaction.followUp({ content: 'a' }));
expectType<Promise<InteractionCallbackResponse>>(interaction.launchActivity({ withResponse: true }));
expectType<Promise<undefined>>(interaction.launchActivity({ withResponse: false }));
expectType<Promise<InteractionCallbackResponse | undefined>>(
interaction.launchActivity({ withResponse: booleanValue }),
);
} else if (interaction.inGuild()) { } else if (interaction.inGuild()) {
expectAssignable<ContextMenuCommandInteraction>(interaction); expectAssignable<ContextMenuCommandInteraction>(interaction);
expectType<Guild | null>(interaction.guild); expectType<Guild | null>(interaction.guild);
@@ -1980,6 +2007,11 @@ client.on('interactionCreate', async interaction => {
expectType<Promise<Message>>(interaction.editReply({ content: 'a' })); expectType<Promise<Message>>(interaction.editReply({ content: 'a' }));
expectType<Promise<Message>>(interaction.fetchReply()); expectType<Promise<Message>>(interaction.fetchReply());
expectType<Promise<Message>>(interaction.followUp({ content: 'a' })); expectType<Promise<Message>>(interaction.followUp({ content: 'a' }));
expectType<Promise<InteractionCallbackResponse>>(interaction.launchActivity({ withResponse: true }));
expectType<Promise<undefined>>(interaction.launchActivity({ withResponse: false }));
expectType<Promise<InteractionCallbackResponse | undefined>>(
interaction.launchActivity({ withResponse: booleanValue }),
);
} }
} }
@@ -2164,6 +2196,57 @@ client.on('interactionCreate', async interaction => {
interaction.options.getMessage('name'); interaction.options.getMessage('name');
} }
if (
interaction.type === InteractionType.ApplicationCommand &&
interaction.commandType === ApplicationCommandType.PrimaryEntryPoint
) {
expectType<PrimaryEntryPointCommandInteraction>(interaction);
// @ts-expect-error No options on primary entry point commands
interaction.options;
if (interaction.inCachedGuild()) {
expectAssignable<PrimaryEntryPointCommandInteraction>(interaction);
expectAssignable<Guild>(interaction.guild);
expectAssignable<CommandInteraction<'cached'>>(interaction);
expectType<Promise<InteractionCallbackResponse>>(interaction.reply({ content: 'a', withResponse: true }));
expectType<Promise<InteractionCallbackResponse>>(interaction.deferReply({ withResponse: true }));
expectType<Promise<InteractionResponse<true>>>(interaction.deferReply());
expectType<Promise<InteractionResponse<true>>>(interaction.reply({ content: 'a', withResponse: false }));
expectType<Promise<InteractionResponse<true>>>(interaction.deferReply({ withResponse: false }));
expectType<Promise<Message<true>>>(interaction.editReply({ content: 'a' }));
expectType<Promise<Message<true>>>(interaction.fetchReply());
expectType<Promise<Message<true>>>(interaction.followUp({ content: 'a' }));
expectType<Promise<InteractionCallbackResponse>>(interaction.launchActivity({ withResponse: true }));
expectType<Promise<undefined>>(interaction.launchActivity({ withResponse: false }));
} else if (interaction.inRawGuild()) {
expectAssignable<PrimaryEntryPointCommandInteraction>(interaction);
expectType<null>(interaction.guild);
expectType<Promise<InteractionCallbackResponse>>(interaction.reply({ content: 'a', withResponse: true }));
expectType<Promise<InteractionCallbackResponse>>(interaction.deferReply({ withResponse: true }));
expectType<Promise<InteractionResponse<false>>>(interaction.deferReply());
expectType<Promise<InteractionResponse<false>>>(interaction.reply({ content: 'a', withResponse: false }));
expectType<Promise<InteractionResponse<false>>>(interaction.deferReply({ withResponse: false }));
expectType<Promise<Message<false>>>(interaction.editReply({ content: 'a' }));
expectType<Promise<Message<false>>>(interaction.fetchReply());
expectType<Promise<Message<false>>>(interaction.followUp({ content: 'a' }));
expectType<Promise<InteractionCallbackResponse>>(interaction.launchActivity({ withResponse: true }));
expectType<Promise<undefined>>(interaction.launchActivity({ withResponse: false }));
} else if (interaction.inGuild()) {
expectAssignable<PrimaryEntryPointCommandInteraction>(interaction);
expectType<Guild | null>(interaction.guild);
expectType<Promise<InteractionCallbackResponse>>(interaction.reply({ content: 'a', withResponse: true }));
expectType<Promise<InteractionCallbackResponse>>(interaction.deferReply({ withResponse: true }));
expectType<Promise<InteractionResponse>>(interaction.deferReply());
expectType<Promise<InteractionResponse>>(interaction.reply({ content: 'a', withResponse: false }));
expectType<Promise<InteractionResponse>>(interaction.deferReply({ withResponse: false }));
expectType<Promise<Message>>(interaction.editReply({ content: 'a' }));
expectType<Promise<Message>>(interaction.fetchReply());
expectType<Promise<Message>>(interaction.followUp({ content: 'a' }));
expectType<Promise<InteractionCallbackResponse>>(interaction.launchActivity({ withResponse: true }));
expectType<Promise<undefined>>(interaction.launchActivity({ withResponse: false }));
}
}
if (interaction.isRepliable()) { if (interaction.isRepliable()) {
expectAssignable<RepliableInteraction>(interaction); expectAssignable<RepliableInteraction>(interaction);
interaction.reply('test'); interaction.reply('test');
@@ -2192,6 +2275,7 @@ client.on('interactionCreate', async interaction => {
expectType<Promise<Message<true>>>(interaction.deferUpdate({ fetchReply: true })); expectType<Promise<Message<true>>>(interaction.deferUpdate({ fetchReply: true }));
expectType<Promise<InteractionCallbackResponse>>(interaction.deferUpdate({ withResponse: true })); expectType<Promise<InteractionCallbackResponse>>(interaction.deferUpdate({ withResponse: true }));
expectType<Promise<Message<true>>>(interaction.followUp({ content: 'a' })); expectType<Promise<Message<true>>>(interaction.followUp({ content: 'a' }));
expectType<Promise<InteractionCallbackResponse>>(interaction.launchActivity({ withResponse: true }));
} else if (interaction.inRawGuild()) { } else if (interaction.inRawGuild()) {
expectAssignable<ModalSubmitInteraction>(interaction); expectAssignable<ModalSubmitInteraction>(interaction);
expectType<null>(interaction.guild); expectType<null>(interaction.guild);
@@ -2204,6 +2288,7 @@ client.on('interactionCreate', async interaction => {
expectType<Promise<Message<false>>>(interaction.deferUpdate({ fetchReply: true })); expectType<Promise<Message<false>>>(interaction.deferUpdate({ fetchReply: true }));
expectType<Promise<InteractionCallbackResponse>>(interaction.deferUpdate({ withResponse: true })); expectType<Promise<InteractionCallbackResponse>>(interaction.deferUpdate({ withResponse: true }));
expectType<Promise<Message<false>>>(interaction.followUp({ content: 'a' })); expectType<Promise<Message<false>>>(interaction.followUp({ content: 'a' }));
expectType<Promise<InteractionCallbackResponse>>(interaction.launchActivity({ withResponse: true }));
} else if (interaction.inGuild()) { } else if (interaction.inGuild()) {
expectAssignable<ModalSubmitInteraction>(interaction); expectAssignable<ModalSubmitInteraction>(interaction);
expectType<Guild | null>(interaction.guild); expectType<Guild | null>(interaction.guild);
@@ -2216,6 +2301,7 @@ client.on('interactionCreate', async interaction => {
expectType<Promise<Message>>(interaction.deferUpdate({ fetchReply: true })); expectType<Promise<Message>>(interaction.deferUpdate({ fetchReply: true }));
expectType<Promise<InteractionCallbackResponse>>(interaction.deferUpdate({ withResponse: true })); expectType<Promise<InteractionCallbackResponse>>(interaction.deferUpdate({ withResponse: true }));
expectType<Promise<Message>>(interaction.followUp({ content: 'a' })); expectType<Promise<Message>>(interaction.followUp({ content: 'a' }));
expectType<Promise<InteractionCallbackResponse>>(interaction.launchActivity({ withResponse: true }));
} }
} }