From 0b4d64947b9a50e48cfb332c5e2783726c5cb8b3 Mon Sep 17 00:00:00 2001 From: Lonami Exo Date: Sat, 23 Mar 2019 19:25:45 +0100 Subject: [PATCH] Fix CallbackQuery.edit for messages via inline queries --- telethon/client/messages.py | 26 +++++++++++++++++++++++--- telethon/events/callbackquery.py | 30 +++++++++++++++++++++++++----- 2 files changed, 48 insertions(+), 8 deletions(-) diff --git a/telethon/client/messages.py b/telethon/client/messages.py index eb623392..b21bf9df 100644 --- a/telethon/client/messages.py +++ b/telethon/client/messages.py @@ -707,6 +707,10 @@ class MessageMethods(UploadMethods, ButtonMethods, MessageParseMethods): from it, so the next parameter will be assumed to be the message text. + You may also pass a :tl:`InputBotInlineMessageID`, + which is the only way to edit messages that were sent + after the user selects an inline query result. + message (`int` | `Message ` | `str`): The ID of the message (or `Message ` itself) to be edited. @@ -756,16 +760,32 @@ class MessageMethods(UploadMethods, ButtonMethods, MessageParseMethods): not modified at all. Returns: - The edited `telethon.tl.custom.message.Message`. + The edited `telethon.tl.custom.message.Message`, unless + `entity` was a :tl:`InputBotInlineMessageID` in which + case this method returns a boolean. """ - if isinstance(entity, types.Message): + if isinstance(entity, types.InputBotInlineMessageID): + text = message + message = entity + elif isinstance(entity, types.Message): text = message # Shift the parameters to the right message = entity entity = entity.to_id - entity = await self.get_input_entity(entity) text, msg_entities = await self._parse_message_text(text, parse_mode) file_handle, media, image = await self._file_to_media(file) + + if isinstance(entity, types.InputBotInlineMessageID): + return await self(functions.messages.EditInlineBotMessageRequest( + id=entity, + message=text, + no_webpage=not link_preview, + entities=msg_entities, + media=media, + reply_markup=self.build_reply_markup(buttons) + )) + + entity = await self.get_input_entity(entity) request = functions.messages.EditMessageRequest( peer=entity, id=utils.get_message_id(message), diff --git a/telethon/events/callbackquery.py b/telethon/events/callbackquery.py index d9329679..527a4e84 100644 --- a/telethon/events/callbackquery.py +++ b/telethon/events/callbackquery.py @@ -201,6 +201,21 @@ class CallbackQuery(EventBuilder): ) ) + @property + def via_inline(self): + """ + Whether this callback was generated from an inline button sent + via an inline query or not. If the bot sent the message itself + with buttons, and one of those is clicked, this will be ``False``. + If a user sent the message coming from an inline query to the + bot, and one of those is clicked, this will be ``True``. + + If it's ``True``, it's likely that the bot is **not** in the + chat, so methods like `respond` or `delete` won't work (but + `edit` will always work). + """ + return isinstance(self.query, types.UpdateInlineBotCallbackQuery) + async def respond(self, *args, **kwargs): """ Responds to the message (not as a reply). Shorthand for @@ -208,6 +223,8 @@ class CallbackQuery(EventBuilder): ``entity`` already set. This method also creates a task to `answer` the callback. + + This method will likely fail if `via_inline` is ``True``. """ self._client.loop.create_task(self.answer()) return await self._client.send_message( @@ -220,6 +237,8 @@ class CallbackQuery(EventBuilder): both ``entity`` and ``reply_to`` already set. This method also creates a task to `answer` the callback. + + This method will likely fail if `via_inline` is ``True``. """ self._client.loop.create_task(self.answer()) kwargs['reply_to'] = self.query.msg_id @@ -228,11 +247,11 @@ class CallbackQuery(EventBuilder): async def edit(self, *args, **kwargs): """ - Edits the message iff it's outgoing. Shorthand for + Edits the message. Shorthand for `telethon.client.messages.MessageMethods.edit_message` with - both ``entity`` and ``message`` already set. + the ``entity`` set to the correct :tl:`InputBotInlineMessageID`. - Returns the edited `Message `. + Returns ``True`` if the edit was successful. This method also creates a task to `answer` the callback. @@ -244,8 +263,7 @@ class CallbackQuery(EventBuilder): """ self._client.loop.create_task(self.answer()) return await self._client.edit_message( - await self.get_input_chat(), self.query.msg_id, - *args, **kwargs + self.query.msg_id, *args, **kwargs ) async def delete(self, *args, **kwargs): @@ -259,6 +277,8 @@ class CallbackQuery(EventBuilder): `telethon.client.telegramclient.TelegramClient` instance directly. This method also creates a task to `answer` the callback. + + This method will likely fail if `via_inline` is ``True``. """ self._client.loop.create_task(self.answer()) return await self._client.delete_messages(