Browse Source

Update invite parameters and add stage interoperability

pull/10109/head
dolfies 2 years ago
parent
commit
44ec9f40c7
  1. 28
      discord/abc.py
  2. 6
      discord/channel.py
  3. 11
      discord/client.py
  4. 8
      discord/http.py
  5. 22
      discord/invite.py
  6. 88
      discord/stage_instance.py
  7. 9
      discord/types/channel.py
  8. 16
      discord/types/guild.py
  9. 73
      discord/types/invite.py

28
discord/abc.py

@ -60,6 +60,7 @@ from .voice_client import VoiceClient, VoiceProtocol
from .sticker import GuildSticker, StickerItem from .sticker import GuildSticker, StickerItem
from .settings import ChannelSettings from .settings import ChannelSettings
from .commands import ApplicationCommand, BaseCommand, SlashCommand, UserCommand, MessageCommand, _command_factory from .commands import ApplicationCommand, BaseCommand, SlashCommand, UserCommand, MessageCommand, _command_factory
from .flags import InviteFlags
from . import utils from . import utils
__all__ = ( __all__ = (
@ -1475,7 +1476,7 @@ class GuildChannel:
max_uses: int = 0, max_uses: int = 0,
temporary: bool = False, temporary: bool = False,
unique: bool = True, unique: bool = True,
validate: Optional[Union[Invite, str]] = None, guest: bool = False,
target_type: Optional[InviteTarget] = None, target_type: Optional[InviteTarget] = None,
target_user: Optional[User] = None, target_user: Optional[User] = None,
target_application: Optional[Snowflake] = None, target_application: Optional[Snowflake] = None,
@ -1486,6 +1487,10 @@ class GuildChannel:
You must have :attr:`~discord.Permissions.create_instant_invite` to do this. You must have :attr:`~discord.Permissions.create_instant_invite` to do this.
.. versionchanged:: 2.1
The ``validate`` parameter has been removed.
Parameters Parameters
------------ ------------
max_age: :class:`int` max_age: :class:`int`
@ -1497,30 +1502,28 @@ class GuildChannel:
temporary: :class:`bool` temporary: :class:`bool`
Denotes that the invite grants temporary membership Denotes that the invite grants temporary membership
(i.e. they get kicked after they disconnect). Defaults to ``False``. (i.e. they get kicked after they disconnect). Defaults to ``False``.
guest: :class:`bool`
Denotes that the invite is a guest invite.
Guest invites grant temporary membership for the purposes of joining a voice channel.
Defaults to ``False``.
.. versionadded:: 2.1
unique: :class:`bool` unique: :class:`bool`
Indicates if a unique invite URL should be created. Defaults to True. Indicates if a unique invite URL should be created. Defaults to ``True``.
If this is set to ``False`` then it will return a previously created If this is set to ``False`` then it will return a previously created
invite. invite.
validate: Union[:class:`.Invite`, :class:`str`]
The existing channel invite to validate and return for reuse.
If this invite is invalid, a new invite will be created according to the parameters and returned.
.. versionadded:: 2.0
target_type: Optional[:class:`~discord.InviteTarget`] target_type: Optional[:class:`~discord.InviteTarget`]
The type of target for the voice channel invite, if any. The type of target for the voice channel invite, if any.
.. versionadded:: 2.0 .. versionadded:: 2.0
target_user: Optional[:class:`~discord.User`] target_user: Optional[:class:`~discord.User`]
The user whose stream to display for this invite, required if ``target_type`` is :attr:`.InviteTarget.stream`. The user must be streaming in the channel. The user whose stream to display for this invite, required if ``target_type`` is :attr:`.InviteTarget.stream`. The user must be streaming in the channel.
.. versionadded:: 2.0 .. versionadded:: 2.0
target_application:: Optional[:class:`~discord.Application`] target_application:: Optional[:class:`~discord.Application`]
The embedded application for the invite, required if ``target_type`` is :attr:`.InviteTarget.embedded_application`. The embedded application for the invite, required if ``target_type`` is :attr:`.InviteTarget.embedded_application`.
.. versionadded:: 2.0 .. versionadded:: 2.0
reason: Optional[:class:`str`] reason: Optional[:class:`str`]
The reason for creating this invite. Shows up on the audit log. The reason for creating this invite. Shows up on the audit log.
@ -1542,6 +1545,9 @@ class GuildChannel:
raise ValueError('target_type parameter must be InviteTarget.stream, or InviteTarget.embedded_application') raise ValueError('target_type parameter must be InviteTarget.stream, or InviteTarget.embedded_application')
if target_type == InviteTarget.unknown: if target_type == InviteTarget.unknown:
target_type = None target_type = None
flags = InviteFlags()
if guest:
flags.guest = True
data = await self._state.http.create_invite( data = await self._state.http.create_invite(
self.id, self.id,
@ -1550,10 +1556,10 @@ class GuildChannel:
max_uses=max_uses, max_uses=max_uses,
temporary=temporary, temporary=temporary,
unique=unique, unique=unique,
validate=utils.resolve_invite(validate).code if validate else None,
target_type=target_type.value if target_type else None, target_type=target_type.value if target_type else None,
target_user_id=target_user.id if target_user else None, target_user_id=target_user.id if target_user else None,
target_application_id=target_application.id if target_application else None, target_application_id=target_application.id if target_application else None,
flags=flags.value,
) )
return Invite.from_incomplete(data=data, state=self._state) return Invite.from_incomplete(data=data, state=self._state)

6
discord/channel.py

@ -1762,17 +1762,13 @@ class StageChannel(VocalGuildChannel):
:class:`StageInstance` :class:`StageInstance`
The newly created stage instance. The newly created stage instance.
""" """
payload = {'channel_id': self.id, 'topic': topic, 'send_start_notification': send_start_notification}
payload: Dict[str, Any] = {'channel_id': self.id, 'topic': topic}
if privacy_level is not MISSING: if privacy_level is not MISSING:
if not isinstance(privacy_level, PrivacyLevel): if not isinstance(privacy_level, PrivacyLevel):
raise TypeError('privacy_level field must be of type PrivacyLevel') raise TypeError('privacy_level field must be of type PrivacyLevel')
payload['privacy_level'] = privacy_level.value payload['privacy_level'] = privacy_level.value
payload['send_start_notification'] = send_start_notification
data = await self._state.http.create_stage_instance(**payload, reason=reason) data = await self._state.http.create_stage_instance(**payload, reason=reason)
return StageInstance(guild=self.guild, state=self._state, data=data) return StageInstance(guild=self.guild, state=self._state, data=data)

11
discord/client.py

@ -2029,7 +2029,6 @@ class Client:
/, /,
*, *,
with_counts: bool = True, with_counts: bool = True,
with_expiration: bool = True,
scheduled_event_id: Optional[int] = None, scheduled_event_id: Optional[int] = None,
) -> Invite: ) -> Invite:
"""|coro| """|coro|
@ -2046,6 +2045,10 @@ class Client:
``url`` parameter is now positional-only. ``url`` parameter is now positional-only.
.. versionchanged:: 2.1
The ``with_expiration`` parameter has been removed.
Parameters Parameters
----------- -----------
url: Union[:class:`.Invite`, :class:`str`] url: Union[:class:`.Invite`, :class:`str`]
@ -2054,11 +2057,6 @@ class Client:
Whether to include count information in the invite. This fills the Whether to include count information in the invite. This fills the
:attr:`.Invite.approximate_member_count` and :attr:`.Invite.approximate_presence_count` :attr:`.Invite.approximate_member_count` and :attr:`.Invite.approximate_presence_count`
fields. fields.
with_expiration: :class:`bool`
Whether to include the expiration date of the invite. This fills the
:attr:`.Invite.expires_at` field.
.. versionadded:: 2.0
scheduled_event_id: Optional[:class:`int`] scheduled_event_id: Optional[:class:`int`]
The ID of the scheduled event this invite is for. The ID of the scheduled event this invite is for.
@ -2094,7 +2092,6 @@ class Client:
data = await self.http.get_invite( data = await self.http.get_invite(
resolved.code, resolved.code,
with_counts=with_counts, with_counts=with_counts,
with_expiration=with_expiration,
guild_scheduled_event_id=scheduled_event_id, guild_scheduled_event_id=scheduled_event_id,
) )
return Invite.from_incomplete(state=self._connection, data=data) return Invite.from_incomplete(state=self._connection, data=data)

