Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions discord/abc.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
from .voice_client import VoiceClient, VoiceProtocol
from .sticker import GuildSticker, StickerItem
from . import utils
from .flags import InviteFlags

__all__ = (
'Snowflake',
Expand All @@ -73,7 +74,7 @@
T = TypeVar('T', bound=VoiceProtocol)

if TYPE_CHECKING:
from typing_extensions import Self

Check warning on line 77 in discord/abc.py

View workflow job for this annotation

GitHub Actions / check 3.x

Import "typing_extensions" could not be resolved from source (reportMissingModuleSource)

from .client import Client
from .user import ClientUser
Expand Down Expand Up @@ -1257,6 +1258,7 @@
target_type: Optional[InviteTarget] = None,
target_user: Optional[User] = None,
target_application_id: Optional[int] = None,
guest: bool = False,
) -> Invite:
"""|coro|

Expand Down Expand Up @@ -1295,6 +1297,10 @@
The id of the embedded application for the invite, required if ``target_type`` is :attr:`.InviteTarget.embedded_application`.

.. versionadded:: 2.0
guest: :class:`bool`
Whether the invite is a guest invite.

.. versionadded:: 2.6

Raises
-------
Expand All @@ -1312,6 +1318,11 @@
if target_type is InviteTarget.unknown:
raise ValueError('Cannot create invite with an unknown target type')

flags: Optional[InviteFlags] = None
if guest:
flags = InviteFlags._from_value(0)
flags.guest = True

data = await self._state.http.create_invite(
self.id,
reason=reason,
Expand All @@ -1322,6 +1333,7 @@
target_type=target_type.value if target_type else None,
target_user_id=target_user.id if target_user else None,
target_application_id=target_application_id,
flags=flags.value if flags else None,
)
return Invite.from_incomplete(data=data, state=self._state)

Expand Down
11 changes: 9 additions & 2 deletions discord/audit_logs.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,8 @@ def _transform_applied_forum_tags(entry: AuditLogEntry, data: List[Snowflake]) -
return [Object(id=tag_id, type=ForumTag) for tag_id in data]


def _transform_overloaded_flags(entry: AuditLogEntry, data: int) -> Union[int, flags.ChannelFlags]:
# The `flags` key is definitely overloaded. Right now it's for channels and threads but
def _transform_overloaded_flags(entry: AuditLogEntry, data: int) -> Union[int, flags.ChannelFlags, flags.InviteFlags]:
# The `flags` key is definitely overloaded. Right now it's for channels, threads and invites but
# I am aware of `member.flags` and `user.flags` existing. However, this does not impact audit logs
# at the moment but better safe than sorry.
channel_audit_log_types = (
Expand All @@ -157,9 +157,16 @@ def _transform_overloaded_flags(entry: AuditLogEntry, data: int) -> Union[int, f
enums.AuditLogAction.thread_update,
enums.AuditLogAction.thread_delete,
)
invite_audit_log_types = (
enums.AuditLogAction.invite_create,
enums.AuditLogAction.invite_update,
enums.AuditLogAction.invite_delete,
)

if entry.action in channel_audit_log_types:
return flags.ChannelFlags._from_value(data)
elif entry.action in invite_audit_log_types:
return flags.InviteFlags._from_value(data)
return data


Expand Down
57 changes: 57 additions & 0 deletions discord/flags.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
'AppInstallationType',
'SKUFlags',
'EmbedFlags',
'InviteFlags',
)

BF = TypeVar('BF', bound='BaseFlags')
Expand Down Expand Up @@ -2397,3 +2398,59 @@ def content_inventory_entry(self):
longer displayed.
"""
return 1 << 5


