Browse Source

Add support for guest invites

pull/10220/head
Soheab_ 2 weeks ago
parent
commit
ca13ea342a
  1. 13
      discord/abc.py
  2. 57
      discord/flags.py
  3. 4
      discord/http.py
  4. 11
      discord/invite.py
  5. 3
      discord/member.py
  6. 2
      discord/types/invite.py
  7. 2
      discord/types/member.py
  8. 8
      docs/api.rst

13
discord/abc.py

@ -60,6 +60,7 @@ from .http import handle_message_parameters
from .voice_client import VoiceClient, VoiceProtocol from .voice_client import VoiceClient, VoiceProtocol
from .sticker import GuildSticker, StickerItem from .sticker import GuildSticker, StickerItem
from . import utils from . import utils
from .flags import GuildInviteFlags
__all__ = ( __all__ = (
'Snowflake', 'Snowflake',
@ -1257,6 +1258,7 @@ class GuildChannel:
target_type: Optional[InviteTarget] = None, target_type: Optional[InviteTarget] = None,
target_user: Optional[User] = None, target_user: Optional[User] = None,
target_application_id: Optional[int] = None, target_application_id: Optional[int] = None,
guest_invite: bool = False,
) -> Invite: ) -> Invite:
"""|coro| """|coro|
@ -1295,6 +1297,12 @@ class GuildChannel:
The id of the embedded application for the invite, required if ``target_type`` is :attr:`.InviteTarget.embedded_application`. The id of the embedded application for the invite, required if ``target_type`` is :attr:`.InviteTarget.embedded_application`.
.. versionadded:: 2.0 .. versionadded:: 2.0
guest_invite: :class:`bool`
Whether the invite is a guest invite.
This is only available to guilds that contain ``GUESTS_ENABLED`` in :attr:`.Guild.features`.
.. versionadded:: 2.6
Raises Raises
------- -------
@ -1312,6 +1320,10 @@ class GuildChannel:
if target_type is InviteTarget.unknown: if target_type is InviteTarget.unknown:
raise ValueError('Cannot create invite with an unknown target type') raise ValueError('Cannot create invite with an unknown target type')
flags = GuildInviteFlags._from_value(0)
if guest_invite:
flags.is_guest_invite = True
data = await self._state.http.create_invite( data = await self._state.http.create_invite(
self.id, self.id,
reason=reason, reason=reason,
@ -1322,6 +1334,7 @@ class GuildChannel:
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, target_application_id=target_application_id,
flags=flags.value,
) )
return Invite.from_incomplete(data=data, state=self._state) return Invite.from_incomplete(data=data, state=self._state)

57
discord/flags.py

@ -64,6 +64,7 @@ __all__ = (
'AppInstallationType', 'AppInstallationType',
'SKUFlags', 'SKUFlags',
'EmbedFlags', 'EmbedFlags',
'GuildInviteFlags',
) )
BF = TypeVar('BF', bound='BaseFlags') BF = TypeVar('BF', bound='BaseFlags')
@ -2397,3 +2398,59 @@ class EmbedFlags(BaseFlags):
longer displayed. longer displayed.
""" """
return 1 << 5 return 1 << 5
class GuildInviteFlags(BaseFlags):
r"""Wraps up the Discord Guild Invite flags
.. versionadded:: 2.6
.. container:: operations
.. describe:: x == y
Checks if two GuildInviteFlags are equal.
.. describe:: x != y
Checks if two GuildInviteFlags are not equal.
.. describe:: x | y, x |= y
Returns a GuildInviteFlags instance with all enabled flags from
both x and y.
.. describe:: x ^ y, x ^= y
Returns a GuildInviteFlags instance with only flags enabled on
only one of x or y, not on both.
.. describe:: ~x
Returns a GuildInviteFlags instance with all flags inverted from x.
.. describe:: hash(x)
Returns the flag's hash.
.. describe:: iter(x)
Returns an iterator of ``(name, value)`` pairs. This allows it
to be, for example, constructed as a dict or a list of pairs.
Note that aliases are not shown.
.. describe:: bool(b)
Returns whether any flag is set to ``True``.
Attributes
----------
value: :class:`int`
The raw value. You should query flags via the properties
rather than using this raw value.
"""
@flag_value
def is_guest_invite(self):
""":class:`bool`: Returns ``True`` if this is a guest invite for a voice channel."""
return 1 << 0

4
discord/http.py

