Skip to content
Merged
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
180 changes: 75 additions & 105 deletions interactions/client/context.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import asyncio
from contextlib import suppress
from datetime import datetime
from logging import Logger
from typing import TYPE_CHECKING, List, Optional, Tuple, Union
Expand Down Expand Up @@ -160,6 +161,55 @@ async def get_guild(self) -> Guild:
res = await self._client.get_guild(int(self.guild_id))
return Guild(**res, _client=self._client)

async def defer(
self, ephemeral: Optional[bool] = False, edit_origin: Optional[bool] = False
) -> Message:
"""
.. versionchanged:: 4.4.0
Now returns the created message object

This "defers" an interaction response, allowing up
to a 15-minute delay between invocation and responding.

:param Optional[bool] ephemeral: Whether the deferred state is hidden or not.
:param Optional[bool] edit_origin: Whether you want to edit the original message or send a followup message
:return: The deferred message
:rtype: Message
"""
if edit_origin and self.type in {
InteractionType.APPLICATION_COMMAND,
InteractionType.APPLICATION_COMMAND_AUTOCOMPLETE,
}:
raise LibraryException(
message="You cannot defer with edit_origin parameter in this type of interaction"
)

if not self.responded:
self.deferred = True
is_ephemeral: int = MessageFlags.EPHEMERAL.value if bool(ephemeral) else 0
# ephemeral doesn't change callback typings. just data json
self.callback = (
InteractionCallbackType.DEFERRED_UPDATE_MESSAGE
if edit_origin
else InteractionCallbackType.DEFERRED_CHANNEL_MESSAGE_WITH_SOURCE
)

await self._client.create_interaction_response(
token=self.token,
application_id=int(self.id),
data={"type": self.callback.value, "data": {"flags": is_ephemeral}},
)

with suppress(LibraryException):
res = await self._client.get_original_interaction_response(
self.token, str(self.application_id)
)
self.message = Message(**res, _client=self._client)

self.responded = True

return self.message

