Skip to content

Commit 3784072

Browse files
authored
refactor(context): allow edit message from modal interaction (#1245)
* refactor(context): allow edit message from modal; move defer to base * refactor: run pre-commit * docs: defer is not only for component
1 parent 067ea9b commit 3784072

File tree

1 file changed

+75
-105
lines changed

1 file changed

+75
-105
lines changed

interactions/client/context.py

Lines changed: 75 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import asyncio
2+
from contextlib import suppress
23
from datetime import datetime
34
from logging import Logger
45
from typing import TYPE_CHECKING, List, Optional, Tuple, Union
@@ -160,6 +161,55 @@ async def get_guild(self) -> Guild:
160161
res = await self._client.get_guild(int(self.guild_id))
161162
return Guild(**res, _client=self._client)
162163

164+
async def defer(
165+
self, ephemeral: Optional[bool] = False, edit_origin: Optional[bool] = False
166+
) -> Message:
167+
"""
168+
.. versionchanged:: 4.4.0
169+
Now returns the created message object
170+
171+
This "defers" an interaction response, allowing up
172+
to a 15-minute delay between invocation and responding.
173+
174+
:param Optional[bool] ephemeral: Whether the deferred state is hidden or not.
175+
:param Optional[bool] edit_origin: Whether you want to edit the original message or send a followup message
176+
:return: The deferred message
177+
:rtype: Message
178+
"""
179+
if edit_origin and self.type in {
180+
InteractionType.APPLICATION_COMMAND,
181+
InteractionType.APPLICATION_COMMAND_AUTOCOMPLETE,
182+
}:
183+
raise LibraryException(
184+
message="You cannot defer with edit_origin parameter in this type of interaction"
185+
)
186+
187+
if not self.responded:
188+
self.deferred = True
189+
is_ephemeral: int = MessageFlags.EPHEMERAL.value if bool(ephemeral) else 0
190+
# ephemeral doesn't change callback typings. just data json
191+
self.callback = (
192+
InteractionCallbackType.DEFERRED_UPDATE_MESSAGE
193+
if edit_origin
194+
else InteractionCallbackType.DEFERRED_CHANNEL_MESSAGE_WITH_SOURCE
195+
)
196+
197+
await self._client.create_interaction_response(
198+
token=self.token,
199+
application_id=int(self.id),
200+
data={"type": self.callback.value, "data": {"flags": is_ephemeral}},
201+
)
202+
203+
with suppress(LibraryException):
204+
res = await self._client.get_original_interaction_response(
205+
self.token, str(self.application_id)
206+
)
207+
self.message = Message(**res, _client=self._client)
208+
209+
self.responded = True
210+
211+
return self.message
212+
163213
async def send(
164214
self,
165215
content: Optional[str] = MISSING,
@@ -301,6 +351,9 @@ async def edit(
301351
:return: The edited message.
302352
"""
303353

354+
if self.message is None:
355+
raise LibraryException(message="There is no message to edit.")
356+
304357
payload = {}
305358

306359
if self.message.content is not None or content is not MISSING:
@@ -541,55 +594,23 @@ async def edit(
541594
else:
542595
self.message = msg = Message(**res, _client=self._client)
543596
else:
544-
try:
545-
res = await self._client.edit_interaction_response(
546-
token=self.token,
547-
application_id=str(self.application_id),
548-
data=payload,
549-
files=files,
550-
)
551-
except LibraryException as e:
552-
if e.code in {10015, 10018}:
553-
log.warning(f"You can't edit hidden messages." f"({e.message}).")
554-
else:
555-
# if its not ephemeral or some other thing.
556-
raise e from e
557-
else:
558-
self.message = msg = Message(**res, _client=self._client)
559-
560-
return msg if msg is not None else Message(**payload, _client=self._client)
561-
562-
async def defer(self, ephemeral: Optional[bool] = False) -> Message:
563-
"""
564-
.. versionchanged:: 4.4.0
565-
Now returns the created message object
566-
567-
This "defers" an interaction response, allowing up
568-
to a 15-minute delay between invocation and responding.
569-
570-
:param Optional[bool] ephemeral: Whether the deferred state is hidden or not.
571-
:return: The deferred message
572-
:rtype: Message
573-
"""
574-
if not self.responded:
575-
self.deferred = True
576-
_ephemeral: int = MessageFlags.EPHEMERAL.value if ephemeral else 0
577-
self.callback = InteractionCallbackType.DEFERRED_CHANNEL_MESSAGE_WITH_SOURCE
597+
self.callback = InteractionCallbackType.UPDATE_MESSAGE
578598
await self._client.create_interaction_response(
599+
data={"type": self.callback.value, "data": payload},
600+
files=files,
579601
token=self.token,
580602
application_id=int(self.id),
581-
data={"type": self.callback.value, "data": {"flags": _ephemeral}},
582603
)
583-
try:
584-
_msg = await self._client.get_original_interaction_response(
604+
605+
with suppress(LibraryException):
606+
res = await self._client.get_original_interaction_response(
585607
self.token, str(self.application_id)
586608
)
587-
except LibraryException:
588-
pass
589-
else:
590-
self.message = Message(**_msg, _client=self._client)
609+
self.message = msg = Message(**res, _client=self._client)
610+
591611
self.responded = True
592-
return self.message
612+
613+
return msg or Message(**payload, _client=self._client)
593614

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

619-
try:
620-
_msg = await self._client.get_original_interaction_response(
640+
with suppress(LibraryException):
641+
res = await self._client.get_original_interaction_response(
621642
self.token, str(self.application_id)
622643
)
623-
except LibraryException:
624-
pass
625-
else:
626-
self.message = msg = Message(**_msg, _client=self._client)
644+
self.message = msg = Message(**res, _client=self._client)
627645

628646
self.responded = True
629647

630-
if msg is not None:
631-
return msg
632-
return Message(
648+
return msg or Message(
633649
**payload,
634650
_client=self._client,
635651
author={"_client": self._client, "id": None, "username": None, "discriminator": None},
@@ -712,14 +728,12 @@ async def edit(self, content: Optional[str] = MISSING, **kwargs) -> Message:
712728
application_id=int(self.id),
713729
)
714730

715-
try:
716-
_msg = await self._client.get_original_interaction_response(
731+
with suppress(LibraryException):
732+
res = await self._client.get_original_interaction_response(
717733
self.token, str(self.application_id)
718734
)
719-
except LibraryException:
720-
pass
721-
else:
722-
self.message = msg = Message(**_msg, _client=self._client)
735+
736+
self.message = msg = Message(**res, _client=self._client)
723737

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

742-
return msg if msg is not None else Message(**payload, _client=self._client)
756+
return msg or Message(**payload, _client=self._client)
743757

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

769-
try:
770-
_msg = await self._client.get_original_interaction_response(
783+
with suppress(LibraryException):
784+
res = await self._client.get_original_interaction_response(
771785
self.token, str(self.application_id)
772786
)
773-
except LibraryException:
774-
pass
775-
else:
776-
self.message = msg = Message(**_msg, _client=self._client)
787+
self.message = msg = Message(**res, _client=self._client)
777788

778789
self.responded = True
779790

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

782-
async def defer(
783-
self, ephemeral: Optional[bool] = False, edit_origin: Optional[bool] = False
784-
) -> Message:
785-
"""
786-
.. versionchanged:: 4.4.0
787-
Now returns the created message object
788-
789-
This "defers" a component response, allowing up
790-
to a 15-minute delay between invocation and responding.
791-
792-
:param Optional[bool] ephemeral: Whether the deferred state is hidden or not.
793-
:param Optional[bool] edit_origin: Whether you want to edit the original message or send a followup message
794-
:return: The deferred message
795-
:rtype: Message
796-
"""
797-
if not self.responded:
798-
799-
self.deferred = True
800-
_ephemeral: int = MessageFlags.EPHEMERAL.value if bool(ephemeral) else 0
801-
# ephemeral doesn't change callback typings. just data json
802-
if edit_origin:
803-
self.callback = InteractionCallbackType.DEFERRED_UPDATE_MESSAGE
804-
else:
805-
self.callback = InteractionCallbackType.DEFERRED_CHANNEL_MESSAGE_WITH_SOURCE
806-
807-
await self._client.create_interaction_response(
808-
token=self.token,
809-
application_id=int(self.id),
810-
data={"type": self.callback.value, "data": {"flags": _ephemeral}},
811-
)
812-
try:
813-
_msg = await self._client.get_original_interaction_response(
814-
self.token, str(self.application_id)
815-
)
816-
except LibraryException:
817-
pass
818-
else:
819-
self.message = Message(**_msg, _client=self._client)
820-
self.responded = True
821-
return self.message
822-
823793
async def disable_all_components(
824794
self, respond_to_interaction: Optional[bool] = True, **other_kwargs: Optional[dict]
825795
) -> Message:

0 commit comments

Comments
 (0)