mirror of
https://github.com/Rapptz/discord.py.git
synced 2025-06-07 20:28:38 +00:00
Add SKU subscriptions support
This commit is contained in:
parent
0ce75f3f53
commit
58b6929aa5
@ -71,6 +71,7 @@ from .threads import *
|
|||||||
from .automod import *
|
from .automod import *
|
||||||
from .poll import *
|
from .poll import *
|
||||||
from .soundboard import *
|
from .soundboard import *
|
||||||
|
from .subscription import *
|
||||||
|
|
||||||
|
|
||||||
class VersionInfo(NamedTuple):
|
class VersionInfo(NamedTuple):
|
||||||
|
@ -119,6 +119,7 @@ if TYPE_CHECKING:
|
|||||||
from .voice_client import VoiceProtocol
|
from .voice_client import VoiceProtocol
|
||||||
from .audit_logs import AuditLogEntry
|
from .audit_logs import AuditLogEntry
|
||||||
from .poll import PollAnswer
|
from .poll import PollAnswer
|
||||||
|
from .subscription import Subscription
|
||||||
|
|
||||||
|
|
||||||
# fmt: off
|
# fmt: off
|
||||||
@ -1373,6 +1374,18 @@ class Client:
|
|||||||
) -> Union[str, bytes]:
|
) -> Union[str, bytes]:
|
||||||
...
|
...
|
||||||
|
|
||||||
|
# Entitlements
|
||||||
|
@overload
|
||||||
|
async def wait_for(
|
||||||
|
self,
|
||||||
|
event: Literal['entitlement_create', 'entitlement_update', 'entitlement_delete'],
|
||||||
|
/,
|
||||||
|
*,
|
||||||
|
check: Optional[Callable[[Entitlement], bool]],
|
||||||
|
timeout: Optional[float] = None,
|
||||||
|
) -> Entitlement:
|
||||||
|
...
|
||||||
|
|
||||||
# Guilds
|
# Guilds
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
@ -1781,6 +1794,18 @@ class Client:
|
|||||||
) -> Coroutine[Any, Any, Tuple[StageInstance, StageInstance]]:
|
) -> Coroutine[Any, Any, Tuple[StageInstance, StageInstance]]:
|
||||||
...
|
...
|
||||||
|
|
||||||
|
# Subscriptions
|
||||||
|
@overload
|
||||||
|
async def wait_for(
|
||||||
|
self,
|
||||||
|
event: Literal['subscription_create', 'subscription_update', 'subscription_delete'],
|
||||||
|
/,
|
||||||
|
*,
|
||||||
|
check: Optional[Callable[[Subscription], bool]],
|
||||||
|
timeout: Optional[float] = None,
|
||||||
|
) -> Subscription:
|
||||||
|
...
|
||||||
|
|
||||||
# Threads
|
# Threads
|
||||||
@overload
|
@overload
|
||||||
async def wait_for(
|
async def wait_for(
|
||||||
|
@ -75,6 +75,7 @@ __all__ = (
|
|||||||
'EntitlementOwnerType',
|
'EntitlementOwnerType',
|
||||||
'PollLayoutType',
|
'PollLayoutType',
|
||||||
'VoiceChannelEffectAnimationType',
|
'VoiceChannelEffectAnimationType',
|
||||||
|
'SubscriptionStatus',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -847,6 +848,12 @@ class VoiceChannelEffectAnimationType(Enum):
|
|||||||
basic = 1
|
basic = 1
|
||||||
|
|
||||||
|
|
||||||
|
class SubscriptionStatus(Enum):
|
||||||
|
active = 0
|
||||||
|
ending = 1
|
||||||
|
inactive = 2
|
||||||
|
|
||||||
|
|
||||||
def create_unknown_value(cls: Type[E], val: Any) -> E:
|
def create_unknown_value(cls: Type[E], val: Any) -> E:
|
||||||
value_cls = cls._enum_value_cls_ # type: ignore # This is narrowed below
|
value_cls = cls._enum_value_cls_ # type: ignore # This is narrowed below
|
||||||
name = f'unknown_{val}'
|
name = f'unknown_{val}'
|
||||||
|
@ -94,6 +94,7 @@ if TYPE_CHECKING:
|
|||||||
poll,
|
poll,
|
||||||
voice,
|
voice,
|
||||||
soundboard,
|
soundboard,
|
||||||
|
subscription,
|
||||||
)
|
)
|
||||||
from .types.snowflake import Snowflake, SnowflakeList
|
from .types.snowflake import Snowflake, SnowflakeList
|
||||||
|
|
||||||
@ -2699,6 +2700,49 @@ class HTTPClient:
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Subscriptions
|
||||||
|
|
||||||
|
def list_sku_subscriptions(
|
||||||
|
self,
|
||||||
|
sku_id: Snowflake,
|
||||||
|
before: Optional[Snowflake] = None,
|
||||||
|
after: Optional[Snowflake] = None,
|
||||||
|
limit: Optional[int] = None,
|
||||||
|
user_id: Optional[Snowflake] = None,
|
||||||
|
) -> Response[List[subscription.Subscription]]:
|
||||||
|
params = {}
|
||||||
|
|
||||||
|
if before is not None:
|
||||||
|
params['before'] = before
|
||||||
|
|
||||||
|
if after is not None:
|
||||||
|
params['after'] = after
|
||||||
|
|
||||||
|
if limit is not None:
|
||||||
|
params['limit'] = limit
|
||||||
|
|
||||||
|
if user_id is not None:
|
||||||
|
params['user_id'] = user_id
|
||||||
|
|
||||||
|
return self.request(
|
||||||
|
Route(
|
||||||
|
'GET',
|
||||||
|
'/skus/{sku_id}/subscriptions',
|
||||||
|
sku_id=sku_id,
|
||||||
|
),
|
||||||
|
params=params,
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_sku_subscription(self, sku_id: Snowflake, subscription_id: Snowflake) -> Response[subscription.Subscription]:
|
||||||
|
return self.request(
|
||||||
|
Route(
|
||||||
|
'GET',
|
||||||
|
'/skus/{sku_id}/subscriptions/{subscription_id}',
|
||||||
|
sku_id=sku_id,
|
||||||
|
subscription_id=subscription_id,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
# Misc
|
# Misc
|
||||||
|
|
||||||
async def get_bot_gateway(self) -> Tuple[int, str]:
|
async def get_bot_gateway(self) -> Tuple[int, str]:
|
||||||
|
159
discord/sku.py
159
discord/sku.py
@ -25,16 +25,18 @@ DEALINGS IN THE SOFTWARE.
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import Optional, TYPE_CHECKING
|
from typing import AsyncIterator, Optional, TYPE_CHECKING
|
||||||
|
|
||||||
from . import utils
|
from . import utils
|
||||||
from .errors import MissingApplicationID
|
|
||||||
from .enums import try_enum, SKUType, EntitlementType
|
from .enums import try_enum, SKUType, EntitlementType
|
||||||
from .flags import SKUFlags
|
from .flags import SKUFlags
|
||||||
|
from .object import Object
|
||||||
|
from .subscription import Subscription
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
|
from .abc import SnowflakeTime, Snowflake
|
||||||
from .guild import Guild
|
from .guild import Guild
|
||||||
from .state import ConnectionState
|
from .state import ConnectionState
|
||||||
from .types.sku import (
|
from .types.sku import (
|
||||||
@ -100,6 +102,149 @@ class SKU:
|
|||||||
""":class:`datetime.datetime`: Returns the sku's creation time in UTC."""
|
""":class:`datetime.datetime`: Returns the sku's creation time in UTC."""
|
||||||
return utils.snowflake_time(self.id)
|
return utils.snowflake_time(self.id)
|
||||||
|
|
||||||
|
async def fetch_subscription(self, subscription_id: int, /) -> Subscription:
|
||||||
|
"""|coro|
|
||||||
|
|
||||||
|
Retrieves a :class:`.Subscription` with the specified ID.
|
||||||
|
|
||||||
|
.. versionadded:: 2.5
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
-----------
|
||||||
|
subscription_id: :class:`int`
|
||||||
|
The subscription's ID to fetch from.
|
||||||
|
|
||||||
|
Raises
|
||||||
|
-------
|
||||||
|
NotFound
|
||||||
|
An subscription with this ID does not exist.
|
||||||
|
HTTPException
|
||||||
|
Fetching the subscription failed.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
--------
|
||||||
|
:class:`.Subscription`
|
||||||
|
The subscription you requested.
|
||||||
|
"""
|
||||||
|
data = await self._state.http.get_sku_subscription(self.id, subscription_id)
|
||||||
|
return Subscription(data=data, state=self._state)
|
||||||
|
|
||||||
|
async def subscriptions(
|
||||||
|
self,
|
||||||
|
*,
|
||||||
|
limit: Optional[int] = 50,
|
||||||
|
before: Optional[SnowflakeTime] = None,
|
||||||
|
after: Optional[SnowflakeTime] = None,
|
||||||
|
user: Snowflake,
|
||||||
|
) -> AsyncIterator[Subscription]:
|
||||||
|
"""Retrieves an :term:`asynchronous iterator` of the :class:`.Subscription` that SKU has.
|
||||||
|
|
||||||
|
.. versionadded:: 2.5
|
||||||
|
|
||||||
|
Examples
|
||||||
|
---------
|
||||||
|
|
||||||
|
Usage ::
|
||||||
|
|
||||||
|
async for subscription in sku.subscriptions(limit=100):
|
||||||
|
print(subscription.user_id, subscription.current_period_end)
|
||||||
|
|
||||||
|
Flattening into a list ::
|
||||||
|
|
||||||
|
subscriptions = [subscription async for subscription in sku.subscriptions(limit=100)]
|
||||||
|
# subscriptions is now a list of Subscription...
|
||||||
|
|
||||||
|
All parameters are optional.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
-----------
|
||||||
|
limit: Optional[:class:`int`]
|
||||||
|
The number of subscriptions to retrieve. If ``None``, it retrieves every subscription for this SKU.
|
||||||
|
Note, however, that this would make it a slow operation. Defaults to ``100``.
|
||||||
|
before: Optional[Union[:class:`~discord.abc.Snowflake`, :class:`datetime.datetime`]]
|
||||||
|
Retrieve subscriptions before this date or entitlement.
|
||||||
|
If a datetime is provided, it is recommended to use a UTC aware datetime.
|
||||||
|
If the datetime is naive, it is assumed to be local time.
|
||||||
|
after: Optional[Union[:class:`~discord.abc.Snowflake`, :class:`datetime.datetime`]]
|
||||||
|
Retrieve subscriptions after this date or entitlement.
|
||||||
|
If a datetime is provided, it is recommended to use a UTC aware datetime.
|
||||||
|
If the datetime is naive, it is assumed to be local time.
|
||||||
|
user: :class:`~discord.abc.Snowflake`
|
||||||
|
The user to filter by.
|
||||||
|
|
||||||
|
Raises
|
||||||
|
-------
|
||||||
|
HTTPException
|
||||||
|
Fetching the subscriptions failed.
|
||||||
|
TypeError
|
||||||
|
Both ``after`` and ``before`` were provided, as Discord does not
|
||||||
|
support this type of pagination.
|
||||||
|
|
||||||
|
Yields
|
||||||
|
--------
|
||||||
|
:class:`.Subscription`
|
||||||
|
The subscription with the SKU.
|
||||||
|
"""
|
||||||
|
|
||||||
|
if before is not None and after is not None:
|
||||||
|
raise TypeError('subscriptions pagination does not support both before and after')
|
||||||
|
|
||||||
|
# This endpoint paginates in ascending order.
|
||||||
|
endpoint = self._state.http.list_sku_subscriptions
|
||||||
|
|
||||||
|
async def _before_strategy(retrieve: int, before: Optional[Snowflake], limit: Optional[int]):
|
||||||
|
before_id = before.id if before else None
|
||||||
|
data = await endpoint(self.id, before=before_id, limit=retrieve, user_id=user.id)
|
||||||
|
|
||||||
|
if data:
|
||||||
|
if limit is not None:
|
||||||
|
limit -= len(data)
|
||||||
|
|
||||||
|
before = Object(id=int(data[0]['id']))
|
||||||
|
|
||||||
|
return data, before, limit
|
||||||
|
|
||||||
|
async def _after_strategy(retrieve: int, after: Optional[Snowflake], limit: Optional[int]):
|
||||||
|
after_id = after.id if after else None
|
||||||
|
data = await endpoint(
|
||||||
|
self.id,
|
||||||
|
after=after_id,
|
||||||
|
limit=retrieve,
|
||||||
|
user_id=user.id,
|
||||||
|
)
|
||||||
|
|
||||||
|
if data:
|
||||||
|
if limit is not None:
|
||||||
|
limit -= len(data)
|
||||||
|
|
||||||
|
after = Object(id=int(data[-1]['id']))
|
||||||
|
|
||||||
|
return data, after, limit
|
||||||
|
|
||||||
|
if isinstance(before, datetime):
|
||||||
|
before = Object(id=utils.time_snowflake(before, high=False))
|
||||||
|
if isinstance(after, datetime):
|
||||||
|
after = Object(id=utils.time_snowflake(after, high=True))
|
||||||
|
|
||||||
|
if before:
|
||||||
|
strategy, state = _before_strategy, before
|
||||||
|
else:
|
||||||
|
strategy, state = _after_strategy, after
|
||||||
|
|
||||||
|
while True:
|
||||||
|
retrieve = 100 if limit is None else min(limit, 100)
|
||||||
|
if retrieve < 1:
|
||||||
|
return
|
||||||
|
|
||||||
|
data, state, limit = await strategy(retrieve, state, limit)
|
||||||
|
|
||||||
|
# Terminate loop on next iteration; there's no data left after this
|
||||||
|
if len(data) < 1000:
|
||||||
|
limit = 0
|
||||||
|
|
||||||
|
for e in data:
|
||||||
|
yield Subscription(data=e, state=self._state)
|
||||||
|
|
||||||
|
|
||||||
class Entitlement:
|
class Entitlement:
|
||||||
"""Represents an entitlement from user or guild which has been granted access to a premium offering.
|
"""Represents an entitlement from user or guild which has been granted access to a premium offering.
|
||||||
@ -190,17 +335,12 @@ class Entitlement:
|
|||||||
|
|
||||||
Raises
|
Raises
|
||||||
-------
|
-------
|
||||||
MissingApplicationID
|
|
||||||
The application ID could not be found.
|
|
||||||
NotFound
|
NotFound
|
||||||
The entitlement could not be found.
|
The entitlement could not be found.
|
||||||
HTTPException
|
HTTPException
|
||||||
Consuming the entitlement failed.
|
Consuming the entitlement failed.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if self.application_id is None:
|
|
||||||
raise MissingApplicationID
|
|
||||||
|
|
||||||
await self._state.http.consume_entitlement(self.application_id, self.id)
|
await self._state.http.consume_entitlement(self.application_id, self.id)
|
||||||
|
|
||||||
async def delete(self) -> None:
|
async def delete(self) -> None:
|
||||||
@ -210,15 +350,10 @@ class Entitlement:
|
|||||||
|
|
||||||
Raises
|
Raises
|
||||||
-------
|
-------
|
||||||
MissingApplicationID
|
|
||||||
The application ID could not be found.
|
|
||||||
NotFound
|
NotFound
|
||||||
The entitlement could not be found.
|
The entitlement could not be found.
|
||||||
HTTPException
|
HTTPException
|
||||||
Deleting the entitlement failed.
|
Deleting the entitlement failed.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if self.application_id is None:
|
|
||||||
raise MissingApplicationID
|
|
||||||
|
|
||||||
await self._state.http.delete_entitlement(self.application_id, self.id)
|
await self._state.http.delete_entitlement(self.application_id, self.id)
|
||||||
|
@ -79,6 +79,8 @@ from .automod import AutoModRule, AutoModAction
|
|||||||
from .audit_logs import AuditLogEntry
|
from .audit_logs import AuditLogEntry
|
||||||
from ._types import ClientT
|
from ._types import ClientT
|
||||||
from .soundboard import SoundboardSound
|
from .soundboard import SoundboardSound
|
||||||
|
from .subscription import Subscription
|
||||||
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from .abc import PrivateChannel
|
from .abc import PrivateChannel
|
||||||
@ -1736,6 +1738,18 @@ class ConnectionState(Generic[ClientT]):
|
|||||||
if poll:
|
if poll:
|
||||||
self.dispatch('poll_vote_remove', user, poll.get_answer(raw.answer_id))
|
self.dispatch('poll_vote_remove', user, poll.get_answer(raw.answer_id))
|
||||||
|
|
||||||
|
def parse_subscription_create(self, data: gw.SubscriptionCreateEvent) -> None:
|
||||||
|
subscription = Subscription(data=data, state=self)
|
||||||
|
self.dispatch('subscription_create', subscription)
|
||||||
|
|
||||||
|
def parse_subscription_update(self, data: gw.SubscriptionUpdateEvent) -> None:
|
||||||
|
subscription = Subscription(data=data, state=self)
|
||||||
|
self.dispatch('subscription_update', subscription)
|
||||||
|
|
||||||
|
def parse_subscription_delete(self, data: gw.SubscriptionDeleteEvent) -> None:
|
||||||
|
subscription = Subscription(data=data, state=self)
|
||||||
|
self.dispatch('subscription_delete', subscription)
|
||||||
|
|
||||||
def _get_reaction_user(self, channel: MessageableChannel, user_id: int) -> Optional[Union[User, Member]]:
|
def _get_reaction_user(self, channel: MessageableChannel, user_id: int) -> Optional[Union[User, Member]]:
|
||||||
if isinstance(channel, (TextChannel, Thread, VoiceChannel)):
|
if isinstance(channel, (TextChannel, Thread, VoiceChannel)):
|
||||||
return channel.guild.get_member(user_id)
|
return channel.guild.get_member(user_id)
|
||||||
|
103
discord/subscription.py
Normal file
103
discord/subscription.py
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
"""
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2015-present Rapptz
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
to deal in the Software without restriction, including without limitation
|
||||||
|
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import datetime
|
||||||
|
from typing import List, Optional, TYPE_CHECKING
|
||||||
|
|
||||||
|
from . import utils
|
||||||
|
from .mixins import Hashable
|
||||||
|
from .enums import try_enum, SubscriptionStatus
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from .state import ConnectionState
|
||||||
|
from .types.subscription import Subscription as SubscriptionPayload
|
||||||
|
from .user import User
|
||||||
|
|
||||||
|
__all__ = ('Subscription',)
|
||||||
|
|
||||||
|
|
||||||
|
class Subscription(Hashable):
|
||||||
|
"""Represents a Discord subscription.
|
||||||
|
|
||||||
|
.. versionadded:: 2.5
|
||||||
|
|
||||||
|
Attributes
|
||||||
|
-----------
|
||||||
|
id: :class:`int`
|
||||||
|
The subscription's ID.
|
||||||
|
user_id: :class:`int`
|
||||||
|
The ID of the user that is subscribed.
|
||||||
|
sku_ids: List[:class:`int`]
|
||||||
|
The IDs of the SKUs that the user subscribed to.
|
||||||
|
entitlement_ids: List[:class:`int`]
|
||||||
|
The IDs of the entitlements granted for this subscription.
|
||||||
|
current_period_start: :class:`datetime.datetime`
|
||||||
|
When the current billing period started.
|
||||||
|
current_period_end: :class:`datetime.datetime`
|
||||||
|
When the current billing period ends.
|
||||||
|
status: :class:`SubscriptionStatus`
|
||||||
|
The status of the subscription.
|
||||||
|
canceled_at: Optional[:class:`datetime.datetime`]
|
||||||
|
When the subscription was canceled.
|
||||||
|
This is only available for subscriptions with a :attr:`status` of :attr:`SubscriptionStatus.inactive`.
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = (
|
||||||
|
'_state',
|
||||||
|
'id',
|
||||||
|
'user_id',
|
||||||
|
'sku_ids',
|
||||||
|
'entitlement_ids',
|
||||||
|
'current_period_start',
|
||||||
|
'current_period_end',
|
||||||
|
'status',
|
||||||
|
'canceled_at',
|
||||||
|
)
|
||||||
|
|
||||||
|
def __init__(self, *, state: ConnectionState, data: SubscriptionPayload):
|
||||||
|
self._state = state
|
||||||
|
|
||||||
|
self.id: int = int(data['id'])
|
||||||
|
self.user_id: int = int(data['user_id'])
|
||||||
|
self.sku_ids: List[int] = list(map(int, data['sku_ids']))
|
||||||
|
self.entitlement_ids: List[int] = list(map(int, data['entitlement_ids']))
|
||||||
|
self.current_period_start: datetime.datetime = utils.parse_time(data['current_period_start'])
|
||||||
|
self.current_period_end: datetime.datetime = utils.parse_time(data['current_period_end'])
|
||||||
|
self.status: SubscriptionStatus = try_enum(SubscriptionStatus, data['status'])
|
||||||
|
self.canceled_at: Optional[datetime.datetime] = utils.parse_time(data['canceled_at'])
|
||||||
|
|
||||||
|
def __repr__(self) -> str:
|
||||||
|
return f'<Subscription id={self.id} user_id={self.user_id} status={self.status!r}>'
|
||||||
|
|
||||||
|
@property
|
||||||
|
def created_at(self) -> datetime.datetime:
|
||||||
|
""":class:`datetime.datetime`: Returns the subscription's creation time in UTC."""
|
||||||
|
return utils.snowflake_time(self.id)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def user(self) -> Optional[User]:
|
||||||
|
"""Optional[:class:`User`]: The user that is subscribed."""
|
||||||
|
return self._state.get_user(self.user_id)
|
@ -46,6 +46,7 @@ from .threads import Thread, ThreadMember
|
|||||||
from .scheduled_event import GuildScheduledEvent
|
from .scheduled_event import GuildScheduledEvent
|
||||||
from .audit_log import AuditLogEntry
|
from .audit_log import AuditLogEntry
|
||||||
from .soundboard import SoundboardSound
|
from .soundboard import SoundboardSound
|
||||||
|
from .subscription import Subscription
|
||||||
|
|
||||||
|
|
||||||
class SessionStartLimit(TypedDict):
|
class SessionStartLimit(TypedDict):
|
||||||
@ -372,3 +373,6 @@ class PollVoteActionEvent(TypedDict):
|
|||||||
message_id: Snowflake
|
message_id: Snowflake
|
||||||
guild_id: NotRequired[Snowflake]
|
guild_id: NotRequired[Snowflake]
|
||||||
answer_id: int
|
answer_id: int
|
||||||
|
|
||||||
|
|
||||||
|
SubscriptionCreateEvent = SubscriptionUpdateEvent = SubscriptionDeleteEvent = Subscription
|
||||||
|
42
discord/types/subscription.py
Normal file
42
discord/types/subscription.py
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
"""
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2015-present Rapptz
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
to deal in the Software without restriction, including without limitation
|
||||||
|
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import List, Literal, Optional, TypedDict
|
||||||
|
|
||||||
|
from .snowflake import Snowflake
|
||||||
|
|
||||||
|
SubscriptionStatus = Literal[0, 1, 2]
|
||||||
|
|
||||||
|
|
||||||
|
class Subscription(TypedDict):
|
||||||
|
id: Snowflake
|
||||||
|
user_id: Snowflake
|
||||||
|
sku_ids: List[Snowflake]
|
||||||
|
entitlement_ids: List[Snowflake]
|
||||||
|
current_period_start: str
|
||||||
|
current_period_end: str
|
||||||
|
status: SubscriptionStatus
|
||||||
|
canceled_at: Optional[str]
|
58
docs/api.rst
58
docs/api.rst
@ -1356,6 +1356,37 @@ Stages
|
|||||||
:param after: The stage instance after the update.
|
:param after: The stage instance after the update.
|
||||||
:type after: :class:`StageInstance`
|
:type after: :class:`StageInstance`
|
||||||
|
|
||||||
|
|
||||||
|
Subscriptions
|
||||||
|
~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. function:: on_subscription_create(subscription)
|
||||||
|
|
||||||
|
Called when a subscription is created.
|
||||||
|
|
||||||
|
.. versionadded:: 2.5
|
||||||
|
|
||||||
|
:param subscription: The subscription that was created.
|
||||||
|
:type subscription: :class:`Subscription`
|
||||||
|
|
||||||
|
.. function:: on_subscription_update(subscription)
|
||||||
|
|
||||||
|
Called when a subscription is updated.
|
||||||
|
|
||||||
|
.. versionadded:: 2.5
|
||||||
|
|
||||||
|
:param subscription: The subscription that was updated.
|
||||||
|
:type subscription: :class:`Subscription`
|
||||||
|
|
||||||
|
.. function:: on_subscription_delete(subscription)
|
||||||
|
|
||||||
|
Called when a subscription is deleted.
|
||||||
|
|
||||||
|
.. versionadded:: 2.5
|
||||||
|
|
||||||
|
:param subscription: The subscription that was deleted.
|
||||||
|
:type subscription: :class:`Subscription`
|
||||||
|
|
||||||
Threads
|
Threads
|
||||||
~~~~~~~~
|
~~~~~~~~
|
||||||
|
|
||||||
@ -3754,6 +3785,25 @@ of :class:`enum.Enum`.
|
|||||||
The standard animation.
|
The standard animation.
|
||||||
|
|
||||||
|
|
||||||
|
.. class:: SubscriptionStatus
|
||||||
|
|
||||||
|
Represents the status of an subscription.
|
||||||
|
|
||||||
|
.. versionadded:: 2.5
|
||||||
|
|
||||||
|
.. attribute:: active
|
||||||
|
|
||||||
|
The subscription is active.
|
||||||
|
|
||||||
|
.. attribute:: ending
|
||||||
|
|
||||||
|
The subscription is active but will not renew.
|
||||||
|
|
||||||
|
.. attribute:: inactive
|
||||||
|
|
||||||
|
The subscription is inactive and not being charged.
|
||||||
|
|
||||||
|
|
||||||
.. _discord-api-audit-logs:
|
.. _discord-api-audit-logs:
|
||||||
|
|
||||||
Audit Log Data
|
Audit Log Data
|
||||||
@ -5151,6 +5201,14 @@ Entitlement
|
|||||||
.. autoclass:: Entitlement()
|
.. autoclass:: Entitlement()
|
||||||
:members:
|
:members:
|
||||||
|
|
||||||
|
Subscription
|
||||||
|
~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. attributetable:: Subscription
|
||||||
|
|
||||||
|
.. autoclass:: Subscription()
|
||||||
|
:members:
|
||||||
|
|
||||||
RawMessageDeleteEvent
|
RawMessageDeleteEvent
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user