Skip to content

Commit

Permalink
feat(message): include member data in InteractionReference.user (#1160
Browse files Browse the repository at this point in the history
)
  • Loading branch information
shiftinv authored Aug 24, 2024
1 parent 975657a commit 0a5ab1e
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 13 deletions.
1 change: 1 addition & 0 deletions changelog/1160.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
:attr:`InteractionReference.user` can now be a :class:`Member` in guild contexts.
55 changes: 42 additions & 13 deletions disnake/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -704,24 +704,48 @@ class InteractionReference:
For interaction references created before July 18th, 2022, this will not include group or subcommand names.
user: :class:`User`
The interaction author.
user: Union[:class:`User`, :class:`Member`]
The user or member that triggered the referenced interaction.
.. versionchanged:: 2.10
This is now a :class:`Member` when in a guild, if the message was received via a
gateway event or the member is cached.
"""

__slots__ = ("id", "type", "name", "user", "_state")
__slots__ = ("id", "type", "name", "user")

def __init__(self, *, state: ConnectionState, data: InteractionMessageReferencePayload) -> None:
self._state: ConnectionState = state
def __init__(
self,
*,
state: ConnectionState,
guild: Optional[Guild],
data: InteractionMessageReferencePayload,
) -> None:
self.id: int = int(data["id"])
self.type: InteractionType = try_enum(InteractionType, int(data["type"]))
self.name: str = data["name"]
self.user: User = User(state=state, data=data["user"])

user: Optional[Union[User, Member]] = None
if guild:
if isinstance(guild, Guild): # this can be a placeholder object in interactions
user = guild.get_member(int(data["user"]["id"]))

# If not cached, try data from event.
# This is only available via gateway (message_create/_edit), not HTTP
if not user and (member := data.get("member")):
user = Member(data=member, user_data=data["user"], guild=guild, state=state)

# If still none, deserialize user
if not user:
user = state.store_user(data["user"])

self.user: Union[User, Member] = user

def __repr__(self) -> str:
return f"<InteractionReference id={self.id!r} type={self.type!r} name={self.name!r} user={self.user!r}>"

@property
def author(self) -> User:
def author(self) -> Union[User, Member]:
return self.user


Expand Down Expand Up @@ -1003,12 +1027,6 @@ def __init__(
for d in data.get("components", [])
]

inter_payload = data.get("interaction")
inter = (
None if inter_payload is None else InteractionReference(state=state, data=inter_payload)
)
self.interaction: Optional[InteractionReference] = inter

self.poll: Optional[Poll] = None
if poll_data := data.get("poll"):
self.poll = Poll.from_dict(message=self, data=poll_data)
Expand All @@ -1019,6 +1037,12 @@ def __init__(
except AttributeError:
self.guild = state._get_guild(utils._get_as_snowflake(data, "guild_id"))

self.interaction: Optional[InteractionReference] = (
InteractionReference(state=state, guild=self.guild, data=interaction)
if (interaction := data.get("interaction"))
else None
)

if thread_data := data.get("thread"):
if not self.thread and isinstance(self.guild, Guild):
self.guild._store_thread(thread_data)
Expand Down Expand Up @@ -1236,8 +1260,13 @@ def _handle_components(self, components: List[ComponentPayload]) -> None:
def _rebind_cached_references(self, new_guild: Guild, new_channel: GuildMessageable) -> None:
self.guild = new_guild
self.channel = new_channel

# rebind the members' guilds; the members themselves will potentially be
# updated later in _update_member_references, after re-chunking
if isinstance(self.author, Member):
self.author.guild = new_guild
if self.interaction and isinstance(self.interaction.user, Member):
self.interaction.user.guild = new_guild

@utils.cached_slot_property("_cs_raw_mentions")
def raw_mentions(self) -> List[int]:
Expand Down
6 changes: 6 additions & 0 deletions disnake/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -2258,6 +2258,7 @@ def _update_guild_channel_references(self) -> None:
if new_guild is None:
continue

# TODO: use PartialMessageable instead of Object (3.0)
new_channel = new_guild._resolve_channel(vc.channel.id) or Object(id=vc.channel.id)
if new_channel is not vc.channel:
vc.channel = new_channel # type: ignore
Expand All @@ -2275,6 +2276,11 @@ def _update_member_references(self) -> None:
if new_author is not None and new_author is not msg.author:
msg.author = new_author

if msg.interaction is not None and isinstance(msg.interaction.user, Member):
new_author = msg.guild.get_member(msg.interaction.user.id)
if new_author is not None and new_author is not msg.interaction.user:
msg.interaction.user = new_author

async def chunker(
self,
guild_id: int,
Expand Down
1 change: 1 addition & 0 deletions disnake/types/interactions.py
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,7 @@ class InteractionMessageReference(TypedDict):
type: InteractionType
name: str
user: User
member: NotRequired[Member]


class EditApplicationCommand(TypedDict):
Expand Down

0 comments on commit 0a5ab1e

Please sign in to comment.