Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Backport Interaction#isRepliable #7563

Merged
merged 6 commits into from Apr 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/structures/Interaction.js
Expand Up @@ -226,6 +226,16 @@ class Interaction extends Base {
MessageComponentTypes[this.componentType] === MessageComponentTypes.SELECT_MENU
);
}

/**
* Indicates whether this interaction can be replied to.
* @returns {boolean}
*/
isRepliable() {
return ![InteractionTypes.PING, InteractionTypes.APPLICATION_COMMAND_AUTOCOMPLETE].includes(
InteractionTypes[this.type],
);
}
}

module.exports = Interaction;
16 changes: 16 additions & 0 deletions typings/index.d.ts
Expand Up @@ -320,6 +320,21 @@ export type GuildCacheMessage<Cached extends CacheType> = CacheTypeReducer<
Message | APIMessage
>;

export interface InteractionResponseFields<Cached extends CacheType = CacheType> {
deferred: boolean;
ephemeral: boolean | null;
replied: boolean;
webhook: InteractionWebhook;
reply(options: InteractionReplyOptions & { fetchReply: true }): Promise<GuildCacheMessage<Cached>>;
reply(options: string | MessagePayload | InteractionReplyOptions): Promise<void>;
deleteReply(): Promise<void>;
editReply(options: string | MessagePayload | WebhookEditMessageOptions): Promise<GuildCacheMessage<Cached>>;
deferReply(options: InteractionDeferReplyOptions & { fetchReply: true }): Promise<GuildCacheMessage<Cached>>;
deferReply(options?: InteractionDeferReplyOptions): Promise<void>;
fetchReply(): Promise<GuildCacheMessage<Cached>>;
followUp(options: string | MessagePayload | InteractionReplyOptions): Promise<GuildCacheMessage<Cached>>;
}

export abstract class BaseCommandInteraction<Cached extends CacheType = CacheType> extends Interaction<Cached> {
public readonly command: ApplicationCommand | ApplicationCommand<{ guild: GuildResolvable }> | null;
public options: Omit<
Expand Down Expand Up @@ -1352,6 +1367,7 @@ export class Interaction<Cached extends CacheType = CacheType> extends Base {
public isMessageContextMenu(): this is MessageContextMenuInteraction<Cached>;
public isMessageComponent(): this is MessageComponentInteraction<Cached>;
public isSelectMenu(): this is SelectMenuInteraction<Cached>;
public isRepliable(): this is this & InteractionResponseFields<Cached>;
}

export class InteractionCollector<T extends Interaction> extends Collector<Snowflake, T> {
Expand Down
11 changes: 11 additions & 0 deletions typings/index.test-d.ts
Expand Up @@ -93,6 +93,7 @@ import {
MessageActionRowComponent,
MessageSelectMenu,
PartialDMChannel,
InteractionResponseFields,
} from '.';
import type { ApplicationCommandOptionTypes } from './enums';
import { expectAssignable, expectDeprecated, expectNotAssignable, expectNotType, expectType } from 'tsd';
Expand Down Expand Up @@ -1145,6 +1146,16 @@ client.on('interactionCreate', async interaction => {
expectType<string | null>(interaction.options.getSubcommandGroup(booleanValue));
expectType<string | null>(interaction.options.getSubcommandGroup(false));
}

if (interaction.isRepliable()) {
expectAssignable<InteractionResponseFields>(interaction);
interaction.reply('test');
}

if (interaction.isCommand() && interaction.isRepliable()) {
expectAssignable<CommandInteraction>(interaction);
expectAssignable<InteractionResponseFields>(interaction);
}
});

declare const shard: Shard;
Expand Down