mirror of
https://github.com/LonamiWebs/Telethon.git
synced 2025-02-09 08:00:53 +03:00
Add edit_message convenience method and refactor to accomodate it
This commit is contained in:
parent
80f918956a
commit
62c057a058
|
@ -46,8 +46,8 @@ from .tl.functions.contacts import (
|
||||||
from .tl.functions.messages import (
|
from .tl.functions.messages import (
|
||||||
GetDialogsRequest, GetHistoryRequest, SendMediaRequest,
|
GetDialogsRequest, GetHistoryRequest, SendMediaRequest,
|
||||||
SendMessageRequest, GetChatsRequest, GetAllDraftsRequest,
|
SendMessageRequest, GetChatsRequest, GetAllDraftsRequest,
|
||||||
CheckChatInviteRequest, ReadMentionsRequest,
|
CheckChatInviteRequest, ReadMentionsRequest, SendMultiMediaRequest,
|
||||||
SendMultiMediaRequest, UploadMediaRequest
|
UploadMediaRequest, EditMessageRequest
|
||||||
)
|
)
|
||||||
|
|
||||||
from .tl.functions import channels
|
from .tl.functions import channels
|
||||||
|
@ -70,7 +70,8 @@ from .tl.types import (
|
||||||
ChatInvite, ChatInviteAlready, PeerChannel, Photo, InputPeerSelf,
|
ChatInvite, ChatInviteAlready, PeerChannel, Photo, InputPeerSelf,
|
||||||
InputSingleMedia, InputMediaPhoto, InputPhoto, InputFile, InputFileBig,
|
InputSingleMedia, InputMediaPhoto, InputPhoto, InputFile, InputFileBig,
|
||||||
InputDocument, InputMediaDocument, Document, MessageEntityTextUrl,
|
InputDocument, InputMediaDocument, Document, MessageEntityTextUrl,
|
||||||
InputMessageEntityMentionName, DocumentAttributeVideo
|
InputMessageEntityMentionName, DocumentAttributeVideo,
|
||||||
|
UpdateEditMessage, UpdateEditChannelMessage, UpdateShort, Updates
|
||||||
)
|
)
|
||||||
from .tl.types.messages import DialogsSlice
|
from .tl.types.messages import DialogsSlice
|
||||||
from .extensions import markdown, html
|
from .extensions import markdown, html
|
||||||
|
@ -565,11 +566,60 @@ class TelegramClient(TelegramBareClient):
|
||||||
msg_id = update.id
|
msg_id = update.id
|
||||||
break
|
break
|
||||||
|
|
||||||
for update in result.updates:
|
if isinstance(result, UpdateShort):
|
||||||
|
updates = [result.update]
|
||||||
|
elif isinstance(result, Updates):
|
||||||
|
updates = result.updates
|
||||||
|
else:
|
||||||
|
return
|
||||||
|
|
||||||
|
for update in updates:
|
||||||
if isinstance(update, (UpdateNewChannelMessage, UpdateNewMessage)):
|
if isinstance(update, (UpdateNewChannelMessage, UpdateNewMessage)):
|
||||||
if update.message.id == msg_id:
|
if update.message.id == msg_id:
|
||||||
return update.message
|
return update.message
|
||||||
|
|
||||||
|
elif (isinstance(update, UpdateEditMessage) and
|
||||||
|
not isinstance(request.peer, InputPeerChannel)):
|
||||||
|
if request.id == update.message.id:
|
||||||
|
return update.message
|
||||||
|
|
||||||
|
elif (isinstance(update, UpdateEditChannelMessage) and
|
||||||
|
utils.get_peer_id(request.peer) ==
|
||||||
|
utils.get_peer_id(update.message.to_id)):
|
||||||
|
if request.id == update.message.id:
|
||||||
|
return update.message
|
||||||
|
|
||||||
|
def _parse_message_text(self, message, parse_mode):
|
||||||
|
"""
|
||||||
|
Returns a (parsed message, entities) tuple depending on parse_mode.
|
||||||
|
"""
|
||||||
|
if not parse_mode:
|
||||||
|
return message, []
|
||||||
|
|
||||||
|
parse_mode = parse_mode.lower()
|
||||||
|
if parse_mode in {'md', 'markdown'}:
|
||||||
|
message, msg_entities = markdown.parse(message)
|
||||||
|
elif parse_mode.startswith('htm'):
|
||||||
|
message, msg_entities = html.parse(message)
|
||||||
|
else:
|
||||||
|
raise ValueError('Unknown parsing mode: {}'.format(parse_mode))
|
||||||
|
|
||||||
|
for i, e in enumerate(msg_entities):
|
||||||
|
if isinstance(e, MessageEntityTextUrl):
|
||||||
|
m = re.match(r'^@|\+|tg://user\?id=(\d+)', e.url)
|
||||||
|
if m:
|
||||||
|
try:
|
||||||
|
msg_entities[i] = InputMessageEntityMentionName(
|
||||||
|
e.offset, e.length, self.get_input_entity(
|
||||||
|
int(m.group(1)) if m.group(1) else e.url
|
||||||
|
)
|
||||||
|
)
|
||||||
|
except (ValueError, TypeError):
|
||||||
|
# Make no replacement
|
||||||
|
pass
|
||||||
|
|
||||||
|
return message, msg_entities
|
||||||
|
|
||||||
def send_message(self, entity, message, reply_to=None, parse_mode='md',
|
def send_message(self, entity, message, reply_to=None, parse_mode='md',
|
||||||
link_preview=True):
|
link_preview=True):
|
||||||
"""
|
"""
|
||||||
|
@ -599,37 +649,14 @@ class TelegramClient(TelegramBareClient):
|
||||||
the sent message
|
the sent message
|
||||||
"""
|
"""
|
||||||
entity = self.get_input_entity(entity)
|
entity = self.get_input_entity(entity)
|
||||||
if parse_mode:
|
message, msg_entities = self._parse_message_text(message, parse_mode)
|
||||||
parse_mode = parse_mode.lower()
|
|
||||||
if parse_mode in {'md', 'markdown'}:
|
|
||||||
message, msg_entities = markdown.parse(message)
|
|
||||||
elif parse_mode.startswith('htm'):
|
|
||||||
message, msg_entities = html.parse(message)
|
|
||||||
else:
|
|
||||||
raise ValueError('Unknown parsing mode: {}'.format(parse_mode))
|
|
||||||
|
|
||||||
for i, e in enumerate(msg_entities):
|
|
||||||
if isinstance(e, MessageEntityTextUrl):
|
|
||||||
m = re.match(r'^@|\+|tg://user\?id=(\d+)', e.url)
|
|
||||||
if m:
|
|
||||||
try:
|
|
||||||
msg_entities[i] = InputMessageEntityMentionName(
|
|
||||||
e.offset, e.length, self.get_input_entity(
|
|
||||||
int(m.group(1)) if m.group(1) else e.url
|
|
||||||
)
|
|
||||||
)
|
|
||||||
except (ValueError, TypeError):
|
|
||||||
# Make no replacement
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
msg_entities = []
|
|
||||||
|
|
||||||
request = SendMessageRequest(
|
request = SendMessageRequest(
|
||||||
peer=entity,
|
peer=entity,
|
||||||
message=message,
|
message=message,
|
||||||
entities=msg_entities,
|
entities=msg_entities,
|
||||||
no_webpage=not link_preview,
|
no_webpage=not link_preview,
|
||||||
reply_to_msg_id=self._get_reply_to(reply_to)
|
reply_to_msg_id=self._get_message_id(reply_to)
|
||||||
)
|
)
|
||||||
result = self(request)
|
result = self(request)
|
||||||
if isinstance(result, UpdateShortSentMessage):
|
if isinstance(result, UpdateShortSentMessage):
|
||||||
|
@ -645,6 +672,50 @@ class TelegramClient(TelegramBareClient):
|
||||||
|
|
||||||
return self._get_response_message(request, result)
|
return self._get_response_message(request, result)
|
||||||
|
|
||||||
|
def edit_message(self, entity, message_id, message=None, parse_mode='md',
|
||||||
|
link_preview=True):
|
||||||
|
"""
|
||||||
|
Edits the given message ID (to change its contents or disable preview).
|
||||||
|
|
||||||
|
Args:
|
||||||
|
entity (:obj:`entity`):
|
||||||
|
From which chat to edit the message.
|
||||||
|
|
||||||
|
message_id (:obj:`str`):
|
||||||
|
The ID of the message (or ``Message`` itself) to be edited.
|
||||||
|
|
||||||
|
message (:obj:`str`, optional):
|
||||||
|
The new text of the message.
|
||||||
|
|
||||||
|
parse_mode (:obj:`str`, optional):
|
||||||
|
Can be 'md' or 'markdown' for markdown-like parsing (default),
|
||||||
|
or 'htm' or 'html' for HTML-like parsing. If ``None`` or any
|
||||||
|
other false-y value is provided, the message will be sent with
|
||||||
|
no formatting.
|
||||||
|
|
||||||
|
link_preview (:obj:`bool`, optional):
|
||||||
|
Should the link preview be shown?
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
``MessageAuthorRequiredError`` if you're not the author of the
|
||||||
|
message but try editing it anyway.
|
||||||
|
|
||||||
|
``MessageNotModifiedError`` if the contents of the message were
|
||||||
|
not modified at all.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
the edited message
|
||||||
|
"""
|
||||||
|
message, msg_entities = self._parse_message_text(message, parse_mode)
|
||||||
|
request = EditMessageRequest(
|
||||||
|
peer=self.get_input_entity(entity),
|
||||||
|
id=self._get_message_id(message_id),
|
||||||
|
message=message,
|
||||||
|
no_webpage=not link_preview
|
||||||
|
)
|
||||||
|
result = self(request)
|
||||||
|
return self._get_response_message(request, result)
|
||||||
|
|
||||||
def delete_messages(self, entity, message_ids, revoke=True):
|
def delete_messages(self, entity, message_ids, revoke=True):
|
||||||
"""
|
"""
|
||||||
Deletes a message from a chat, optionally "for everyone".
|
Deletes a message from a chat, optionally "for everyone".
|
||||||
|
@ -869,22 +940,22 @@ class TelegramClient(TelegramBareClient):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _get_reply_to(reply_to):
|
def _get_message_id(message):
|
||||||
"""Sanitizes the 'reply_to' parameter a user may send"""
|
"""Sanitizes the 'reply_to' parameter a user may send"""
|
||||||
if reply_to is None:
|
if message is None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
if isinstance(reply_to, int):
|
if isinstance(message, int):
|
||||||
return reply_to
|
return message
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if reply_to.SUBCLASS_OF_ID == 0x790009e3:
|
if message.SUBCLASS_OF_ID == 0x790009e3:
|
||||||
# hex(crc32(b'Message')) = 0x790009e3
|
# hex(crc32(b'Message')) = 0x790009e3
|
||||||
return reply_to.id
|
return message.id
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
raise TypeError('Invalid reply_to type: {}'.format(type(reply_to)))
|
raise TypeError('Invalid message type: {}'.format(type(message)))
|
||||||
|
|
||||||
# endregion
|
# endregion
|
||||||
|
|
||||||
|
@ -973,7 +1044,7 @@ class TelegramClient(TelegramBareClient):
|
||||||
]
|
]
|
||||||
|
|
||||||
entity = self.get_input_entity(entity)
|
entity = self.get_input_entity(entity)
|
||||||
reply_to = self._get_reply_to(reply_to)
|
reply_to = self._get_message_id(reply_to)
|
||||||
|
|
||||||
if not isinstance(file, (str, bytes, io.IOBase)):
|
if not isinstance(file, (str, bytes, io.IOBase)):
|
||||||
# The user may pass a Message containing media (or the media,
|
# The user may pass a Message containing media (or the media,
|
||||||
|
@ -1086,7 +1157,7 @@ class TelegramClient(TelegramBareClient):
|
||||||
# cache only makes a difference for documents where the user may
|
# cache only makes a difference for documents where the user may
|
||||||
# want the attributes used on them to change. Caption's ignored.
|
# want the attributes used on them to change. Caption's ignored.
|
||||||
entity = self.get_input_entity(entity)
|
entity = self.get_input_entity(entity)
|
||||||
reply_to = self._get_reply_to(reply_to)
|
reply_to = self._get_message_id(reply_to)
|
||||||
|
|
||||||
# Need to upload the media first, but only if they're not cached yet
|
# Need to upload the media first, but only if they're not cached yet
|
||||||
media = []
|
media = []
|
||||||
|
|
Loading…
Reference in New Issue
Block a user