@ -1834,6 +1834,7 @@ class HTTPClient:
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: Optional[int] = None,
) -> Response[invite.Invite]: ) -> Response[invite.Invite]:
r = Route('POST', '/channels/{channel_id}/invites', channel_id=channel_id) r = Route('POST', '/channels/{channel_id}/invites', channel_id=channel_id)
payload = { payload = {
@ -1852,6 +1853,9 @@ class HTTPClient:
if target_application_id: if target_application_id:
payload['target_application_id'] = str(target_application_id) payload['target_application_id'] = str(target_application_id)
if flags is not None:
payload['flags'] = flags
return self.request(r, reason=reason, json=payload) return self.request(r, reason=reason, json=payload)
def get_invite( def get_invite(

11
discord/invite.py

@ -32,6 +32,7 @@ from .mixins import Hashable
from .enums import ChannelType, NSFWLevel, VerificationLevel, InviteTarget, InviteType, try_enum from .enums import ChannelType, NSFWLevel, VerificationLevel, InviteTarget, InviteType, try_enum
from .appinfo import PartialAppInfo from .appinfo import PartialAppInfo
from .scheduled_event import ScheduledEvent from .scheduled_event import ScheduledEvent
from .flags import GuildInviteFlags
__all__ = ( __all__ = (
'PartialInviteChannel', 'PartialInviteChannel',
@ -379,6 +380,7 @@ class Invite(Hashable):
'scheduled_event', 'scheduled_event',
'scheduled_event_id', 'scheduled_event_id',
'type', 'type',
'_flags',
) )
BASE = 'https://discord.gg' BASE = 'https://discord.gg'
@ -432,6 +434,7 @@ class Invite(Hashable):
else None else None
) )
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
self._flags: int = data.get('flags', 0)
@classmethod @classmethod
def from_incomplete(cls, *, state: ConnectionState, data: InvitePayload) -> Self: def from_incomplete(cls, *, state: ConnectionState, data: InvitePayload) -> Self:
@ -523,6 +526,14 @@ class Invite(Hashable):
url += '?event=' + str(self.scheduled_event_id) url += '?event=' + str(self.scheduled_event_id)
return url return url
@property
def flags(self) -> GuildInviteFlags:
""":class:`GuildInviteFlags`: Returns the flags for this guild invite.
.. versionadded:: 2.6
"""
return GuildInviteFlags._from_value(self._flags)
def set_scheduled_event(self, scheduled_event: Snowflake, /) -> Self: def set_scheduled_event(self, scheduled_event: Snowflake, /) -> Self:
"""Sets the scheduled event for this invite. """Sets the scheduled event for this invite.

3
discord/member.py

@ -238,7 +238,8 @@ class Member(discord.abc.Messageable, _UserTag):
---------- ----------
joined_at: Optional[:class:`datetime.datetime`] joined_at: Optional[:class:`datetime.datetime`]
An aware datetime object that specifies the date and time in UTC that the member joined the guild. An aware datetime object that specifies the date and time in UTC that the member joined the guild.
If the member left and rejoined the guild, this will be the latest date. In certain cases, this can be ``None``. If the member left and rejoined the guild, this will be the latest date.
This can be ``None``, such as when the member is a guest.
activities: Tuple[Union[:class:`BaseActivity`, :class:`Spotify`]] activities: Tuple[Union[:class:`BaseActivity`, :class:`Spotify`]]
The activities that the user is currently doing. The activities that the user is currently doing.

2
discord/types/invite.py

@ -65,6 +65,7 @@ class Invite(IncompleteInvite, total=False):
target_application: PartialAppInfo target_application: PartialAppInfo
guild_scheduled_event: GuildScheduledEvent guild_scheduled_event: GuildScheduledEvent
type: InviteType type: InviteType
flags: NotRequired[int]
class InviteWithCounts(Invite, _GuildPreviewUnique): class InviteWithCounts(Invite, _GuildPreviewUnique):
@ -84,6 +85,7 @@ class GatewayInviteCreate(TypedDict):
target_type: NotRequired[InviteTargetType] target_type: NotRequired[InviteTargetType]
target_user: NotRequired[PartialUser] target_user: NotRequired[PartialUser]
target_application: NotRequired[PartialAppInfo] target_application: NotRequired[PartialAppInfo]
flags: NotRequired[int]
class GatewayInviteDelete(TypedDict): class GatewayInviteDelete(TypedDict):

2
discord/types/member.py

@ -34,7 +34,7 @@ class Nickname(TypedDict):
class PartialMember(TypedDict): class PartialMember(TypedDict):
roles: SnowflakeList roles: SnowflakeList
joined_at: str joined_at: Optional[str] # null if guest
deaf: bool deaf: bool
mute: bool mute: bool
flags: int flags: int

8
docs/api.rst

@ -5734,6 +5734,14 @@ EmbedFlags
.. autoclass:: EmbedFlags() .. autoclass:: EmbedFlags()
:members: :members:
GuildInviteFlags
~~~~~~~~~~~~~~~~
.. attributetable:: GuildInviteFlags
.. autoclass:: GuildInviteFlags(
:members:
ForumTag ForumTag
~~~~~~~~~ ~~~~~~~~~

Loading…
Cancel
Save