Skip to content

feat: add Tag to user properties #2789

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
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
25 changes: 25 additions & 0 deletions discord/asset.py
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,31 @@ def _from_scheduled_event_image(
animated=False,
)

@classmethod
def _from_user_tag(cls, state, guild_id: int, badge_id: str) -> Asset:
"""Creates an Asset for a user's clan (tag) badge.

Parameters
----------
state: ConnectionState
The connection state.
guild_id: int
The ID of the guild (clan).
badge_id: str
The badge hash/id.

Returns
-------
:class:`Asset`
The clan badge asset.
"""
return cls(
state,
url=f"{cls.BASE}/clan-badges/{guild_id}/{badge_id}.png?size=256",
key=badge_id,
animated=False,
)

def __str__(self) -> str:
return self._url

Expand Down
3 changes: 2 additions & 1 deletion discord/guild.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
EntitlementOwnerType,
NotificationLevel,
NSFWLevel,
OnboardingMode,
ScheduledEventLocationType,
ScheduledEventPrivacyLevel,
VerificationLevel,
Expand All @@ -77,7 +78,7 @@
from .member import Member, VoiceState
from .mixins import Hashable
from .monetization import Entitlement
from .onboarding import Onboarding
from .onboarding import Onboarding, OnboardingPrompt
from .permissions import PermissionOverwrite
from .role import Role
from .scheduled_events import ScheduledEvent, ScheduledEventLocation
Expand Down
9 changes: 9 additions & 0 deletions discord/types/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@

from typing import Literal, TypedDict

from discord.asset import Asset

from .snowflake import Snowflake


Expand All @@ -41,6 +43,13 @@ class PartialUser(TypedDict):
PremiumType = Literal[0, 1, 2, 3]


class Tag(TypedDict, total=False):
identity_guild_id: Snowflake | None
identity_enabled: bool | None
tag: str | None
badge: str | None


class User(PartialUser, total=False):
bot: bool
system: bool
Expand Down
28 changes: 28 additions & 0 deletions discord/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
from typing import TYPE_CHECKING, Any, TypeVar

import discord.abc
from discord.types.user import Tag

from .asset import Asset
from .colour import Colour
Expand Down Expand Up @@ -76,6 +77,7 @@ class BaseUser(_UserTag):
"_public_flags",
"_avatar_decoration",
"_state",
"_clan",
)

if TYPE_CHECKING:
Expand All @@ -91,6 +93,7 @@ class BaseUser(_UserTag):
_accent_colour: int | None
_avatar_decoration: dict | None
_public_flags: int
_clan: dict | None

def __init__(
self, *, state: ConnectionState, data: UserPayload | PartialUserPayload
Expand Down Expand Up @@ -146,6 +149,7 @@ def _update(self, data: UserPayload) -> None:
self._public_flags = data.get("public_flags", 0)
self.bot = data.get("bot", False)
self.system = data.get("system", False)
self._clan = data.get("clan", None)

@classmethod
def _copy(cls: type[BU], user: BU) -> BU:
Expand All @@ -162,6 +166,7 @@ def _copy(cls: type[BU], user: BU) -> BU:
self.bot = user.bot
self._state = user._state
self._public_flags = user._public_flags
self._clan = user._clan

return self

Expand Down Expand Up @@ -296,6 +301,29 @@ def mention(self) -> str:
"""Returns a string that allows you to mention the given user."""
return f"<@{self.id}>"

@property
def tag(self) -> Tag:
"""Returns a :class:`Tag` object that contains the user's tag information.

.. versionadded:: 2.5

.. note::
This information is only available via :meth:`Client.fetch_user`.
"""
if self._clan:
return Tag(
guild_id=self._clan.get("identity_guild_id"),
enabled=self._clan.get("identity_enabled", False),
tag=self._clan.get("tag", str(self)),
badge=self._clan.get("badge"),
)
return Tag(
identity_guild_id=None,
identity_enabled=False,
tag=str(self),
badge=None,
)

@property
def created_at(self) -> datetime:
"""Returns the user's creation time in UTC.
Expand Down