8
discord/http.py

@ -2390,18 +2390,19 @@ class HTTPClient:
max_uses: int = 0, max_uses: int = 0,
temporary: bool = False, temporary: bool = False,
unique: bool = True, unique: bool = True,
validate: Optional[str] = None,
target_type: Optional[invite.InviteTargetType] = None, target_type: Optional[invite.InviteTargetType] = None,
target_user_id: Optional[Snowflake] = None, target_user_id: Optional[Snowflake] = None,
target_application_id: Optional[Snowflake] = None, target_application_id: Optional[Snowflake] = None,
flags: int = 0,
) -> Response[invite.Invite]: ) -> Response[invite.Invite]:
payload = { payload = {
'max_age': max_age, 'max_age': max_age,
'max_uses': max_uses, 'max_uses': max_uses,
'target_type': target_type, 'target_type': target_type,
'temporary': temporary, 'temporary': temporary,
'validate': validate, 'flags': flags,
} }
if unique: if unique:
payload['unique'] = unique payload['unique'] = unique
if target_user_id: if target_user_id:
@ -2440,13 +2441,12 @@ class HTTPClient:
invite_id: str, invite_id: str,
*, *,
with_counts: bool = True, with_counts: bool = True,
with_expiration: bool = True,
guild_scheduled_event_id: Optional[Snowflake] = None, guild_scheduled_event_id: Optional[Snowflake] = None,
input_value: Optional[str] = None, input_value: Optional[str] = None,
) -> Response[invite.Invite]: ) -> Response[invite.Invite]:
params: Dict[str, Any] = { params: Dict[str, Any] = {
'with_counts': str(with_counts).lower(), 'with_counts': str(with_counts).lower(),
'with_expiration': str(with_expiration).lower(), 'with_expiration': 'true', # No longer exists
} }
if input_value: if input_value:
params['inputValue'] = input_value params['inputValue'] = input_value

