Skip to content

Commit

Permalink
feat: consumable entitlements (#10235)
Browse files Browse the repository at this point in the history
* feat: consumable entitlements

* feat: move logic to EntitlementManager

---------

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
  • Loading branch information
almeidx and kodiakhq[bot] authored May 1, 2024
1 parent a1aeaeb commit 9978870
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 0 deletions.
16 changes: 16 additions & 0 deletions packages/core/src/api/monetization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,20 @@ export class MonetizationAPI {
) {
await this.rest.delete(Routes.entitlement(applicationId, entitlementId), { signal });
}

/**
* Marks a given entitlement for the user as consumed. Only available for One-Time Purchase consumable SKUs.
*
* @see {@link https://discord.com/developers/docs/monetization/entitlements#consume-an-entitlement}
* @param applicationId - The application id to consume the entitlement for
* @param entitlementId - The entitlement id to consume
* @param options - The options for consuming the entitlement
*/
public async consumeEntitlement(
applicationId: Snowflake,
entitlementId: Snowflake,
{ signal }: Pick<RequestData, 'signal'> = {},
) {
await this.rest.post(Routes.consumeEntitlement(applicationId, entitlementId), { signal });
}
}
10 changes: 10 additions & 0 deletions packages/discord.js/src/managers/EntitlementManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,16 @@ class EntitlementManager extends CachedManager {

await this.client.rest.delete(Routes.entitlement(this.client.application.id, resolved));
}

/**
* Marks an entitlement as consumed
* <info>Only available for One-Time Purchase consumable SKUs.</info>
* @param {Snowflake} entitlementId The id of the entitlement to consume
* @returns {Promise<void>}
*/
async consume(entitlementId) {
await this.client.rest.post(Routes.consumeEntitlement(this.client.application.id, entitlementId));
}
}

exports.EntitlementManager = EntitlementManager;
19 changes: 19 additions & 0 deletions packages/discord.js/src/structures/Entitlement.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,16 @@ class Entitlement extends Base {
} else {
this.endsTimestamp ??= null;
}

if ('consumed' in data) {
/**
* Whether this entitlement has been consumed
* @type {boolean}
*/
this.consumed = data.consumed;
} else {
this.consumed ??= false;
}
}

/**
Expand Down Expand Up @@ -159,6 +169,15 @@ class Entitlement extends Base {
fetchUser() {
return this.client.users.fetch(this.userId);
}

/**
* Marks this entitlement as consumed
* <info>Only available for One-Time Purchase consumable SKUs.</info>
* @returns {Promise<void>}
*/
async consume() {
await this.client.application.entitlements.consume(this.id);
}
}

exports.Entitlement = Entitlement;
3 changes: 3 additions & 0 deletions packages/discord.js/typings/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1346,12 +1346,14 @@ export class Entitlement extends Base {
public guildId: Snowflake | null;
public applicationId: Snowflake;
public type: EntitlementType;
public consumed: boolean;
public deleted: boolean;
public startsTimestamp: number | null;
public endsTimestamp: number | null;
public get guild(): Guild | null;
public get startsAt(): Date | null;
public get endsAt(): Date | null;
public consume(): Promise<void>;
public fetchUser(): Promise<User>;
public isActive(): boolean;
public isTest(): this is this & {
Expand Down Expand Up @@ -4179,6 +4181,7 @@ export class EntitlementManager extends CachedManager<Snowflake, Entitlement, En
public fetch(options?: FetchEntitlementsOptions): Promise<Collection<Snowflake, Entitlement>>;
public createTest(options: GuildEntitlementCreateOptions | UserEntitlementCreateOptions): Promise<Entitlement>;
public deleteTest(entitlement: EntitlementResolvable): Promise<void>;
public consume(entitlementId: Snowflake): Promise<void>;
}

export interface FetchGuildApplicationCommandFetchOptions extends Omit<FetchApplicationCommandOptions, 'guildId'> {}
Expand Down
2 changes: 2 additions & 0 deletions packages/discord.js/typings/index.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2495,6 +2495,8 @@ declare const sku: SKU;

await application.entitlements.deleteTest(entitlement);

await application.entitlements.consume(snowflake);

expectType<boolean>(entitlement.isActive());

if (entitlement.isUserSubscription()) {
Expand Down

0 comments on commit 9978870

Please sign in to comment.