diff --git a/discord/interactions.py b/discord/interactions.py index d506a3347..8737c2d63 100644 --- a/discord/interactions.py +++ b/discord/interactions.py @@ -163,7 +163,7 @@ class Interaction(Generic[ClientT]): else: # The fallback to Object for guild causes a type check error but is explicitly allowed here self.user = Member(state=self._state, guild=guild, data=member) # type: ignore - self._permissions = int(member.get('permissions', 0)) + self._permissions = self.user._permissions or 0 else: try: self.user = User(state=self._state, data=data['user']) # type: ignore - The key is optional and handled diff --git a/discord/member.py b/discord/member.py index 31985e279..841817ab8 100644 --- a/discord/member.py +++ b/discord/member.py @@ -272,6 +272,7 @@ class Member(discord.abc.Messageable, _UserTag): 'pending', 'nick', 'timed_out_until', + '_permissions', '_client_status', '_user', '_state', @@ -307,6 +308,12 @@ class Member(discord.abc.Messageable, _UserTag): self.nick: Optional[str] = data.get('nick', None) self.pending: bool = data.get('pending', False) self._avatar: Optional[str] = data.get('avatar') + self._permissions: Optional[int] + try: + self._permissions = int(data['permissions']) + except KeyError: + self._permissions = None + self.timed_out_until: Optional[datetime.datetime] = utils.parse_time(data.get('communication_disabled_until')) def __str__(self) -> str: @@ -365,6 +372,7 @@ class Member(discord.abc.Messageable, _UserTag): self.pending = member.pending self.activities = member.activities self.timed_out_until = member.timed_out_until + self._permissions = member._permissions self._state = member._state self._avatar = member._avatar @@ -618,6 +626,22 @@ class Member(discord.abc.Messageable, _UserTag): return base + @property + def resolved_permissions(self) -> Optional[Permissions]: + """Optional[:class:`Permissions`]: Returns the member's resolved permissions + from an interaction. + + This is only available in interaction contexts and represents the resolved + permissions of the member in the channel the interaction was executed in. + This is more or less equivalent to calling :meth:`abc.GuildChannel.permissions_for` + but stored and returned as an attribute by the Discord API rather than computed. + + .. versionadded:: 2.0 + """ + if self._permissions is None: + return None + return Permissions(self._permissions) + @property def voice(self) -> Optional[VoiceState]: """Optional[:class:`VoiceState`]: Returns the member's current voice state."""