Skip to content

Commit 22199b0

Browse files
committed
Implement editing of messages sent via inline bots
- edit_message_text - edit_message_caption - edit_message_media - edit_message_reply_markup
1 parent a2d1752 commit 22199b0

6 files changed

Lines changed: 122 additions & 65 deletions

File tree

pyrogram/client/ext/base_client.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,3 +156,6 @@ def guess_extension(self, *args, **kwargs):
156156

157157
def get_profile_photos(self, *args, **kwargs):
158158
pass
159+
160+
def edit_message_text(self, *args, **kwargs):
161+
pass

pyrogram/client/ext/utils.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
# You should have received a copy of the GNU Lesser General Public License
1717
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
1818

19+
import base64
1920
import struct
2021
from base64 import b64decode, b64encode
2122
from typing import Union, List
@@ -191,3 +192,14 @@ def parse_deleted_messages(client, update) -> List["pyrogram.Message"]:
191192
)
192193

193194
return pyrogram.List(parsed_messages)
195+
196+
197+
def unpack_inline_message_id(inline_message_id: str) -> types.InputBotInlineMessageID:
198+
r = inline_message_id + "=" * (-len(inline_message_id) % 4)
199+
r = struct.unpack("<iqq", base64.b64decode(r, altchars="-_"))
200+
201+
return types.InputBotInlineMessageID(
202+
dc_id=r[0],
203+
id=r[1],
204+
access_hash=r[2]
205+
)

pyrogram/client/methods/messages/edit_message_caption.py

Lines changed: 24 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -19,61 +19,58 @@
1919
from typing import Union
2020

2121
import pyrogram
22-
from pyrogram.api import functions, types
2322
from pyrogram.client.ext import BaseClient
2423

2524

