diff --git a/src/constants.ts b/src/constants.ts index 023f5d58..3ede07b8 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -49,7 +49,9 @@ export enum InteractionResponseType { /** Responds to an autocomplete interaction request. */ APPLICATION_COMMAND_AUTOCOMPLETE_RESULT = 8, /** Respond to an interaction with a popup modal. */ - MODAL = 9 + MODAL = 9, + /** Respond to an interaction with prompt for a premium subscription. */ + PREMIUM_REQUIRED = 10 } /** Message flags for interaction responses. */ @@ -355,6 +357,7 @@ export interface DMModalSubmitRequestData { user: CommandUser; message?: MessageData; app_permissions?: string; + entitlements: AppEntitlement[]; data: { custom_id: string; components: ComponentActionRow[]; @@ -378,6 +381,7 @@ export interface GuildModalSubmitRequestData { member: CommandMember; message?: MessageData; app_permissions?: string; + entitlements: AppEntitlement[]; data: { custom_id: string; components: ComponentActionRow[]; @@ -405,6 +409,7 @@ export interface DMInteractionRequestData { user: CommandUser; channel: CommandChannel; app_permissions?: string; + entitlements: AppEntitlement[]; data: CommandData; } @@ -425,6 +430,7 @@ export interface GuildInteractionRequestData { member: CommandMember; channel: CommandChannel; app_permissions?: string; + entitlements: AppEntitlement[]; data: CommandData; } @@ -469,6 +475,7 @@ export interface DMMessageComponentRequestData { user: CommandUser; channel: CommandChannel; app_permissions?: string; + entitlements: AppEntitlement[]; data: { custom_id: string; component_type: ComponentType; @@ -491,6 +498,7 @@ export interface GuildMessageComponentRequestData { guild_id: string; member: CommandMember; channel: CommandChannel; + entitlements: AppEntitlement[]; app_permissions?: string; data: { custom_id: string; @@ -499,6 +507,22 @@ export interface GuildMessageComponentRequestData { }; } +export interface AppEntitlement { + id: string; + sku_id: string; + user_id?: string; + guild_id?: string; + application_id: string; + type: EntitlementType; + consumed: false; + starts_at?: string; + ends_at?: string; +} + +export enum EntitlementType { + APPLICATION_SUBSCRIPTION = 8 +} + /** * Any message component interaction. * @private diff --git a/src/structures/interfaces/baseInteraction.ts b/src/structures/interfaces/baseInteraction.ts index c669ce6b..604c1793 100644 --- a/src/structures/interfaces/baseInteraction.ts +++ b/src/structures/interfaces/baseInteraction.ts @@ -2,7 +2,7 @@ import { SlashCreator } from '../../creator'; import { Member } from '../member'; import { User } from '../user'; import { Permissions } from '../permissions'; -import { AttachmentData } from '../../constants'; +import { AppEntitlement, AttachmentData } from '../../constants'; import { Collection } from '../../util/collection'; import { Channel } from '../channel'; import { Message } from '../message'; @@ -35,6 +35,8 @@ export class BaseInteractionContext { readonly invokedAt: number = Date.now(); /** The permissions the application has. */ readonly appPermissions?: Permissions; + /** The entitlements the invoking user has. */ + readonly entitlements: AppEntitlement[]; /** The resolved users of the interaction. */ readonly users = new Collection(); @@ -66,6 +68,7 @@ export class BaseInteractionContext { this.user = new User('guild_id' in data ? data.member.user : data.user, this.creator); this.channel = new Channel(data.channel); this.appPermissions = data.app_permissions ? new Permissions(BigInt(data.app_permissions)) : undefined; + this.entitlements = data.entitlements; if (data.data.resolved) { if (data.data.resolved.users) diff --git a/src/structures/interfaces/messageInteraction.ts b/src/structures/interfaces/messageInteraction.ts index c219a7f9..512a0a61 100644 --- a/src/structures/interfaces/messageInteraction.ts +++ b/src/structures/interfaces/messageInteraction.ts @@ -234,6 +234,28 @@ export class MessageInteractionContext extends BaseInteractionContext { return false; } + /** + * Creates a message that prompts the user for a premium subscription. + * @returns Whether the message passed + */ + async promptPremium(): Promise { + if (!this.initiallyResponded && !this.deferred) { + this.initiallyResponded = true; + this.deferred = true; + clearTimeout(this._timeout); + await this._respond({ + status: 200, + body: { + type: InteractionResponseType.PREMIUM_REQUIRED, + data: {} + } + }); + return true; + } + + return false; + } + /** * Registers a component callback from the initial message. * This unregisters automatically when the context expires.