22
discord/invite.py

@ -32,6 +32,7 @@ from .flags import InviteFlags
from .mixins import Hashable from .mixins import Hashable
from .object import Object from .object import Object
from .scheduled_event import ScheduledEvent from .scheduled_event import ScheduledEvent
from .stage_instance import StageInstance
from .utils import MISSING, _generate_session_id, _get_as_snowflake, parse_time, snowflake_time from .utils import MISSING, _generate_session_id, _get_as_snowflake, parse_time, snowflake_time
from .welcome_screen import WelcomeScreen from .welcome_screen import WelcomeScreen
@ -288,6 +289,9 @@ class PartialInviteGuild:
return None return None
return Asset._from_guild_image(self._state, self.id, self._splash, path='splashes') return Asset._from_guild_image(self._state, self.id, self._splash, path='splashes')
def _resolve_channel(self, channel_id: Optional[int], /):
return
class Invite(Hashable): class Invite(Hashable):
r"""Represents a Discord :class:`Guild` or :class:`abc.GuildChannel` invite. r"""Represents a Discord :class:`Guild` or :class:`abc.GuildChannel` invite.
@ -335,6 +339,10 @@ class Invite(Hashable):
If it's not in the table above then it is available by all methods. If it's not in the table above then it is available by all methods.
.. versionchanged:: 2.1
The ``revoked`` attribute has been removed.
Attributes Attributes
----------- -----------
max_age: Optional[:class:`int`] max_age: Optional[:class:`int`]
@ -348,8 +356,6 @@ class Invite(Hashable):
.. versionadded:: 2.0 .. versionadded:: 2.0
guild: Optional[Union[:class:`Guild`, :class:`Object`, :class:`PartialInviteGuild`]] guild: Optional[Union[:class:`Guild`, :class:`Object`, :class:`PartialInviteGuild`]]
The guild the invite is for. Can be ``None`` if not a guild invite. The guild the invite is for. Can be ``None`` if not a guild invite.
revoked: Optional[:class:`bool`]
Indicates if the invite has been revoked.
created_at: Optional[:class:`datetime.datetime`] created_at: Optional[:class:`datetime.datetime`]
An aware UTC datetime object denoting the time the invite was created. An aware UTC datetime object denoting the time the invite was created.
temporary: Optional[:class:`bool`] temporary: Optional[:class:`bool`]
@ -404,6 +410,7 @@ class Invite(Hashable):
.. versionadded:: 2.0 .. versionadded:: 2.0
.. note:: .. note::
This is only possibly ``True`` in accepted invite objects This is only possibly ``True`` in accepted invite objects
(i.e. the objects received from :meth:`accept` and :meth:`use`). (i.e. the objects received from :meth:`accept` and :meth:`use`).
show_verification_form: :class:`bool` show_verification_form: :class:`bool`
@ -412,6 +419,7 @@ class Invite(Hashable):
.. versionadded:: 2.0 .. versionadded:: 2.0
.. note:: .. note::
This is only possibly ``True`` in accepted invite objects This is only possibly ``True`` in accepted invite objects
(i.e. the objects received from :meth:`accept` and :meth:`use`). (i.e. the objects received from :meth:`accept` and :meth:`use`).
""" """
@ -420,7 +428,6 @@ class Invite(Hashable):
'max_age', 'max_age',
'code', 'code',
'guild', 'guild',
'revoked',
'created_at', 'created_at',
'uses', 'uses',
'temporary', 'temporary',
@ -436,6 +443,7 @@ class Invite(Hashable):
'expires_at', 'expires_at',
'scheduled_event', 'scheduled_event',
'scheduled_event_id', 'scheduled_event_id',
'stage_instance',
'_message', '_message',
'welcome_screen', 'welcome_screen',
'type', 'type',
@ -461,7 +469,6 @@ class Invite(Hashable):
self.max_age: Optional[int] = data.get('max_age') self.max_age: Optional[int] = data.get('max_age')
self.code: str = data['code'] self.code: str = data['code']
self.guild: Optional[InviteGuildType] = self._resolve_guild(data.get('guild'), guild) self.guild: Optional[InviteGuildType] = self._resolve_guild(data.get('guild'), guild)
self.revoked: Optional[bool] = data.get('revoked')
self.created_at: Optional[datetime.datetime] = parse_time(data.get('created_at')) self.created_at: Optional[datetime.datetime] = parse_time(data.get('created_at'))
self.temporary: Optional[bool] = data.get('temporary') self.temporary: Optional[bool] = data.get('temporary')
self.uses: Optional[int] = data.get('uses') self.uses: Optional[int] = data.get('uses')
@ -510,6 +517,11 @@ class Invite(Hashable):
) )
self.scheduled_event_id: Optional[int] = self.scheduled_event.id if self.scheduled_event else None self.scheduled_event_id: Optional[int] = self.scheduled_event.id if self.scheduled_event else None
stage_instance = data.get('stage_instance')
self.stage_instance: Optional[StageInstance] = (
StageInstance.from_invite(self, stage_instance) if stage_instance else None
)
# Only present on accepted invites # Only present on accepted invites
self.new_member: bool = data.get('new_member', False) self.new_member: bool = data.get('new_member', False)
self.show_verification_form: bool = data.get('show_verification_form', False) self.show_verification_form: bool = data.get('show_verification_form', False)
@ -537,7 +549,7 @@ class Invite(Hashable):
if channel_data and channel_data.get('type') == ChannelType.private.value: if channel_data and channel_data.get('type') == ChannelType.private.value:
channel_data['recipients'] = [data['inviter']] if 'inviter' in data else [] channel_data['recipients'] = [data['inviter']] if 'inviter' in data else []
channel = PartialInviteChannel(channel_data, state) channel = PartialInviteChannel(channel_data, state)
channel = state.get_channel(getattr(channel, 'id', None)) or channel channel = (state.get_channel(channel.id) or channel) if channel else None
return cls(state=state, data=data, guild=guild, channel=channel, welcome_screen=welcome_screen, message=message) # type: ignore return cls(state=state, data=data, guild=guild, channel=channel, welcome_screen=welcome_screen, message=message) # type: ignore

