1+ from discord .message import PartialMessage
12from discord_ui .slash .tools import handle_options
2- from .errors import InvalidEvent , OutOfValidRange
3+ from .errors import InvalidEvent , OutOfValidRange , WrongType
34from .slash .errors import AlreadyDeferred , EphemeralDeletion
45from .slash .types import ContextCommand , SlashCommand , SubSlashCommand
56from .tools import MISSING , setup_logger
67from .http import BetterRoute , jsonifyMessage , send_files
7- from .components import ActionRow , Button , LinkButton , SelectMenu , SelectOption
8+ from .components import ActionRow , Button , ComponentType , LinkButton , SelectMenu , SelectOption
89
910import discord
11+ from discord .ext .commands import Bot
1012from discord .errors import HTTPException
1113from discord .state import ConnectionState
1214
@@ -357,12 +359,11 @@ async def getResponseMessage(state: ConnectionState, data, user=None, response =
357359 channel = state .get_channel (int (data ["channel_id" ]))
358360 if response and user :
359361 if data .get ("message" ) is not None and data ["message" ]["flags" ] == 64 :
360- try :
361- return ResponseMessage (state = state , channel = channel , data = data , user = user )
362- except :
363- return EphemeralMessage (state = state , channel = channel , data = data ["message" ])
362+ return EphemeralResponseMessage (state = state , channel = channel , data = data , user = user )
364363 return ResponseMessage (state = state , channel = channel , data = data , user = user )
365364
365+ if data .get ("message" ) is not None and data ["message" ]["flags" ] == 64 :
366+ return EphemeralMessage (state = state , channel = channel , data = data ["message" ])
366367 return Message (state = state , channel = channel , data = data )
367368
368369class Message (discord .Message ):
@@ -371,6 +372,7 @@ def __init__(self, *, state, channel, data):
371372 self .__slots__ = discord .Message .__slots__ + ("components" , "supressed" )
372373 self ._payload = data
373374
375+ self ._state : ConnectionState = None
374376 super ().__init__ (state = state , channel = channel , data = data )
375377 self .components : typing .List [typing .Union [Button , LinkButton , SelectMenu ]] = []
376378 """The components in the message
@@ -599,7 +601,8 @@ def check(btn, msg):
599601 if custom_id is not MISSING and btn .custom_id == custom_id :
600602 return True
601603 return True
602-
604+ if not isinstance (client , Bot ):
605+ raise WrongType ("client" , client , "discord.ext.commands.Bot" )
603606 return (await client .wait_for ('button_press' if event_name .lower () == "button" else "menu_select" , check = check , timeout = timeout ))[0 ]
604607
605608 raise InvalidEvent (event_name , ["button" , "select" ])
@@ -665,22 +668,62 @@ def __init__(self, value) -> None:
665668
666669
667670class EphemeralMessage (Message ):
668- """Represents a hidden (ephemeral) message
669-
670- .. note::
671-
672- You will get this class for a message only if you sent a hidden response
673-
674- This class is almost the same as the :class:`~Message` class, but you can't edit, delete or reply to the message
675-
676- If you want to "reply" to id, use the `interaction.send` method instead
677- """
678- def __init__ (self , * , state , channel , data , application_id = MISSING , token = MISSING ):
671+ """Represents a hidden (ephemeral) message"""
672+ def __init__ (self , state , channel , data , application_id = MISSING , token = MISSING ):
679673 Message .__init__ (self , state = state , channel = channel , data = data )
680674 self ._application_id = application_id
681675 self ._interaction_token = token
682676 async def edit (self , ** fields ):
683677 r = BetterRoute ("PATCH" , f"/webhooks/{ self ._application_id } /{ self ._interaction_token } /messages/{ self .id } " )
684678 self ._update (await self ._state .http .request (r , json = jsonifyMessage (** fields )))
685679 async def delete (self ):
686- raise EphemeralDeletion ()
680+ raise EphemeralDeletion ()
681+
682+ class EphemeralResponseMessage (ResponseMessage ):
683+ """A ephemeral message wich was created from an interaction
684+
685+ .. important::
686+
687+ Methods like `.edit()`, which change the original message, need a `token` paremeter passed in order to work
688+ """
689+ def __init__ (self , * , state , channel , data , user ):
690+ ResponseMessage .__init__ (self , state = state , channel = channel , data = data , user = user )
691+
692+ async def edit (self , token , ** fields ):
693+ """Edits the message
694+
695+ Parameters
696+ ----------
697+ token: :class:`str`
698+ The token of the interaction with wich this ephemeral message was sent
699+ fields: :class:`kwargs`
700+ The fields to edit (ex. `content="...", embed=..., attachments=[...]`)
701+
702+ Example
703+
704+ .. code-block::
705+
706+ async def testing(ctx):
707+ msg = await ctx.send("hello hidden world", components=[Button("test")])
708+ btn = await msg.wait_for(client, "button")
709+ await btn.message.edit(ctx.token, content="edited", components=None)
710+
711+ """
712+ route = BetterRoute ("PATCH" , f"/webhooks/{ self .interaction .application_id } /{ token } /messages/{ self .id } " )
713+ self ._update (await self ._state .http .request (route , json = jsonifyMessage (** fields )))
714+ async def delete (self ):
715+ raise EphemeralDeletion ()
716+ async def disable_components (self , token , disable = True ):
717+ """Disables all component in the message
718+
719+ Parameters
720+ ----------
721+ disable: :class:`bool`, optional
722+ Whether to disable (``True``) or enable (``False``) als components; default True
723+
724+ """
725+ fixed = []
726+ for x in self .components :
727+ x .disabled = disable
728+ fixed .append (x )
729+ await self .edit (token , components = fixed )
0 commit comments