2625
class EditMessageCaption(BaseClient):
2726
def edit_message_caption(
2827
self,
29-
chat_id: Union[int, str],
30-
message_id: int,
3128
caption: str,
29+
chat_id: Union[int, str] = None,
30+
message_id: int = None,
31+
inline_message_id: str = None,
3232
parse_mode: str = "",
3333
reply_markup: "pyrogram.InlineKeyboardMarkup" = None
3434
) -> "pyrogram.Message":
35-
"""Edit captions of messages.
35+
"""Edit caption of media messages.
3636
3737
Parameters:
38-
chat_id (``int`` | ``str``):
38+
caption (``str``):
39+
New caption of the media message.
40+
41+
chat_id (``int`` | ``str``, *optional*):
42+
Required if *inline_message_id* is not specified.
3943
Unique identifier (int) or username (str) of the target chat.
4044
For your personal cloud (Saved Messages) you can simply use "me" or "self".
4145
For a contact that exists in your Telegram address book you can use his phone number (str).
4246
43-
message_id (``int``):
47+
message_id (``int``, *optional*):
48+
Required if *inline_message_id* is not specified.
4449
Message identifier in the chat specified in chat_id.
4550
46-
caption (``str``):
47-
New caption of the message.
51+
inline_message_id (``str``, *optional*):
52+
Required if *chat_id* and *message_id* are not specified.
53+
Identifier of the inline message.
4854
4955
parse_mode (``str``, *optional*):
5056
Pass "markdown" or "html" if you want Telegram apps to show bold, italic, fixed-width text or inline
51-
URLs in your caption. Defaults to "markdown".
57+
URLs in your message. Defaults to "markdown".
5258
5359
reply_markup (:obj:`InlineKeyboardMarkup`, *optional*):
5460
An InlineKeyboardMarkup object.
5561
5662
Returns:
57-
:obj:`Message`: On success, the edited message is returned.
63+
:obj:`Message` | ``bool``: On success, if the edited message was sent by the bot, the edited message is
64+
returned, otherwise True is returned (message sent via the bot, as inline query result).
5865
5966
Raises:
6067
RPCError: In case of a Telegram RPC error.
6168
"""
62-
style = self.html if parse_mode.lower() == "html" else self.markdown
63-
64-
r = self.send(
65-
functions.messages.EditMessage(
66-
peer=self.resolve_peer(chat_id),
67-
id=message_id,
68-
reply_markup=reply_markup.write() if reply_markup else None,
69-
**style.parse(caption)
70-
)
69+
return self.edit_message_text(
70+
text=caption,
71+
chat_id=chat_id,
72+
message_id=message_id,
73+
inline_message_id=inline_message_id,
74+
parse_mode=parse_mode,
75+
reply_markup=reply_markup
7176
)
72-
73-
for i in r.updates:
74-
if isinstance(i, (types.UpdateEditMessage, types.UpdateEditChannelMessage)):
75-
return pyrogram.Message._parse(
76-
self, i.message,
77-
{i.id: i for i in r.users},
78-
{i.id: i for i in r.chats}
79-
)

pyrogram/client/methods/messages/edit_message_media.py

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -32,35 +32,42 @@
3232
class EditMessageMedia(BaseClient):
3333
def edit_message_media(
3434
self,
35-
chat_id: Union[int, str],
36-
message_id: int,
3735
media: InputMedia,
36+
chat_id: Union[int, str] = None,
37+
message_id: int = None,
38+
inline_message_id: str = None,
3839
reply_markup: "pyrogram.InlineKeyboardMarkup" = None
3940
) -> "pyrogram.Message":
40-
"""Edit audio, document, photo, or video messages.
41+
"""Edit animation, audio, document, photo or video messages.
4142
4243
If a message is a part of a message album, then it can be edited only to a photo or a video. Otherwise,
4344
message type can be changed arbitrarily. When inline message is edited, new file can't be uploaded.
44-
Use previously uploaded file via its file_id or specify a URL. On success, if the edited message was sent
45-
by the bot, the edited Message is returned, otherwise True is returned.
45+
Use previously uploaded file via its file_id or specify a URL.
4646
4747
Parameters:
48-
chat_id (``int`` | ``str``):
48+
media (:obj:`InputMedia`)
49+
One of the InputMedia objects describing an animation, audio, document, photo or video.
50+
51+
chat_id (``int`` | ``str``, *optional*):
52+
Required if *inline_message_id* is not specified.
4953
Unique identifier (int) or username (str) of the target chat.
5054
For your personal cloud (Saved Messages) you can simply use "me" or "self".
5155
For a contact that exists in your Telegram address book you can use his phone number (str).
5256
53-
message_id (``int``):
57+
message_id (``int``, *optional*):
58+
Required if *inline_message_id* is not specified.
5459
Message identifier in the chat specified in chat_id.
5560
56-
media (:obj:`InputMedia`)
57-
One of the InputMedia objects describing an animation, audio, document, photo or video.
61+
inline_message_id (``str``, *optional*):
62+
Required if *chat_id* and *message_id* are not specified.
63+
Identifier of the inline message.
5864
5965
reply_markup (:obj:`InlineKeyboardMarkup`, *optional*):
6066
An InlineKeyboardMarkup object.
6167
6268
Returns:
63-
:obj:`Message`: On success, the edited message is returned.
69+
:obj:`Message` | ``bool``: On success, if the edited message was sent by the bot, the edited message is
70+
returned, otherwise True is returned (message sent via the bot, as inline query result).
6471
6572
Raises:
6673
RPCError: In case of a Telegram RPC error.
@@ -92,8 +99,7 @@ def edit_message_media(
9299
)
93100
else:
94101
media = utils.get_input_media_from_file_id(media.media, 2)
95-
96-
if isinstance(media, InputMediaVideo):
102+
elif isinstance(media, InputMediaVideo):
97103
if os.path.exists(media.media):
98104
media = self.send(
99105
functions.messages.UploadMedia(
@@ -130,8 +136,7 @@ def edit_message_media(
130136
)
131137
else:
132138
media = utils.get_input_media_from_file_id(media.media, 4)
133-
134-
if isinstance(media, InputMediaAudio):
139+
elif isinstance(media, InputMediaAudio):
135140
if os.path.exists(media.media):
136141
media = self.send(
137142
functions.messages.UploadMedia(
@@ -167,8 +172,7 @@ def edit_message_media(
167172
)
168173
else:
169174
media = utils.get_input_media_from_file_id(media.media, 9)
170-
171-
if isinstance(media, InputMediaAnimation):
175+
elif isinstance(media, InputMediaAnimation):
172176
if os.path.exists(media.media):
173177
media = self.send(
174178
functions.messages.UploadMedia(
@@ -206,8 +210,7 @@ def edit_message_media(
206210
)
207211
else:
208212
media = utils.get_input_media_from_file_id(media.media, 10)
209-
210-
if isinstance(media, InputMediaDocument):
213+
elif isinstance(media, InputMediaDocument):
211214
if os.path.exists(media.media):
212215
media = self.send(
213216
functions.messages.UploadMedia(
@@ -239,12 +242,22 @@ def edit_message_media(
239242
else:
240243
media = utils.get_input_media_from_file_id(media.media, 5)
241244

245+
if inline_message_id is not None:
246+
return self.send(
247+
functions.messages.EditInlineBotMessage(
248+
id=utils.unpack_inline_message_id(inline_message_id),
249+
media=media,
250+
reply_markup=reply_markup.write() if reply_markup else None,
251+
**style.parse(caption)
252+
)
253+
)
254+
242255
r = self.send(
243256
functions.messages.EditMessage(
244257
peer=self.resolve_peer(chat_id),
245258
id=message_id,
246-
reply_markup=reply_markup.write() if reply_markup else None,
247259
media=media,
260+
reply_markup=reply_markup.write() if reply_markup else None,
248261
**style.parse(caption)
249262
)
250263
)

pyrogram/client/methods/messages/edit_message_reply_markup.py

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,43 +20,57 @@
2020

2121
import pyrogram
2222
from pyrogram.api import functions, types
23-
from pyrogram.client.ext import BaseClient
23+
from pyrogram.client.ext import BaseClient, utils
2424

2525

2626
class EditMessageReplyMarkup(BaseClient):
2727
def edit_message_reply_markup(
2828
self,
29-
chat_id: Union[int, str],
30-
message_id: int,
31-
reply_markup: "pyrogram.InlineKeyboardMarkup" = None
29+
reply_markup: "pyrogram.InlineKeyboardMarkup" = None,
30+
chat_id: Union[int, str] = None,
31+
message_id: int = None,
32+
inline_message_id: str = None
3233
) -> "pyrogram.Message":
3334
"""Edit only the reply markup of messages sent by the bot or via the bot (for inline bots).
3435
3536
Parameters:
36-
chat_id (``int`` | ``str``):
37+
reply_markup (:obj:`InlineKeyboardMarkup`, *optional*):
38+
An InlineKeyboardMarkup object.
39+
40+
chat_id (``int`` | ``str``, *optional*):
41+
Required if *inline_message_id* is not specified.
3742
Unique identifier (int) or username (str) of the target chat.
3843
For your personal cloud (Saved Messages) you can simply use "me" or "self".
3944
For a contact that exists in your Telegram address book you can use his phone number (str).
4045
41-
message_id (``int``):
46+
message_id (``int``, *optional*):
47+
Required if *inline_message_id* is not specified.
4248
Message identifier in the chat specified in chat_id.
4349
44-
reply_markup (:obj:`InlineKeyboardMarkup`, *optional*):
45-
An InlineKeyboardMarkup object.
50+
inline_message_id (``str``, *optional*):
51+
Required if *chat_id* and *message_id* are not specified.
52+
Identifier of the inline message.
4653
4754
Returns:
48-
:obj:`Message` | ``bool``: In case the edited message is sent by the bot, the edited message is returned,
49-
otherwise, True is returned in case the edited message is send by the user.
55+
:obj:`Message` | ``bool``: On success, if the edited message was sent by the bot, the edited message is
56+
returned, otherwise True is returned (message sent via the bot, as inline query result).
5057
5158
Raises:
5259
RPCError: In case of a Telegram RPC error.
5360
"""
61+
if inline_message_id is not None:
62+
return self.send(
63+
functions.messages.EditInlineBotMessage(
64+
id=utils.unpack_inline_message_id(inline_message_id),
65+
reply_markup=reply_markup.write() if reply_markup else None,
66+
)
67+
)
5468

5569
r = self.send(
5670
functions.messages.EditMessage(
5771
peer=self.resolve_peer(chat_id),
5872
id=message_id,
59-
reply_markup=reply_markup.write() if reply_markup else None
73+
reply_markup=reply_markup.write() if reply_markup else None,
6074
)
6175
)
6276

pyrogram/client/methods/messages/edit_message_text.py

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,32 +20,39 @@
2020

2121
import pyrogram
2222
from pyrogram.api import functions, types
23-
from pyrogram.client.ext import BaseClient
23+
from pyrogram.client.ext import BaseClient, utils
2424

2525

2626
class EditMessageText(BaseClient):
2727
def edit_message_text(
2828
self,
29-
chat_id: Union[int, str],
30-
message_id: int,
3129
text: str,
30+
chat_id: Union[int, str] = None,
31+
message_id: int = None,
32+
inline_message_id: str = None,
3233
parse_mode: str = "",
3334
disable_web_page_preview: bool = None,
3435
reply_markup: "pyrogram.InlineKeyboardMarkup" = None
3536
) -> "pyrogram.Message":
3637
"""Edit text messages.
3738
3839
Parameters:
39-
chat_id (``int`` | ``str``):
40+
text (``str``):
41+
New text of the message.
42+
43+
chat_id (``int`` | ``str``, *optional*):
44+
Required if *inline_message_id* is not specified.
4045
Unique identifier (int) or username (str) of the target chat.
4146
For your personal cloud (Saved Messages) you can simply use "me" or "self".
4247
For a contact that exists in your Telegram address book you can use his phone number (str).
4348
44-
message_id (``int``):
49+
message_id (``int``, *optional*):
50+
Required if *inline_message_id* is not specified.
4551
Message identifier in the chat specified in chat_id.
4652
47-
text (``str``):
48-
New text of the message.
53+
inline_message_id (``str``, *optional*):
54+
Required if *chat_id* and *message_id* are not specified.
55+
Identifier of the inline message.
4956
5057
parse_mode (``str``, *optional*):
5158
Pass "markdown" or "html" if you want Telegram apps to show bold, italic, fixed-width text or inline
@@ -58,13 +65,24 @@ def edit_message_text(
5865
An InlineKeyboardMarkup object.
5966
6067
Returns:
61-
:obj:`Message`: On success, the edited message is returned.
68+
:obj:`Message` | ``bool``: On success, if the edited message was sent by the bot, the edited message is
69+
returned, otherwise True is returned (message sent via the bot, as inline query result).
6270
6371
Raises:
6472
RPCError: In case of a Telegram RPC error.
6573
"""
6674
style = self.html if parse_mode.lower() == "html" else self.markdown
6775

76+
if inline_message_id is not None:
77+
return self.send(
78+
functions.messages.EditInlineBotMessage(
79+
id=utils.unpack_inline_message_id(inline_message_id),
80+
no_webpage=disable_web_page_preview or None,
81+
reply_markup=reply_markup.write() if reply_markup else None,
82+
**style.parse(text)
83+
)
84+
)
85+
6886
r = self.send(
6987
functions.messages.EditMessage(
7088
peer=self.resolve_peer(chat_id),

0 commit comments

Comments
 (0)