Skip to content

Commit bdd3f16

Browse files
committed
feat: gateway capabilities
1 parent 25a1aee commit bdd3f16

5 files changed

Lines changed: 62 additions & 1 deletion

File tree

discord/abc.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,10 @@ def __init__(
346346
): ...
347347

348348
def __str__(self) -> str:
349+
flags = getattr(self, "flags", None)
350+
if flags is not None and getattr(flags, "obfuscated", False):
351+
return f"Obfuscated Channel ({self.id})"
352+
349353
return self.name
350354

351355
@property

discord/client.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,10 @@ class Client:
168168
If not given, defaults to a regularly constructed :class:`Intents` class.
169169
170170
.. versionadded:: 1.5
171+
capabilities: :class:`GatewayCapabilities`
172+
Gateway capabilities to include with the IDENTIFY payload. Defaults to
173+
:meth:`GatewayCapabilities.none`. These are mostly undocumented and may not
174+
be supported for bot accounts.
171175
member_cache_flags: :class:`MemberCacheFlags`
172176
Allows for finer control over how the library caches members.
173177
If not given, defaults to cache as much as possible with the

discord/flags.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
"MessageFlags",
3535
"AttachmentFlags",
3636
"PublicUserFlags",
37+
"GatewayCapabilities",
3738
"Intents",
3839
"MemberCacheFlags",
3940
"ApplicationFlags",
@@ -587,6 +588,36 @@ def all(self) -> list[UserFlags]:
587588
]
588589

589590

591+
@fill_with_flags()
592+
class GatewayCapabilities(BaseFlags):
593+
"""Wraps Discord gateway capabilities.
594+
595+
These bits are mostly undocumented and meant for specialized clients. They are
596+
sent with the IDENTIFY payload as the ``capabilities`` field.
597+
598+
Attributes
599+
----------
600+
value: :class:`int`
601+
The raw capability value. Prefer toggling via the provided attributes.
602+
"""
603+
604+
__slots__ = ()
605+
606+
@classmethod
607+
def none(cls) -> GatewayCapabilities:
608+
"""Creates a :class:`GatewayCapabilities` instance with no bits enabled."""
609+
610+
self = cls.__new__(cls)
611+
self.value = cls.DEFAULT_VALUE
612+
return self
613+
614+
@flag_value
615+
def obfuscated_channels(self):
616+
""":class:`bool`: Obfuscates channel identifiers in gateway events."""
617+
618+
return 1 << 15
619+
620+
590621
@fill_with_flags()
591622
class Intents(BaseFlags):
592623
r"""Wraps up a Discord gateway intent flag.
@@ -1585,6 +1616,12 @@ def hide_media_download_options(self):
15851616
"""
15861617
return 1 << 15
15871618

1619+
@flag_value
1620+
def obfuscated(self):
1621+
""":class:`bool`: Returns ``True`` if the channel is obfuscated by the gateway."""
1622+
1623+
return 1 << 17
1624+
15881625

15891626
@fill_with_flags()
15901627
class AttachmentFlags(BaseFlags):

discord/gateway.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,7 @@ async def from_client(
361361
ws.session_id = session
362362
ws.sequence = sequence
363363
ws._max_heartbeat_timeout = client._connection.heartbeat_timeout
364+
ws.capabilities = client._connection.capabilities.value
364365

365366
if client._enable_debug_events:
366367
ws.send = ws.debug_send
@@ -420,6 +421,9 @@ async def identify(self):
420421
},
421422
"compress": True,
422423
"large_threshold": 250,
424+
"capabilities": (
425+
self.capabilities if hasattr(self, "capabilities") else 0
426+
),
423427
},
424428
}
425429

discord/state.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
from .channel import _channel_factory
5252
from .emoji import AppEmoji, GuildEmoji
5353
from .enums import ChannelType, InteractionType, ScheduledEventStatus, Status, try_enum
54-
from .flags import ApplicationFlags, Intents, MemberCacheFlags
54+
from .flags import ApplicationFlags, GatewayCapabilities, Intents, MemberCacheFlags
5555
from .guild import Guild
5656
from .integrations import _integration_factory
5757
from .interactions import Interaction
@@ -248,6 +248,18 @@ def __init__(
248248
self._status: str | None = status
249249
self._intents: Intents = intents
250250

251+
capabilities = options.get("capabilities")
252+
if capabilities is None:
253+
capabilities = GatewayCapabilities.none()
254+
elif isinstance(capabilities, int):
255+
capabilities = GatewayCapabilities._from_value(capabilities)
256+
elif not isinstance(capabilities, GatewayCapabilities):
257+
raise TypeError(
258+
"capabilities parameter must be GatewayCapabilities or int."
259+
)
260+
261+
self.capabilities: GatewayCapabilities = capabilities
262+
251263
if not intents.members or cache_flags._empty:
252264
self.store_user = self.create_user # type: ignore
253265
self.deref_user = self.deref_user_no_intents # type: ignore

0 commit comments

Comments
 (0)