Skip to content
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

feat: Received Interactions come with a channel object #2025

Merged
merged 6 commits into from Apr 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Expand Up @@ -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

Expand Down
4 changes: 3 additions & 1 deletion discord/channel.py
Expand Up @@ -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"])

Expand Down
46 changes: 36 additions & 10 deletions discord/interactions.py
Expand Up @@ -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
Expand Down Expand Up @@ -57,7 +57,9 @@

from .channel import (
CategoryChannel,
DMChannel,
ForumChannel,
GroupChannel,
StageChannel,
TextChannel,
VoiceChannel,
Expand All @@ -82,6 +84,8 @@
ForumChannel,
CategoryChannel,
Thread,
DMChannel,
GroupChannel,
PartialMessageable,
]

Expand All @@ -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`]]
Expand All @@ -129,6 +135,7 @@ class Interaction:
"id",
"type",
"guild_id",
"channel",
"channel_id",
"data",
"application_id",
Expand All @@ -139,6 +146,7 @@ class Interaction:
"token",
"version",
"custom_id",
"_channel_data",
"_message_data",
"_permissions",
"_app_permissions",
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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."""
Expand All @@ -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.

Expand Down
2 changes: 2 additions & 0 deletions discord/types/interactions.py
Expand Up @@ -39,6 +39,7 @@

if TYPE_CHECKING:
from .message import AllowedMentions, Message
from ..interactions import InteractionChannel

from .._typed_dict import NotRequired, TypedDict

Expand Down Expand Up @@ -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]
Expand Down