class InviteFlags(BaseFlags):
r"""Wraps up the Discord Invite flags

.. versionadded:: 2.6

.. container:: operations

.. describe:: x == y

Checks if two InviteFlags are equal.

.. describe:: x != y

Checks if two InviteFlags are not equal.

.. describe:: x | y, x |= y

Returns a InviteFlags instance with all enabled flags from
both x and y.

.. describe:: x ^ y, x ^= y

Returns a InviteFlags instance with only flags enabled on
only one of x or y, not on both.

.. describe:: ~x

Returns a InviteFlags 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 guest(self):
""":class:`bool`: Returns ``True`` if this is a guest invite for a voice channel."""
return 1 << 0
4 changes: 4 additions & 0 deletions discord/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -1834,6 +1834,7 @@ def create_invite(
target_type: Optional[invite.InviteTargetType] = None,
target_user_id: Optional[Snowflake] = None,
target_application_id: Optional[Snowflake] = None,
flags: Optional[int] = None,
) -> Response[invite.Invite]:
r = Route('POST', '/channels/{channel_id}/invites', channel_id=channel_id)
payload = {
Expand All @@ -1852,6 +1853,9 @@ def create_invite(
if target_application_id:
payload['target_application_id'] = str(target_application_id)

if flags:
payload['flags'] = flags

return self.request(r, reason=reason, json=payload)

def get_invite(
Expand Down
11 changes: 11 additions & 0 deletions discord/invite.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
from .enums import ChannelType, NSFWLevel, VerificationLevel, InviteTarget, InviteType, try_enum
from .appinfo import PartialAppInfo
from .scheduled_event import ScheduledEvent
from .flags import InviteFlags

__all__ = (
'PartialInviteChannel',
Expand Down Expand Up @@ -379,6 +380,7 @@ class Invite(Hashable):
'scheduled_event',
'scheduled_event_id',
'type',
'_flags',
)

BASE = 'https://discord.gg'
Expand Down Expand Up @@ -432,6 +434,7 @@ def __init__(
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
def from_incomplete(cls, *, state: ConnectionState, data: InvitePayload) -> Self:
Expand Down Expand Up @@ -523,6 +526,14 @@ def url(self) -> str:
url += '?event=' + str(self.scheduled_event_id)
return url

@property
def flags(self) -> InviteFlags:
""":class:`InviteFlags`: Returns the flags for this invite.

.. versionadded:: 2.6
"""
return InviteFlags._from_value(self._flags)

def set_scheduled_event(self, scheduled_event: Snowflake, /) -> Self:
"""Sets the scheduled event for this invite.

Expand Down
3 changes: 2 additions & 1 deletion discord/member.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,8 @@ class Member(discord.abc.Messageable, _UserTag):
----------
joined_at: Optional[:class:`datetime.datetime`]
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`]]
The activities that the user is currently doing.

Expand Down
2 changes: 2 additions & 0 deletions discord/types/invite.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ class Invite(IncompleteInvite, total=False):
target_application: PartialAppInfo
guild_scheduled_event: GuildScheduledEvent
type: InviteType
flags: NotRequired[int]


class InviteWithCounts(Invite, _GuildPreviewUnique):
Expand All @@ -84,6 +85,7 @@ class GatewayInviteCreate(TypedDict):
target_type: NotRequired[InviteTargetType]
target_user: NotRequired[PartialUser]
target_application: NotRequired[PartialAppInfo]
flags: NotRequired[int]


class GatewayInviteDelete(TypedDict):
Expand Down
2 changes: 1 addition & 1 deletion discord/types/member.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class Nickname(TypedDict):

class PartialMember(TypedDict):
roles: SnowflakeList
joined_at: str
joined_at: Optional[str] # null if guest
deaf: bool
mute: bool
flags: int
Expand Down
16 changes: 13 additions & 3 deletions docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2517,6 +2517,7 @@ of :class:`enum.Enum`.
- :attr:`~AuditLogDiff.channel`
- :attr:`~AuditLogDiff.uses`
- :attr:`~AuditLogDiff.max_uses`
- :attr:`~AuditLogDiff.flags`

.. attribute:: invite_update

Expand All @@ -2541,6 +2542,7 @@ of :class:`enum.Enum`.
- :attr:`~AuditLogDiff.channel`
- :attr:`~AuditLogDiff.uses`
- :attr:`~AuditLogDiff.max_uses`
- :attr:`~AuditLogDiff.flags`

.. attribute:: webhook_create

Expand Down Expand Up @@ -4552,11 +4554,11 @@ AuditLogDiff

.. attribute:: flags

The channel flags associated with this thread or forum post.
The flags associated with this thread, forum post or invite.

See also :attr:`ForumChannel.flags` and :attr:`Thread.flags`
See also :attr:`ForumChannel.flags`, :attr:`Thread.flags` and :attr:`Invite.flags`

:type: :class:`ChannelFlags`
:type: Union[:class:`ChannelFlags`, :class:`InviteFlags`]

.. attribute:: default_thread_slowmode_delay

Expand Down Expand Up @@ -5734,6 +5736,14 @@ EmbedFlags
.. autoclass:: EmbedFlags()
:members:

InviteFlags
~~~~~~~~~~~~~~~~

.. attributetable:: InviteFlags

.. autoclass:: InviteFlags()
:members:

ForumTag
~~~~~~~~~

Expand Down
Loading