From 6a72ff0eede452d55d22b6134bd519d5669b263c Mon Sep 17 00:00:00 2001 From: UK <41271523+NeloBlivion@users.noreply.github.com> Date: Tue, 25 Apr 2023 18:43:25 +0100 Subject: [PATCH] feat: Received Interactions come with a channel object (#2025) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Lala Sabathil --- CHANGELOG.md | 4 +++ discord/channel.py | 4 ++- discord/interactions.py | 46 +++++++++++++++++++++++++++-------- discord/types/interactions.py | 2 ++ 4 files changed, 45 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c77691d4b6..5992376353 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,6 +44,10 @@ These changes are available on the `master` branch, but have not yet been releas - Changed file-upload size limit from 8 MB to 25 MB accordingly. ([#2014](https://github.com/Pycord-Development/pycord/pull/2014)) +- `Interaction.channel` is received from the gateway, so it can now be `DMChannel` and + `GroupChannel`. ([#2025](https://github.com/Pycord-Development/pycord/pull/2025)) +- `DMChannel.recipients` can now be `None` + ([#2025](https://github.com/Pycord-Development/pycord/pull/2025)) ### Removed diff --git a/discord/channel.py b/discord/channel.py index 88ba717db5..ce2e87aad9 100644 --- a/discord/channel.py +++ b/discord/channel.py @@ -2838,7 +2838,9 @@ def __init__( self, *, me: ClientUser, state: ConnectionState, data: DMChannelPayload ): self._state: ConnectionState = state - self.recipient: User | None = state.store_user(data["recipients"][0]) + self.recipient: User | None = None + if r := data.get("recipients"): + self.recipient: state.store_user(r[0]) self.me: ClientUser = me self.id: int = int(data["id"]) diff --git a/discord/interactions.py b/discord/interactions.py index d4120a961a..c207da7105 100644 --- a/discord/interactions.py +++ b/discord/interactions.py @@ -29,7 +29,7 @@ from typing import TYPE_CHECKING, Any, Coroutine, Union from . import utils -from .channel import ChannelType, PartialMessageable +from .channel import ChannelType, PartialMessageable, _threaded_channel_factory from .enums import InteractionResponseType, InteractionType, try_enum from .errors import ClientException, InteractionResponded, InvalidArgument from .file import File @@ -57,7 +57,9 @@ from .channel import ( CategoryChannel, + DMChannel, ForumChannel, + GroupChannel, StageChannel, TextChannel, VoiceChannel, @@ -82,6 +84,8 @@ ForumChannel, CategoryChannel, Thread, + DMChannel, + GroupChannel, PartialMessageable, ] @@ -104,8 +108,10 @@ class Interaction: The interaction type. guild_id: Optional[:class:`int`] The guild ID the interaction was sent from. + channel: Optional[Union[:class:`abc.GuildChannel`, :class:`abc.PrivateChannel`, :class:`Thread`]] + The channel the interaction was sent from. channel_id: Optional[:class:`int`] - The channel ID the interaction was sent from. + The ID of the channel the interaction was sent from. application_id: :class:`int` The application ID that the interaction was for. user: Optional[Union[:class:`User`, :class:`Member`]] @@ -129,6 +135,7 @@ class Interaction: "id", "type", "guild_id", + "channel", "channel_id", "data", "application_id", @@ -139,6 +146,7 @@ class Interaction: "token", "version", "custom_id", + "_channel_data", "_message_data", "_permissions", "_app_permissions", @@ -174,13 +182,7 @@ def _from_data(self, data: InteractionPayload): self._app_permissions: int = int(data.get("app_permissions", 0)) self.message: Message | None = None - - if message_data := data.get("message"): - self.message = Message( - state=self._state, channel=self.channel, data=message_data - ) - - self._message_data = message_data + self.channel = None self.user: User | Member | None = None self._permissions: int = 0 @@ -211,6 +213,30 @@ def _from_data(self, data: InteractionPayload): except KeyError: pass + if channel := data.get("channel"): + if (ch_type := channel.get("type")) is not None: + factory, ch_type = _threaded_channel_factory(ch_type) + + if ch_type in (ChannelType.group, ChannelType.private): + self.channel = factory( + me=self.user, data=channel, state=self._state + ) + elif self.guild: + self.channel = factory( + guild=self.guild, state=self._state, data=channel + ) + else: + self.channel = self.cached_channel + + self._channel_data = channel + + if message_data := data.get("message"): + self.message = Message( + state=self._state, channel=self.channel, data=message_data + ) + + self._message_data = message_data + @property def client(self) -> Client: """Returns the client that sent the interaction.""" @@ -230,7 +256,7 @@ def is_component(self) -> bool: return self.type == InteractionType.component @utils.cached_slot_property("_cs_channel") - def channel(self) -> InteractionChannel | None: + def cached_channel(self) -> InteractionChannel | None: """The channel the interaction was sent from. diff --git a/discord/types/interactions.py b/discord/types/interactions.py index 458247709d..ad891e3203 100644 --- a/discord/types/interactions.py +++ b/discord/types/interactions.py @@ -39,6 +39,7 @@ if TYPE_CHECKING: from .message import AllowedMentions, Message + from ..interactions import InteractionChannel from .._typed_dict import NotRequired, TypedDict @@ -196,6 +197,7 @@ class Interaction(TypedDict): data: NotRequired[InteractionData] guild_id: NotRequired[Snowflake] channel_id: NotRequired[Snowflake] + channel: NotRequired[InteractionChannel] member: NotRequired[Member] user: NotRequired[User] message: NotRequired[Message]