async def send(
self,
content: Optional[str] = MISSING,
Expand Down Expand Up @@ -301,6 +351,9 @@ async def edit(
:return: The edited message.
"""

if self.message is None:
raise LibraryException(message="There is no message to edit.")

payload = {}

if self.message.content is not None or content is not MISSING:
Expand Down Expand Up @@ -541,55 +594,23 @@ async def edit(
else:
self.message = msg = Message(**res, _client=self._client)
else:
try:
res = await self._client.edit_interaction_response(
token=self.token,
application_id=str(self.application_id),
data=payload,
files=files,
)
except LibraryException as e:
if e.code in {10015, 10018}:
log.warning(f"You can't edit hidden messages." f"({e.message}).")
else:
# if its not ephemeral or some other thing.
raise e from e
else:
self.message = msg = Message(**res, _client=self._client)

return msg if msg is not None else Message(**payload, _client=self._client)

async def defer(self, ephemeral: Optional[bool] = False) -> Message:
"""
.. versionchanged:: 4.4.0
Now returns the created message object

This "defers" an interaction response, allowing up
to a 15-minute delay between invocation and responding.

:param Optional[bool] ephemeral: Whether the deferred state is hidden or not.
:return: The deferred message
:rtype: Message
"""
if not self.responded:
self.deferred = True
_ephemeral: int = MessageFlags.EPHEMERAL.value if ephemeral else 0
self.callback = InteractionCallbackType.DEFERRED_CHANNEL_MESSAGE_WITH_SOURCE
self.callback = InteractionCallbackType.UPDATE_MESSAGE
await self._client.create_interaction_response(
data={"type": self.callback.value, "data": payload},
files=files,
token=self.token,
application_id=int(self.id),
data={"type": self.callback.value, "data": {"flags": _ephemeral}},
)
try:
_msg = await self._client.get_original_interaction_response(

with suppress(LibraryException):
res = await self._client.get_original_interaction_response(
self.token, str(self.application_id)
)
except LibraryException:
pass
else:
self.message = Message(**_msg, _client=self._client)
self.message = msg = Message(**res, _client=self._client)

self.responded = True
return self.message

return msg or Message(**payload, _client=self._client)

async def send(self, content: Optional[str] = MISSING, **kwargs) -> Message:
payload, files = await super().send(content, **kwargs)
Expand All @@ -616,20 +637,15 @@ async def send(self, content: Optional[str] = MISSING, **kwargs) -> Message:
files=files,
)

try:
_msg = await self._client.get_original_interaction_response(
with suppress(LibraryException):
res = await self._client.get_original_interaction_response(
self.token, str(self.application_id)
)
except LibraryException:
pass
else:
self.message = msg = Message(**_msg, _client=self._client)
self.message = msg = Message(**res, _client=self._client)

self.responded = True

if msg is not None:
return msg
return Message(
return msg or Message(
**payload,
_client=self._client,
author={"_client": self._client, "id": None, "username": None, "discriminator": None},
Expand Down Expand Up @@ -712,14 +728,12 @@ async def edit(self, content: Optional[str] = MISSING, **kwargs) -> Message:
application_id=int(self.id),
)

try:
_msg = await self._client.get_original_interaction_response(
with suppress(LibraryException):
res = await self._client.get_original_interaction_response(
self.token, str(self.application_id)
)
except LibraryException:
pass
else:
self.message = msg = Message(**_msg, _client=self._client)

self.message = msg = Message(**res, _client=self._client)

self.responded = True
elif self.callback != InteractionCallbackType.DEFERRED_UPDATE_MESSAGE:
Expand All @@ -739,7 +753,7 @@ async def edit(self, content: Optional[str] = MISSING, **kwargs) -> Message:
self.responded = True
self.message = msg = Message(**res, _client=self._client)

return msg if msg is not None else Message(**payload, _client=self._client)
return msg or Message(**payload, _client=self._client)

async def send(self, content: Optional[str] = MISSING, **kwargs) -> Message:
payload, files = await super().send(content, **kwargs)
Expand All @@ -766,60 +780,16 @@ async def send(self, content: Optional[str] = MISSING, **kwargs) -> Message:
files=files,
)

try:
_msg = await self._client.get_original_interaction_response(
with suppress(LibraryException):
res = await self._client.get_original_interaction_response(
self.token, str(self.application_id)
)
except LibraryException:
pass
else:
self.message = msg = Message(**_msg, _client=self._client)
self.message = msg = Message(**res, _client=self._client)

self.responded = True

return msg if msg is not None else Message(**payload, _client=self._client)

async def defer(
self, ephemeral: Optional[bool] = False, edit_origin: Optional[bool] = False
) -> Message:
"""
.. versionchanged:: 4.4.0
Now returns the created message object

This "defers" a component response, allowing up
to a 15-minute delay between invocation and responding.

:param Optional[bool] ephemeral: Whether the deferred state is hidden or not.
:param Optional[bool] edit_origin: Whether you want to edit the original message or send a followup message
:return: The deferred message
:rtype: Message
"""
if not self.responded:

self.deferred = True
_ephemeral: int = MessageFlags.EPHEMERAL.value if bool(ephemeral) else 0
# ephemeral doesn't change callback typings. just data json
if edit_origin:
self.callback = InteractionCallbackType.DEFERRED_UPDATE_MESSAGE
else:
self.callback = InteractionCallbackType.DEFERRED_CHANNEL_MESSAGE_WITH_SOURCE

await self._client.create_interaction_response(
token=self.token,
application_id=int(self.id),
data={"type": self.callback.value, "data": {"flags": _ephemeral}},
)
try:
_msg = await self._client.get_original_interaction_response(
self.token, str(self.application_id)
)
except LibraryException:
pass
else:
self.message = Message(**_msg, _client=self._client)
self.responded = True
return self.message

async def disable_all_components(
self, respond_to_interaction: Optional[bool] = True, **other_kwargs: Optional[dict]
) -> Message:
Expand Down