feat(bot,rest,types): Add support for one-time entitlements (#3626)

* Add support for one-time entitlements

* Add comment to consumeEntitlement route

Co-authored-by: LTS20050703 <lts20050703@gmail.com>

* Check for undefined instead of falsy values in consumed for entitlements

Co-authored-by: LTS20050703 <lts20050703@gmail.com>

---------

Co-authored-by: LTS20050703 <lts20050703@gmail.com>
Co-authored-by: Awesome Stickz <awesome@stickz.dev>
This commit is contained in:
Fleny
2024-05-26 18:38:48 +00:00
committed by GitHub
co-authored by LTS20050703 Awesome Stickz
parent 541dc3b0cf
commit 47d0cea664
7 changed files with 40 additions and 2 deletions
+2
View File
@@ -520,6 +520,7 @@ export interface Transformers {
deleted: boolean deleted: boolean
startsAt: boolean startsAt: boolean
endsAt: boolean endsAt: boolean
consumed: boolean
} }
sku: { sku: {
id: boolean id: boolean
@@ -1127,6 +1128,7 @@ export function createTransformers(options: Partial<Transformers>, opts?: Create
deleted: opts?.defaultDesiredPropertiesValue ?? false, deleted: opts?.defaultDesiredPropertiesValue ?? false,
startsAt: opts?.defaultDesiredPropertiesValue ?? false, startsAt: opts?.defaultDesiredPropertiesValue ?? false,
endsAt: opts?.defaultDesiredPropertiesValue ?? false, endsAt: opts?.defaultDesiredPropertiesValue ?? false,
consumed: opts?.defaultDesiredPropertiesValue ?? false,
}, },
sku: { sku: {
id: opts?.defaultDesiredPropertiesValue ?? false, id: opts?.defaultDesiredPropertiesValue ?? false,
@@ -14,6 +14,7 @@ export function transformEntitlement(bot: Bot, payload: DiscordEntitlement): Ent
if (props.deleted && payload.deleted) entitlement.deleted = payload.deleted if (props.deleted && payload.deleted) entitlement.deleted = payload.deleted
if (props.startsAt && payload.starts_at) entitlement.startsAt = Date.parse(payload.starts_at) if (props.startsAt && payload.starts_at) entitlement.startsAt = Date.parse(payload.starts_at)
if (props.endsAt && payload.ends_at) entitlement.endsAt = Date.parse(payload.ends_at) if (props.endsAt && payload.ends_at) entitlement.endsAt = Date.parse(payload.ends_at)
if (props.consumed && payload.consumed !== undefined) entitlement.consumed = payload.consumed
return bot.transformers.customizers.entitlement(bot, payload, entitlement) return bot.transformers.customizers.entitlement(bot, payload, entitlement)
} }
@@ -37,4 +38,6 @@ export interface Entitlement {
startsAt?: number startsAt?: number
/** Date at which the entitlement is no longer valid. Not present when using test entitlements */ /** Date at which the entitlement is no longer valid. Not present when using test entitlements */
endsAt?: number endsAt?: number
/** For consumable items, whether or not the entitlement has been consumed */
consumed?: boolean
} }
+5 -1
View File
@@ -24,6 +24,7 @@ import {
type DiscordEmoji, type DiscordEmoji,
type DiscordEntitlement, type DiscordEntitlement,
type DiscordFollowedChannel, type DiscordFollowedChannel,
type DiscordGetAnswerVotesResponse,
type DiscordGetGatewayBot, type DiscordGetGatewayBot,
type DiscordGuild, type DiscordGuild,
type DiscordGuildApplicationCommandPermissions, type DiscordGuildApplicationCommandPermissions,
@@ -40,7 +41,6 @@ import {
type DiscordMemberWithUser, type DiscordMemberWithUser,
type DiscordMessage, type DiscordMessage,
type DiscordPartialGuild, type DiscordPartialGuild,
type DiscordGetAnswerVotesResponse,
type DiscordPrunedCount, type DiscordPrunedCount,
type DiscordRole, type DiscordRole,
type DiscordScheduledEvent, type DiscordScheduledEvent,
@@ -1495,6 +1495,10 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage
await rest.delete(rest.routes.monetization.entitlement(applicationId, entitlementId)) await rest.delete(rest.routes.monetization.entitlement(applicationId, entitlementId))
}, },
async consumeEntitlement(applicationId, entitlementId) {
await rest.post(rest.routes.monetization.consumeEntitlement(applicationId, entitlementId))
},
async listSkus(applicationId) { async listSkus(applicationId) {
return await rest.get<DiscordSku[]>(rest.routes.monetization.skus(applicationId)) return await rest.get<DiscordSku[]>(rest.routes.monetization.skus(applicationId))
}, },
+3
View File
@@ -617,6 +617,9 @@ export function createRoutes(): RestRoutes {
entitlement: (applicationId, entitlementId) => { entitlement: (applicationId, entitlementId) => {
return `/applications/${applicationId}/entitlements/${entitlementId}` return `/applications/${applicationId}/entitlements/${entitlementId}`
}, },
consumeEntitlement: (applicationId, entitlementId) => {
return `/applications/${applicationId}/entitlements/${entitlementId}/consume`
},
skus: (applicationId) => { skus: (applicationId) => {
return `/applications/${applicationId}/skus` return `/applications/${applicationId}/skus`
+5 -1
View File
@@ -21,6 +21,7 @@ import type {
CamelizedDiscordEmoji, CamelizedDiscordEmoji,
CamelizedDiscordEntitlement, CamelizedDiscordEntitlement,
CamelizedDiscordFollowedChannel, CamelizedDiscordFollowedChannel,
CamelizedDiscordGetAnswerVotesResponse,
CamelizedDiscordGetGatewayBot, CamelizedDiscordGetGatewayBot,
CamelizedDiscordGuild, CamelizedDiscordGuild,
CamelizedDiscordGuildApplicationCommandPermissions, CamelizedDiscordGuildApplicationCommandPermissions,
@@ -36,7 +37,6 @@ import type {
CamelizedDiscordMessage, CamelizedDiscordMessage,
CamelizedDiscordModifyGuildWelcomeScreen, CamelizedDiscordModifyGuildWelcomeScreen,
CamelizedDiscordPartialGuild, CamelizedDiscordPartialGuild,
CamelizedDiscordGetAnswerVotesResponse,
CamelizedDiscordPrunedCount, CamelizedDiscordPrunedCount,
CamelizedDiscordRole, CamelizedDiscordRole,
CamelizedDiscordScheduledEvent, CamelizedDiscordScheduledEvent,
@@ -2903,6 +2903,10 @@ export interface RestManager {
* @param entitlementId - The id of the entitlement to delete * @param entitlementId - The id of the entitlement to delete
*/ */
deleteTestEntitlement: (applicationId: BigString, entitlementId: BigString) => Promise<void> deleteTestEntitlement: (applicationId: BigString, entitlementId: BigString) => Promise<void>
/**
* For One-Time Purchase consumable SKUs, marks a given entitlement for the user as consumed. The entitlement will have `consumed: true` when using {@link RestManager.listEntitlements | List Entitlements}
*/
consumeEntitlement: (applicationId: BigString, entitlementId: BigString) => Promise<void>
/** /**
* Returns all SKUs for a given application * Returns all SKUs for a given application
* *
+2
View File
@@ -268,6 +268,8 @@ export interface RestRoutes {
entitlements: (applicationId: BigString, options?: GetEntitlements) => string entitlements: (applicationId: BigString, options?: GetEntitlements) => string
/** Route to delete an entitlement */ /** Route to delete an entitlement */
entitlement: (applicationId: BigString, entitlementId: BigString) => string entitlement: (applicationId: BigString, entitlementId: BigString) => string
/** Route to consume an entitlement */
consumeEntitlement: (applicationId: BigString, entitlementId: BigString) => string
/** Route to list the SKUs */ /** Route to list the SKUs */
skus: (applicationId: BigString) => string skus: (applicationId: BigString) => string
} }
+20
View File
@@ -3265,10 +3265,26 @@ export interface DiscordEntitlement {
starts_at?: string starts_at?: string
/** Date at which the entitlement is no longer valid. Not present when using test entitlements */ /** Date at which the entitlement is no longer valid. Not present when using test entitlements */
ends_at?: string ends_at?: string
/** For consumable items, whether or not the entitlement has been consumed */
consumed?: boolean
} }
/** https://discord.com/developers/docs/monetization/entitlements#entitlement-object-entitlement-types */ /** https://discord.com/developers/docs/monetization/entitlements#entitlement-object-entitlement-types */
export enum DiscordEntitlementType { export enum DiscordEntitlementType {
/** Entitlement was purchased by user */
Purchase = 1,
/** Entitlement for Discord Nitro subscription */
PremiumSubscription = 2,
/** Entitlement was gifted by developer */
DeveloperGift = 3,
/** Entitlement was purchased by a dev in application test mode */
TestModePurchase = 4,
/** Entitlement was granted when the SKU was free */
FreePurchase = 5,
/** Entitlement was gifted by another user */
UserGift = 6,
/** Entitlement was claimed by user for free as a Nitro Subscriber */
PremiumPurchase = 7,
/** Entitlement was purchased as an app subscription */ /** Entitlement was purchased as an app subscription */
ApplicationSubscription = 8, ApplicationSubscription = 8,
} }
@@ -3291,6 +3307,10 @@ export interface DiscordSku {
/** https://discord.com/developers/docs/monetization/skus#sku-object-sku-types */ /** https://discord.com/developers/docs/monetization/skus#sku-object-sku-types */
export enum DiscordSkuType { export enum DiscordSkuType {
/** Durable one-time purchase */
Durable = 2,
/** Consumable one-time purchase */
Consumable = 3,
/** Represents a recurring subscription */ /** Represents a recurring subscription */
Subscription = 5, Subscription = 5,
/** System-generated group for each SUBSCRIPTION SKU created */ /** System-generated group for each SUBSCRIPTION SKU created */