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

Add support for one-time purchases #9803

Merged
merged 3 commits into from May 5, 2024
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
9 changes: 9 additions & 0 deletions discord/enums.py
Expand Up @@ -796,11 +796,20 @@ class SelectDefaultValueType(Enum):


class SKUType(Enum):
durable = 2
consumable = 3
subscription = 5
subscription_group = 6


class EntitlementType(Enum):
purchase = 1
premium_subscription = 2
developer_gift = 3
test_mode_purchase = 4
free_purchase = 5
user_gift = 6
premium_purchase = 7
application_subscription = 8


Expand Down
10 changes: 10 additions & 0 deletions discord/http.py
Expand Up @@ -2454,6 +2454,16 @@ def get_entitlement(self, application_id: Snowflake, entitlement_id: Snowflake)
),
)

def consume_entitlement(self, application_id: Snowflake, entitlement_id: Snowflake) -> Response[None]:
return self.request(
Route(
'POST',
'/applications/{application_id}/entitlements/{entitlement_id}/consume',
application_id=application_id,
entitlement_id=entitlement_id,
),
)

def create_entitlement(
self, application_id: Snowflake, sku_id: Snowflake, owner_id: Snowflake, owner_type: sku.EntitlementOwnerType
) -> Response[sku.Entitlement]:
Expand Down
24 changes: 24 additions & 0 deletions discord/sku.py
Expand Up @@ -126,6 +126,8 @@ class Entitlement:
A UTC date which entitlement is no longer valid. Not present when using test entitlements.
guild_id: Optional[:class:`int`]
The ID of the guild that is granted access to the entitlement
consumed: :class:`bool`
For consumable items, whether the entitlement has been consumed.
"""

__slots__ = (
Expand All @@ -139,6 +141,7 @@ class Entitlement:
'starts_at',
'ends_at',
'guild_id',
'consumed',
)

def __init__(self, state: ConnectionState, data: EntitlementPayload):
Expand All @@ -152,6 +155,7 @@ def __init__(self, state: ConnectionState, data: EntitlementPayload):
self.starts_at: Optional[datetime] = utils.parse_time(data.get('starts_at', None))
self.ends_at: Optional[datetime] = utils.parse_time(data.get('ends_at', None))
self.guild_id: Optional[int] = utils._get_as_snowflake(data, 'guild_id')
self.consumed: bool = data.get('consumed', False)

def __repr__(self) -> str:
return f'<Entitlement id={self.id} type={self.type!r} user_id={self.user_id}>'
Expand Down Expand Up @@ -179,6 +183,26 @@ def is_expired(self) -> bool:
return False
return utils.utcnow() >= self.ends_at

async def consume(self) -> None:
"""|coro|

Marks a one-time purchase entitlement as consumed.

Raises
-------
MissingApplicationID
The application ID could not be found.
NotFound
The entitlement could not be found.
HTTPException
Consuming the entitlement failed.
"""

if self.application_id is None:
raise MissingApplicationID

await self._state.http.consume_entitlement(self.application_id, self.id)

async def delete(self) -> None:
"""|coro|

Expand Down
3 changes: 2 additions & 1 deletion discord/types/sku.py
Expand Up @@ -46,7 +46,8 @@ class Entitlement(TypedDict):
deleted: bool
starts_at: NotRequired[str]
ends_at: NotRequired[str]
guild_id: Optional[str]
guild_id: NotRequired[str]
consumed: NotRequired[bool]


EntitlementOwnerType = Literal[1, 2]
36 changes: 36 additions & 0 deletions docs/api.rst
Expand Up @@ -3506,6 +3506,14 @@ of :class:`enum.Enum`.

.. versionadded:: 2.4

.. attribute:: durable

The SKU is a durable one-time purchase.

.. attribute:: consumable

The SKU is a consumable one-time purchase.

.. attribute:: subscription

The SKU is a recurring subscription.
Expand All @@ -3521,6 +3529,34 @@ of :class:`enum.Enum`.

.. versionadded:: 2.4

.. attribute:: purchase

The entitlement was purchased by the user.

.. attribute:: premium_subscription

The entitlement is for a nitro subscription.

.. attribute:: developer_gift

The entitlement was gifted by the developer.

.. attribute:: test_mode_purchase

The entitlement was purchased by a developer in application test mode.

.. attribute:: free_purchase

The entitlement was granted, when the SKU was free.

.. attribute:: user_gift

The entitlement was gifted by a another user.

.. attribute:: premium_purchase

The entitlement was claimed for free by a nitro subscriber.

.. attribute:: application_subscription

The entitlement was purchased as an app subscription.
Expand Down