88
discord/stage_instance.py

@ -24,7 +24,7 @@ DEALINGS IN THE SOFTWARE.
from __future__ import annotations from __future__ import annotations
from typing import Optional, TYPE_CHECKING from typing import List, Optional, TYPE_CHECKING
from .utils import MISSING, cached_slot_property, _get_as_snowflake from .utils import MISSING, cached_slot_property, _get_as_snowflake
from .mixins import Hashable from .mixins import Hashable
@ -37,11 +37,15 @@ __all__ = (
# fmt: on # fmt: on
if TYPE_CHECKING: if TYPE_CHECKING:
from .types.channel import StageInstance as StageInstancePayload from typing_extensions import Self
from .types.channel import StageInstance as StageInstancePayload, InviteStageInstance as InviteStageInstancePayload
from .state import ConnectionState from .state import ConnectionState
from .channel import StageChannel from .channel import StageChannel
from .guild import Guild from .guild import Guild
from .scheduled_event import ScheduledEvent from .scheduled_event import ScheduledEvent
from .invite import Invite
from .member import Member
class StageInstance(Hashable): class StageInstance(Hashable):
@ -77,8 +81,12 @@ class StageInstance(Hashable):
The privacy level of the stage instance. The privacy level of the stage instance.
discoverable_disabled: :class:`bool` discoverable_disabled: :class:`bool`
Whether discoverability for the stage instance is disabled. Whether discoverability for the stage instance is disabled.
invite_code: Optional[:class:`str`]
The invite code of the stage instance, if public.
.. versionadded:: 2.1
scheduled_event_id: Optional[:class:`int`] scheduled_event_id: Optional[:class:`int`]
The ID of scheduled event that belongs to the stage instance if any. The ID of the scheduled event that belongs to the stage instance, if any.
.. versionadded:: 2.0 .. versionadded:: 2.0
""" """
@ -91,44 +99,104 @@ class StageInstance(Hashable):
'topic', 'topic',
'privacy_level', 'privacy_level',
'discoverable_disabled', 'discoverable_disabled',
'invite_code',
'scheduled_event_id', 'scheduled_event_id',
'_cs_channel', '_members',
'_cs_scheduled_event', '_participant_count',
) )
def __init__(self, *, state: ConnectionState, guild: Guild, data: StageInstancePayload) -> None: def __init__(self, *, state: ConnectionState, guild: Guild, data: StageInstancePayload) -> None:
self._state: ConnectionState = state self._state: ConnectionState = state
self.guild: Guild = guild self.guild: Guild = guild
self._members: Optional[List[Member]] = None
self._participant_count: Optional[int] = None
self._update(data) self._update(data)
def _update(self, data: StageInstancePayload) -> None: def _update(self, data: StageInstancePayload, /) -> None:
self.id: int = int(data['id']) self.id: int = int(data['id'])
self.channel_id: int = int(data['channel_id']) self.channel_id: int = int(data['channel_id'])
self.topic: str = data['topic'] self.topic: str = data['topic']
self.privacy_level: PrivacyLevel = try_enum(PrivacyLevel, data['privacy_level']) self.privacy_level: PrivacyLevel = try_enum(PrivacyLevel, data['privacy_level'])
self.discoverable_disabled: bool = data.get('discoverable_disabled', False) self.discoverable_disabled: bool = data.get('discoverable_disabled', False)
self.invite_code: Optional[str] = data.get('invite_code')
self.scheduled_event_id: Optional[int] = _get_as_snowflake(data, 'guild_scheduled_event_id') self.scheduled_event_id: Optional[int] = _get_as_snowflake(data, 'guild_scheduled_event_id')
@staticmethod
def _resolve_stage_instance_id(invite: Invite) -> int:
try:
return invite.channel.instance.id # type: ignore
except AttributeError:
# This is a lie, but it doesn't matter
return invite.channel.id # type: ignore
@classmethod
def from_invite(cls, invite: Invite, data: InviteStageInstancePayload, /) -> Self:
state = invite._state
payload: StageInstancePayload = {
'id': cls._resolve_stage_instance_id(invite),
'guild_id': invite.guild.id, # type: ignore # Will always be defined
'channel_id': invite.channel.id, # type: ignore # Will always be defined
'topic': data['topic'],
'privacy_level': PrivacyLevel.public.value,
'discoverable_disabled': False,
'invite_code': invite.code,
'guild_scheduled_event_id': invite.scheduled_event.id if invite.scheduled_event else None,
}
self = cls(state=state, guild=invite.guild, data=payload) # type: ignore # Guild may be wrong type
self._members = [Member(data=mdata, state=state, guild=invite.guild) for mdata in data['members']] # type: ignore # Guild may be wrong type
self._participant_count = data.get('participant_count', len(self._members))
return self
def __repr__(self) -> str: def __repr__(self) -> str:
return f'<StageInstance id={self.id} guild={self.guild!r} channel_id={self.channel_id} topic={self.topic!r}>' return f'<StageInstance id={self.id} guild={self.guild!r} channel_id={self.channel_id} topic={self.topic!r}>'
@property
def invite_url(self) -> Optional[str]:
"""Optional[:class:`str`]: The stage instance's invite URL, if public.
.. versionadded:: 2.1
"""
if self.invite_code is None:
return None
return f'https://discord.gg/{self.invite_code}'
@property @property
def discoverable(self) -> bool: def discoverable(self) -> bool:
""":class:`bool`: Whether the stage instance is discoverable.""" """:class:`bool`: Whether the stage instance is discoverable."""
return not self.discoverable_disabled return not self.discoverable_disabled
@cached_slot_property('_cs_channel') @property
def channel(self) -> Optional[StageChannel]: def channel(self) -> Optional[StageChannel]:
"""Optional[:class:`StageChannel`]: The channel that stage instance is running in.""" """Optional[:class:`StageChannel`]: The channel that stage instance is running in."""
# The returned channel will always be a StageChannel or None # The returned channel will always be a StageChannel or None
return self._state.get_channel(self.channel_id) # type: ignore return self.guild._resolve_channel(self.channel_id) # type: ignore
@cached_slot_property('_cs_scheduled_event') @property
def scheduled_event(self) -> Optional[ScheduledEvent]: def scheduled_event(self) -> Optional[ScheduledEvent]:
"""Optional[:class:`ScheduledEvent`]: The scheduled event that belongs to the stage instance.""" """Optional[:class:`ScheduledEvent`]: The scheduled event that belongs to the stage instance."""
# Guild.get_scheduled_event() expects an int, we are passing Optional[int] # Guild.get_scheduled_event() expects an int, we are passing Optional[int]
return self.guild.get_scheduled_event(self.scheduled_event_id) # type: ignore return self.guild.get_scheduled_event(self.scheduled_event_id) # type: ignore
@property
def speakers(self) -> List[Member]:
"""List[:class:`Member`]: The members that are speaking in the stage instance.
.. versionadded:: 2.1
"""
if self._members is not None or self.channel is None:
return self._members or []
return self.channel.speakers
@property
def participant_count(self) -> int:
""":class:`int`: The number of participants in the stage instance.
.. versionadded:: 2.1
"""
if self._participant_count is not None or self.channel is None:
return self._participant_count or 0
return len(self.channel.voice_states)
async def edit( async def edit(
self, self,
*, *,
@ -161,10 +229,8 @@ class StageInstance(Hashable):
Editing a stage instance failed. Editing a stage instance failed.
""" """
payload = {} payload = {}
if topic is not MISSING: if topic is not MISSING:
payload['topic'] = topic payload['topic'] = topic
if privacy_level is not MISSING: if privacy_level is not MISSING:
if not isinstance(privacy_level, PrivacyLevel): if not isinstance(privacy_level, PrivacyLevel):
raise TypeError('privacy_level field must be of type PrivacyLevel') raise TypeError('privacy_level field must be of type PrivacyLevel')

9
discord/types/channel.py

@ -27,6 +27,7 @@ from typing_extensions import NotRequired
from .user import PartialUser from .user import PartialUser
from .snowflake import Snowflake from .snowflake import Snowflake
from .guild import MemberWithUser
from .threads import ThreadMetadata, ThreadMember, ThreadArchiveDuration, ThreadType from .threads import ThreadMetadata, ThreadMember, ThreadArchiveDuration, ThreadType
@ -195,4 +196,12 @@ class StageInstance(TypedDict):
topic: str topic: str
privacy_level: PrivacyLevel privacy_level: PrivacyLevel
discoverable_disabled: bool discoverable_disabled: bool
invite_code: Optional[str]
guild_scheduled_event_id: Optional[int] guild_scheduled_event_id: Optional[int]
class InviteStageInstance(TypedDict):
members: List[MemberWithUser]
participant_count: int
speaker_count: int
topic: str

16
discord/types/guild.py

@ -136,8 +136,20 @@ class UserGuild(BaseGuild):
approximate_presence_count: NotRequired[int] approximate_presence_count: NotRequired[int]
class InviteGuild(Guild, total=False): class InviteGuild(TypedDict):
welcome_screen: WelcomeScreen id: Snowflake
name: str
icon: Optional[str]
description: Optional[str]
banner: Optional[str]
splash: Optional[str]
verification_level: VerificationLevel
features: List[str]
vanity_url_code: Optional[str]
premium_subscription_count: NotRequired[int]
nsfw: bool
nsfw_level: NSFWLevel
welcome_screen: NotRequired[WelcomeScreen]
class GuildWithCounts(Guild, _GuildCounts): class GuildWithCounts(Guild, _GuildCounts):

73
discord/types/invite.py

@ -27,67 +27,78 @@ from __future__ import annotations
from typing import Literal, Optional, TypedDict, Union from typing import Literal, Optional, TypedDict, Union
from typing_extensions import NotRequired from typing_extensions import NotRequired
from .application import PartialApplication
from .channel import InviteStageInstance, PartialChannel
from .guild import InviteGuild, _GuildCounts
from .scheduled_event import GuildScheduledEvent from .scheduled_event import GuildScheduledEvent
from .snowflake import Snowflake from .snowflake import Snowflake
from .guild import InviteGuild, _GuildCounts
from .channel import PartialChannel
from .user import PartialUser from .user import PartialUser
from .application import PartialApplication
InviteTargetType = Literal[1, 2] InviteTargetType = Literal[1, 2]
class _InviteMetadata(TypedDict, total=False): class _InviteMetadata(TypedDict):
uses: int uses: NotRequired[int]
max_uses: int max_uses: NotRequired[int]
max_age: int max_age: NotRequired[int]
temporary: bool temporary: NotRequired[bool]
created_at: str created_at: str
expires_at: Optional[str]
class VanityInvite(_InviteMetadata): class _InviteTargetType(TypedDict, total=False):
target_type: InviteTargetType
target_user: PartialUser
target_application: PartialApplication
class VanityInvite:
code: Optional[str] code: Optional[str]
revoked: NotRequired[bool] uses: int
class IncompleteInvite(_InviteMetadata): class PartialInvite(_InviteTargetType):
code: str code: str
channel: PartialChannel type: Literal[0, 1, 2]
channel: Optional[PartialChannel]
guild_id: NotRequired[Snowflake]
guild: NotRequired[InviteGuild]
inviter: NotRequired[PartialUser]
flags: NotRequired[int]
expires_at: Optional[str]
guild_scheduled_event: NotRequired[GuildScheduledEvent]
stage_instance: NotRequired[InviteStageInstance]
class Invite(IncompleteInvite, total=False): class InviteWithCounts(PartialInvite, _GuildCounts):
guild: InviteGuild ...
inviter: PartialUser
target_user: PartialUser
target_type: InviteTargetType
target_application: PartialApplication
guild_scheduled_event: GuildScheduledEvent
class InviteWithCounts(Invite, _GuildCounts): class InviteWithMetadata(PartialInvite, _InviteMetadata):
... ...
class GatewayInviteCreate(TypedDict): Invite = Union[PartialInvite, InviteWithCounts, InviteWithMetadata]
channel_id: Snowflake
class GatewayInviteCreate(_InviteTargetType):
code: str code: str
type: Literal[0]
channel_id: Snowflake
guild_id: Snowflake
inviter: NotRequired[PartialUser]
expires_at: Optional[str]
created_at: str created_at: str
uses: int
max_age: int max_age: int
max_uses: int max_uses: int
temporary: bool temporary: bool
uses: bool flags: NotRequired[int]
guild_id: Snowflake
inviter: NotRequired[PartialUser]
target_type: NotRequired[InviteTargetType]
target_user: NotRequired[PartialUser]
target_application: NotRequired[PartialApplication]
class GatewayInviteDelete(TypedDict): class GatewayInviteDelete(TypedDict):
channel_id: Snowflake
code: str code: str
guild_id: NotRequired[Snowflake] channel_id: Snowflake
guild_id: Snowflake
GatewayInvite = Union[GatewayInviteCreate, GatewayInviteDelete] GatewayInvite = Union[GatewayInviteCreate, GatewayInviteDelete]

Loading…
Cancel
Save