mirror of
				https://github.com/LonamiWebs/Telethon.git
				synced 2025-10-30 23:47:33 +03:00 
			
		
		
		
	Move events.NewMessage properties to custom.Message
This commit is contained in:
		
							parent
							
								
									97b0a0610e
								
							
						
					
					
						commit
						6dcd0911a7
					
				|  | @ -1,9 +1,7 @@ | ||||||
| import re | import re | ||||||
| 
 | 
 | ||||||
| from .common import EventBuilder, EventCommon, name_inner_event | from .common import EventBuilder, EventCommon, name_inner_event | ||||||
| from .. import utils | from ..tl import types, custom | ||||||
| from ..extensions import markdown |  | ||||||
| from ..tl import types, functions, custom |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @name_inner_event | @name_inner_event | ||||||
|  | @ -116,23 +114,19 @@ class NewMessage(EventBuilder): | ||||||
| 
 | 
 | ||||||
|     class Event(EventCommon): |     class Event(EventCommon): | ||||||
|         """ |         """ | ||||||
|         Represents the event of a new message. |         Represents the event of a new message. This event can be treated | ||||||
|  |         to all effects as a `telethon.tl.custom.message.Message`, so please | ||||||
|  |         **refer to its documentation** to know what you can do with this event. | ||||||
| 
 | 
 | ||||||
|         Members: |         Members: | ||||||
|             message (:tl:`Message`): |             message (:tl:`Message`): | ||||||
|                 This is the original :tl:`Message` object. |                 This is the only difference with the received | ||||||
|  |                 `telethon.tl.custom.message.Message`, and will | ||||||
|  |                 return the `telethon.tl.custom.message.Message` itself, | ||||||
|  |                 not the text. | ||||||
| 
 | 
 | ||||||
|             is_private (`bool`): |                 See `telethon.tl.custom.message.Message` for the rest of | ||||||
|                 True if the message was sent as a private message. |                 available members and methods. | ||||||
| 
 |  | ||||||
|             is_group (`bool`): |  | ||||||
|                 True if the message was sent on a group or megagroup. |  | ||||||
| 
 |  | ||||||
|             is_channel (`bool`): |  | ||||||
|                 True if the message was sent on a megagroup or channel. |  | ||||||
| 
 |  | ||||||
|             is_reply (`str`): |  | ||||||
|                 Whether the message is a reply to some other or not. |  | ||||||
|         """ |         """ | ||||||
|         def __init__(self, message): |         def __init__(self, message): | ||||||
|             if not message.out and isinstance(message.to_id, types.PeerUser): |             if not message.out and isinstance(message.to_id, types.PeerUser): | ||||||
|  | @ -146,282 +140,11 @@ class NewMessage(EventBuilder): | ||||||
|                              msg_id=message.id, broadcast=bool(message.post)) |                              msg_id=message.id, broadcast=bool(message.post)) | ||||||
| 
 | 
 | ||||||
|             self.message = message |             self.message = message | ||||||
|             self._text = None |  | ||||||
| 
 |  | ||||||
|             self._input_sender = None |  | ||||||
|             self._sender = None |  | ||||||
| 
 |  | ||||||
|             self.is_reply = bool(message.reply_to_msg_id) |  | ||||||
|             self._reply_message = None |  | ||||||
| 
 | 
 | ||||||
|         def _set_client(self, client): |         def _set_client(self, client): | ||||||
|             super()._set_client(client) |             super()._set_client(client) | ||||||
|             self.message = custom.Message( |             self.message = custom.Message( | ||||||
|                 client, self.message, self._entities, None) |                 client, self.message, self._entities, None) | ||||||
| 
 | 
 | ||||||
|         def respond(self, *args, **kwargs): |         def __getattr__(self, item): | ||||||
|             """ |             return getattr(self.message, item) | ||||||
|             Responds to the message (not as a reply). Shorthand for |  | ||||||
|             `telethon.telegram_client.TelegramClient.send_message` with |  | ||||||
|             ``entity`` already set. |  | ||||||
|             """ |  | ||||||
|             return self._client.send_message(self.input_chat, *args, **kwargs) |  | ||||||
| 
 |  | ||||||
|         def reply(self, *args, **kwargs): |  | ||||||
|             """ |  | ||||||
|             Replies to the message (as a reply). Shorthand for |  | ||||||
|             `telethon.telegram_client.TelegramClient.send_message` with |  | ||||||
|             both ``entity`` and ``reply_to`` already set. |  | ||||||
|             """ |  | ||||||
|             kwargs['reply_to'] = self.message.id |  | ||||||
|             return self._client.send_message(self.input_chat, *args, **kwargs) |  | ||||||
| 
 |  | ||||||
|         def forward_to(self, *args, **kwargs): |  | ||||||
|             """ |  | ||||||
|             Forwards the message. Shorthand for |  | ||||||
|             `telethon.telegram_client.TelegramClient.forward_messages` with |  | ||||||
|             both ``messages`` and ``from_peer`` already set. |  | ||||||
|             """ |  | ||||||
|             kwargs['messages'] = self.message.id |  | ||||||
|             kwargs['from_peer'] = self.input_chat |  | ||||||
|             return self._client.forward_messages(*args, **kwargs) |  | ||||||
| 
 |  | ||||||
|         def edit(self, *args, **kwargs): |  | ||||||
|             """ |  | ||||||
|             Edits the message iff it's outgoing. Shorthand for |  | ||||||
|             `telethon.telegram_client.TelegramClient.edit_message` with |  | ||||||
|             both ``entity`` and ``message`` already set. |  | ||||||
| 
 |  | ||||||
|             Returns ``None`` if the message was incoming, or the edited |  | ||||||
|             :tl:`Message` otherwise. |  | ||||||
|             """ |  | ||||||
|             if self.message.fwd_from: |  | ||||||
|                 return None |  | ||||||
|             if not self.message.out: |  | ||||||
|                 if not isinstance(self.message.to_id, types.PeerUser): |  | ||||||
|                     return None |  | ||||||
|                 me = self._client.get_me(input_peer=True) |  | ||||||
|                 if self.message.to_id.user_id != me.user_id: |  | ||||||
|                     return None |  | ||||||
| 
 |  | ||||||
|             return self._client.edit_message(self.input_chat, |  | ||||||
|                                              self.message, |  | ||||||
|                                              *args, **kwargs) |  | ||||||
| 
 |  | ||||||
|         def delete(self, *args, **kwargs): |  | ||||||
|             """ |  | ||||||
|             Deletes the message. You're responsible for checking whether you |  | ||||||
|             have the permission to do so, or to except the error otherwise. |  | ||||||
|             Shorthand for |  | ||||||
|             `telethon.telegram_client.TelegramClient.delete_messages` with |  | ||||||
|             ``entity`` and ``message_ids`` already set. |  | ||||||
|             """ |  | ||||||
|             return self._client.delete_messages(self.input_chat, |  | ||||||
|                                                 [self.message], |  | ||||||
|                                                 *args, **kwargs) |  | ||||||
| 
 |  | ||||||
|         @property |  | ||||||
|         def input_sender(self): |  | ||||||
|             """ |  | ||||||
|             This (:tl:`InputPeer`) is the input version of the user who |  | ||||||
|             sent the message. Similarly to ``input_chat``, this doesn't have |  | ||||||
|             things like username or similar, but still useful in some cases. |  | ||||||
| 
 |  | ||||||
|             Note that this might not be available if the library can't |  | ||||||
|             find the input chat, or if the message a broadcast on a channel. |  | ||||||
|             """ |  | ||||||
|             if self._input_sender is None: |  | ||||||
|                 if self.is_channel and not self.is_group: |  | ||||||
|                     return None |  | ||||||
| 
 |  | ||||||
|                 try: |  | ||||||
|                     self._input_sender = self._client.get_input_entity( |  | ||||||
|                         self.message.from_id |  | ||||||
|                     ) |  | ||||||
|                 except (ValueError, TypeError): |  | ||||||
|                     # We can rely on self.input_chat for this |  | ||||||
|                     self._sender, self._input_sender = self._get_entity( |  | ||||||
|                         self.message.id, |  | ||||||
|                         self.message.from_id, |  | ||||||
|                         chat=self.input_chat |  | ||||||
|                     ) |  | ||||||
| 
 |  | ||||||
|             return self._input_sender |  | ||||||
| 
 |  | ||||||
|         @property |  | ||||||
|         def sender(self): |  | ||||||
|             """ |  | ||||||
|             This (:tl:`User`) may make an API call the first time to get |  | ||||||
|             the most up to date version of the sender (mostly when the event |  | ||||||
|             doesn't belong to a channel), so keep that in mind. |  | ||||||
| 
 |  | ||||||
|             ``input_sender`` needs to be available (often the case). |  | ||||||
|             """ |  | ||||||
|             if not self.input_sender: |  | ||||||
|                 return None |  | ||||||
| 
 |  | ||||||
|             if self._sender is None: |  | ||||||
|                 self._sender = \ |  | ||||||
|                     self._entities.get(utils.get_peer_id(self._input_sender)) |  | ||||||
| 
 |  | ||||||
|             if self._sender is None: |  | ||||||
|                 self._sender = self._client.get_entity(self._input_sender) |  | ||||||
| 
 |  | ||||||
|             return self._sender |  | ||||||
| 
 |  | ||||||
|         @property |  | ||||||
|         def sender_id(self): |  | ||||||
|             """ |  | ||||||
|             Returns the marked sender integer ID, if present. |  | ||||||
|             """ |  | ||||||
|             return self.message.from_id |  | ||||||
| 
 |  | ||||||
|         @property |  | ||||||
|         def text(self): |  | ||||||
|             """ |  | ||||||
|             The message text, markdown-formatted. |  | ||||||
|             """ |  | ||||||
|             if self._text is None: |  | ||||||
|                 if not self.message.entities: |  | ||||||
|                     return self.message.message |  | ||||||
|                 self._text = markdown.unparse(self.message.message, |  | ||||||
|                                               self.message.entities or []) |  | ||||||
|             return self._text |  | ||||||
| 
 |  | ||||||
|         @property |  | ||||||
|         def raw_text(self): |  | ||||||
|             """ |  | ||||||
|             The raw message text, ignoring any formatting. |  | ||||||
|             """ |  | ||||||
|             return self.message.message |  | ||||||
| 
 |  | ||||||
|         @property |  | ||||||
|         def reply_message(self): |  | ||||||
|             """ |  | ||||||
|             This optional :tl:`Message` will make an API call the first |  | ||||||
|             time to get the full :tl:`Message` object that one was replying to, |  | ||||||
|             so use with care as there is no caching besides local caching yet. |  | ||||||
|             """ |  | ||||||
|             if not self.message.reply_to_msg_id: |  | ||||||
|                 return None |  | ||||||
| 
 |  | ||||||
|             if self._reply_message is None: |  | ||||||
|                 if isinstance(self.input_chat, types.InputPeerChannel): |  | ||||||
|                     r = self._client(functions.channels.GetMessagesRequest( |  | ||||||
|                         self.input_chat, [self.message.reply_to_msg_id] |  | ||||||
|                     )) |  | ||||||
|                 else: |  | ||||||
|                     r = self._client(functions.messages.GetMessagesRequest( |  | ||||||
|                         [self.message.reply_to_msg_id] |  | ||||||
|                     )) |  | ||||||
|                 if not isinstance(r, types.messages.MessagesNotModified): |  | ||||||
|                     self._reply_message = r.messages[0] |  | ||||||
| 
 |  | ||||||
|             return self._reply_message |  | ||||||
| 
 |  | ||||||
|         @property |  | ||||||
|         def forward(self): |  | ||||||
|             """ |  | ||||||
|             The unmodified :tl:`MessageFwdHeader`, if present.. |  | ||||||
|             """ |  | ||||||
|             return self.message.fwd_from |  | ||||||
| 
 |  | ||||||
|         @property |  | ||||||
|         def media(self): |  | ||||||
|             """ |  | ||||||
|             The unmodified :tl:`MessageMedia`, if present. |  | ||||||
|             """ |  | ||||||
|             return self.message.media |  | ||||||
| 
 |  | ||||||
|         @property |  | ||||||
|         def photo(self): |  | ||||||
|             """ |  | ||||||
|             If the message media is a photo, |  | ||||||
|             this returns the :tl:`Photo` object. |  | ||||||
|             """ |  | ||||||
|             if isinstance(self.message.media, types.MessageMediaPhoto): |  | ||||||
|                 photo = self.message.media.photo |  | ||||||
|                 if isinstance(photo, types.Photo): |  | ||||||
|                     return photo |  | ||||||
| 
 |  | ||||||
|         @property |  | ||||||
|         def document(self): |  | ||||||
|             """ |  | ||||||
|             If the message media is a document, |  | ||||||
|             this returns the :tl:`Document` object. |  | ||||||
|             """ |  | ||||||
|             if isinstance(self.message.media, types.MessageMediaDocument): |  | ||||||
|                 doc = self.message.media.document |  | ||||||
|                 if isinstance(doc, types.Document): |  | ||||||
|                     return doc |  | ||||||
| 
 |  | ||||||
|         def _document_by_attribute(self, kind, condition=None): |  | ||||||
|             """ |  | ||||||
|             Helper method to return the document only if it has an attribute |  | ||||||
|             that's an instance of the given kind, and passes the condition. |  | ||||||
|             """ |  | ||||||
|             doc = self.document |  | ||||||
|             if doc: |  | ||||||
|                 for attr in doc.attributes: |  | ||||||
|                     if isinstance(attr, kind): |  | ||||||
|                         if not condition or condition(doc): |  | ||||||
|                             return doc |  | ||||||
| 
 |  | ||||||
|         @property |  | ||||||
|         def audio(self): |  | ||||||
|             """ |  | ||||||
|             If the message media is a document with an Audio attribute, |  | ||||||
|             this returns the :tl:`Document` object. |  | ||||||
|             """ |  | ||||||
|             return self._document_by_attribute(types.DocumentAttributeAudio, |  | ||||||
|                                                lambda attr: not attr.voice) |  | ||||||
| 
 |  | ||||||
|         @property |  | ||||||
|         def voice(self): |  | ||||||
|             """ |  | ||||||
|             If the message media is a document with a Voice attribute, |  | ||||||
|             this returns the :tl:`Document` object. |  | ||||||
|             """ |  | ||||||
|             return self._document_by_attribute(types.DocumentAttributeAudio, |  | ||||||
|                                                lambda attr: attr.voice) |  | ||||||
| 
 |  | ||||||
|         @property |  | ||||||
|         def video(self): |  | ||||||
|             """ |  | ||||||
|             If the message media is a document with a Video attribute, |  | ||||||
|             this returns the :tl:`Document` object. |  | ||||||
|             """ |  | ||||||
|             return self._document_by_attribute(types.DocumentAttributeVideo) |  | ||||||
| 
 |  | ||||||
|         @property |  | ||||||
|         def video_note(self): |  | ||||||
|             """ |  | ||||||
|             If the message media is a document with a Video attribute, |  | ||||||
|             this returns the :tl:`Document` object. |  | ||||||
|             """ |  | ||||||
|             return self._document_by_attribute(types.DocumentAttributeVideo, |  | ||||||
|                                                lambda attr: attr.round_message) |  | ||||||
| 
 |  | ||||||
|         @property |  | ||||||
|         def gif(self): |  | ||||||
|             """ |  | ||||||
|             If the message media is a document with an Animated attribute, |  | ||||||
|             this returns the :tl:`Document` object. |  | ||||||
|             """ |  | ||||||
|             return self._document_by_attribute(types.DocumentAttributeAnimated) |  | ||||||
| 
 |  | ||||||
|         @property |  | ||||||
|         def sticker(self): |  | ||||||
|             """ |  | ||||||
|             If the message media is a document with a Sticker attribute, |  | ||||||
|             this returns the :tl:`Document` object. |  | ||||||
|             """ |  | ||||||
|             return self._document_by_attribute(types.DocumentAttributeSticker) |  | ||||||
| 
 |  | ||||||
|         @property |  | ||||||
|         def out(self): |  | ||||||
|             """ |  | ||||||
|             Whether the message is outgoing (i.e. you sent it from |  | ||||||
|             another session) or incoming (i.e. someone else sent it). |  | ||||||
|             """ |  | ||||||
|             return self.message.out |  | ||||||
|  |  | ||||||
|  | @ -25,11 +25,14 @@ class Message: | ||||||
|         self.to_dict = self.original_message.to_dict |         self.to_dict = self.original_message.to_dict | ||||||
|         self._client = client |         self._client = client | ||||||
|         self._text = None |         self._text = None | ||||||
|         self._reply_to = None |         self._reply_message = None | ||||||
|         self._buttons = None |         self._buttons = None | ||||||
|         self._buttons_flat = None |         self._buttons_flat = None | ||||||
|         self._sender = entities.get(self.original_message.from_id) |         self._sender = entities.get(self.original_message.from_id) | ||||||
|         self._chat = entities.get(get_peer_id(self.original_message.to_id)) |         self._chat = entities.get(get_peer_id(self.original_message.to_id)) | ||||||
|  |         if self._sender: | ||||||
|  |             self._input_sender = get_input_peer(self._sender) | ||||||
|  |         else: | ||||||
|             self._input_sender = None |             self._input_sender = None | ||||||
|         self._input_chat = input_chat |         self._input_chat = input_chat | ||||||
|         self._fwd_from_entity = None |         self._fwd_from_entity = None | ||||||
|  | @ -105,46 +108,128 @@ class Message: | ||||||
|         if isinstance(self.original_message, types.MessageService): |         if isinstance(self.original_message, types.MessageService): | ||||||
|             return self.original_message.action |             return self.original_message.action | ||||||
| 
 | 
 | ||||||
|  |     def _reload_message(self): | ||||||
|  |         """ | ||||||
|  |         Re-fetches this message to reload the sender and chat entities, | ||||||
|  |         along with their input versions. | ||||||
|  |         """ | ||||||
|  |         try: | ||||||
|  |             chat = self.input_chat if self.is_channel else None | ||||||
|  |             msg = self._client.get_messages(chat, ids=self.original_message.id) | ||||||
|  |         except ValueError: | ||||||
|  |             return  # We may not have the input chat/get message failed | ||||||
|  |         if not msg: | ||||||
|  |             return  # The message may be deleted and it will be None | ||||||
|  | 
 | ||||||
|  |         self._sender = msg._sender | ||||||
|  |         self._input_sender = msg._input_sender | ||||||
|  |         self._chat = msg._chat | ||||||
|  |         self._input_chat = msg._input_chat | ||||||
|  | 
 | ||||||
|     @property |     @property | ||||||
|     def sender(self): |     def sender(self): | ||||||
|  |         """ | ||||||
|  |         This (:tl:`User`) may make an API call the first time to get | ||||||
|  |         the most up to date version of the sender (mostly when the event | ||||||
|  |         doesn't belong to a channel), so keep that in mind. | ||||||
|  | 
 | ||||||
|  |         `input_sender` needs to be available (often the case). | ||||||
|  |         """ | ||||||
|         if self._sender is None: |         if self._sender is None: | ||||||
|  |             try: | ||||||
|                 self._sender = self._client.get_entity(self.input_sender) |                 self._sender = self._client.get_entity(self.input_sender) | ||||||
|  |             except ValueError: | ||||||
|  |                 self._reload_message() | ||||||
|         return self._sender |         return self._sender | ||||||
| 
 | 
 | ||||||
|     @property |     @property | ||||||
|     def chat(self): |     def chat(self): | ||||||
|         if self._chat is None: |         if self._chat is None: | ||||||
|  |             try: | ||||||
|                 self._chat = self._client.get_entity(self.input_chat) |                 self._chat = self._client.get_entity(self.input_chat) | ||||||
|  |             except ValueError: | ||||||
|  |                 self._reload_message() | ||||||
|         return self._chat |         return self._chat | ||||||
| 
 | 
 | ||||||
|     @property |     @property | ||||||
|     def input_sender(self): |     def input_sender(self): | ||||||
|  |         """ | ||||||
|  |         This (:tl:`InputPeer`) is the input version of the user who | ||||||
|  |         sent the message. Similarly to `input_chat`, this doesn't have | ||||||
|  |         things like username or similar, but still useful in some cases. | ||||||
|  | 
 | ||||||
|  |         Note that this might not be available if the library can't | ||||||
|  |         find the input chat, or if the message a broadcast on a channel. | ||||||
|  |         """ | ||||||
|         if self._input_sender is None: |         if self._input_sender is None: | ||||||
|  |             if self.is_channel and not self.is_group: | ||||||
|  |                 return None | ||||||
|             if self._sender is not None: |             if self._sender is not None: | ||||||
|                 self._input_sender = get_input_peer(self._sender) |                 self._input_sender = get_input_peer(self._sender) | ||||||
|             else: |             else: | ||||||
|  |                 try: | ||||||
|                     self._input_sender = self._client.get_input_entity( |                     self._input_sender = self._client.get_input_entity( | ||||||
|                         self.original_message.from_id) |                         self.original_message.from_id) | ||||||
|  |                 except ValueError: | ||||||
|  |                     self._reload_message() | ||||||
|         return self._input_sender |         return self._input_sender | ||||||
| 
 | 
 | ||||||
|     @property |     @property | ||||||
|     def input_chat(self): |     def input_chat(self): | ||||||
|         if self._input_chat is None: |         if self._input_chat is None: | ||||||
|             if self._chat is not None: |             if self._chat is None: | ||||||
|                 self._chat = get_input_peer(self._chat) |                 try: | ||||||
|             else: |  | ||||||
|                     self._chat = self._client.get_input_entity( |                     self._chat = self._client.get_input_entity( | ||||||
|                         self.original_message.to_id) |                         self.original_message.to_id) | ||||||
|  |                 except ValueError: | ||||||
|  |                     # There's a chance that the chat is a recent new dialog. | ||||||
|  |                     # The input chat cannot rely on ._reload_message() because | ||||||
|  |                     # said method may need the input chat. | ||||||
|  |                     target = self.chat_id | ||||||
|  |                     for d in self._client.iter_dialogs(100): | ||||||
|  |                         if d.id == target: | ||||||
|  |                             self._chat = d.entity | ||||||
|  |                             break | ||||||
|  |             if self._chat is not None: | ||||||
|  |                 self._input_chat = get_input_peer(self._chat) | ||||||
|  | 
 | ||||||
|         return self._input_chat |         return self._input_chat | ||||||
| 
 | 
 | ||||||
|     @property |     @property | ||||||
|     def user_id(self): |     def sender_id(self): | ||||||
|  |         """ | ||||||
|  |         Returns the marked sender integer ID, if present. | ||||||
|  |         """ | ||||||
|         return self.original_message.from_id |         return self.original_message.from_id | ||||||
| 
 | 
 | ||||||
|     @property |     @property | ||||||
|     def chat_id(self): |     def chat_id(self): | ||||||
|  |         """ | ||||||
|  |         Returns the marked chat integer ID. | ||||||
|  |         """ | ||||||
|         return get_peer_id(self.original_message.to_id) |         return get_peer_id(self.original_message.to_id) | ||||||
| 
 | 
 | ||||||
|  |     @property | ||||||
|  |     def is_private(self): | ||||||
|  |         """True if the message was sent as a private message.""" | ||||||
|  |         return isinstance(self.original_message.to_id, types.PeerUser) | ||||||
|  | 
 | ||||||
|  |     @property | ||||||
|  |     def is_group(self): | ||||||
|  |         """True if the message was sent on a group or megagroup.""" | ||||||
|  |         return not self.original_message.broadcast and isinstance( | ||||||
|  |             self.original_message.to_id, (types.PeerChat, types.PeerChannel)) | ||||||
|  | 
 | ||||||
|  |     @property | ||||||
|  |     def is_channel(self): | ||||||
|  |         """True if the message was sent on a megagroup or channel.""" | ||||||
|  |         return isinstance(self.original_message.to_id, types.PeerChannel) | ||||||
|  | 
 | ||||||
|  |     @property | ||||||
|  |     def is_reply(self): | ||||||
|  |         """True if the message is a reply to some other or not.""" | ||||||
|  |         return bool(self.original_message.reply_to_msg_id) | ||||||
|  | 
 | ||||||
|     @property |     @property | ||||||
|     def buttons(self): |     def buttons(self): | ||||||
|         """ |         """ | ||||||
|  | @ -170,21 +255,116 @@ class Message: | ||||||
|         return len(self._buttons_flat) if self.buttons else 0 |         return len(self._buttons_flat) if self.buttons else 0 | ||||||
| 
 | 
 | ||||||
|     @property |     @property | ||||||
|     def reply_to(self): |     def photo(self): | ||||||
|  |         """ | ||||||
|  |         If the message media is a photo, | ||||||
|  |         this returns the :tl:`Photo` object. | ||||||
|  |         """ | ||||||
|  |         if isinstance(self.original_message.media, types.MessageMediaPhoto): | ||||||
|  |             photo = self.original_message.media.photo | ||||||
|  |             if isinstance(photo, types.Photo): | ||||||
|  |                 return photo | ||||||
|  | 
 | ||||||
|  |     @property | ||||||
|  |     def document(self): | ||||||
|  |         """ | ||||||
|  |         If the message media is a document, | ||||||
|  |         this returns the :tl:`Document` object. | ||||||
|  |         """ | ||||||
|  |         if isinstance(self.original_message.media, types.MessageMediaDocument): | ||||||
|  |             doc = self.original_message.media.document | ||||||
|  |             if isinstance(doc, types.Document): | ||||||
|  |                 return doc | ||||||
|  | 
 | ||||||
|  |     def _document_by_attribute(self, kind, condition=None): | ||||||
|  |         """ | ||||||
|  |         Helper method to return the document only if it has an attribute | ||||||
|  |         that's an instance of the given kind, and passes the condition. | ||||||
|  |         """ | ||||||
|  |         doc = self.document | ||||||
|  |         if doc: | ||||||
|  |             for attr in doc.attributes: | ||||||
|  |                 if isinstance(attr, kind): | ||||||
|  |                     if not condition or condition(doc): | ||||||
|  |                         return doc | ||||||
|  | 
 | ||||||
|  |     @property | ||||||
|  |     def audio(self): | ||||||
|  |         """ | ||||||
|  |         If the message media is a document with an Audio attribute, | ||||||
|  |         this returns the :tl:`Document` object. | ||||||
|  |         """ | ||||||
|  |         return self._document_by_attribute(types.DocumentAttributeAudio, | ||||||
|  |                                            lambda attr: not attr.voice) | ||||||
|  | 
 | ||||||
|  |     @property | ||||||
|  |     def voice(self): | ||||||
|  |         """ | ||||||
|  |         If the message media is a document with a Voice attribute, | ||||||
|  |         this returns the :tl:`Document` object. | ||||||
|  |         """ | ||||||
|  |         return self._document_by_attribute(types.DocumentAttributeAudio, | ||||||
|  |                                            lambda attr: attr.voice) | ||||||
|  | 
 | ||||||
|  |     @property | ||||||
|  |     def video(self): | ||||||
|  |         """ | ||||||
|  |         If the message media is a document with a Video attribute, | ||||||
|  |         this returns the :tl:`Document` object. | ||||||
|  |         """ | ||||||
|  |         return self._document_by_attribute(types.DocumentAttributeVideo) | ||||||
|  | 
 | ||||||
|  |     @property | ||||||
|  |     def video_note(self): | ||||||
|  |         """ | ||||||
|  |         If the message media is a document with a Video attribute, | ||||||
|  |         this returns the :tl:`Document` object. | ||||||
|  |         """ | ||||||
|  |         return self._document_by_attribute(types.DocumentAttributeVideo, | ||||||
|  |                                            lambda attr: attr.round_message) | ||||||
|  | 
 | ||||||
|  |     @property | ||||||
|  |     def gif(self): | ||||||
|  |         """ | ||||||
|  |         If the message media is a document with an Animated attribute, | ||||||
|  |         this returns the :tl:`Document` object. | ||||||
|  |         """ | ||||||
|  |         return self._document_by_attribute(types.DocumentAttributeAnimated) | ||||||
|  | 
 | ||||||
|  |     @property | ||||||
|  |     def sticker(self): | ||||||
|  |         """ | ||||||
|  |         If the message media is a document with a Sticker attribute, | ||||||
|  |         this returns the :tl:`Document` object. | ||||||
|  |         """ | ||||||
|  |         return self._document_by_attribute(types.DocumentAttributeSticker) | ||||||
|  | 
 | ||||||
|  |     @property | ||||||
|  |     def out(self): | ||||||
|  |         """ | ||||||
|  |         Whether the message is outgoing (i.e. you sent it from | ||||||
|  |         another session) or incoming (i.e. someone else sent it). | ||||||
|  |         """ | ||||||
|  |         return self.original_message.out | ||||||
|  | 
 | ||||||
|  |     @property | ||||||
|  |     def reply_message(self): | ||||||
|         """ |         """ | ||||||
|         The :tl:`Message` that this message is replying to, or ``None``. |         The :tl:`Message` that this message is replying to, or ``None``. | ||||||
| 
 | 
 | ||||||
|         Note that this will make a network call to fetch the message and |         Note that this will make a network call to fetch the message and | ||||||
|         will later be cached. |         will later be cached. | ||||||
|         """ |         """ | ||||||
|         if self._reply_to is None: |         if self._reply_message is None: | ||||||
|             if not self.original_message.reply_to_msg_id: |             if not self.original_message.reply_to_msg_id: | ||||||
|                 return None |                 return None | ||||||
|             self._reply_to = self._client.get_messages( |             self._reply_message = self._client.get_messages( | ||||||
|                 self.original_message.to_id, |                 self.input_chat if self.is_channel else None, | ||||||
|                 ids=self.original_message.reply_to_msg_id |                 ids=self.original_message.reply_to_msg_id | ||||||
|             ) |             ) | ||||||
| 
 | 
 | ||||||
|  |         return self._reply_message | ||||||
|  | 
 | ||||||
|     @property |     @property | ||||||
|     def fwd_from_entity(self): |     def fwd_from_entity(self): | ||||||
|         """ |         """ | ||||||
|  | @ -202,8 +382,14 @@ class Message: | ||||||
|                         get_peer_id(types.PeerChannel(fwd.channel_id))) |                         get_peer_id(types.PeerChannel(fwd.channel_id))) | ||||||
|         return self._fwd_from_entity |         return self._fwd_from_entity | ||||||
| 
 | 
 | ||||||
|     # TODO events.NewMessage and this class share a lot of code; merge them? |     def respond(self, *args, **kwargs): | ||||||
|     # Can we consider the event of a new message to be a message in itself? |         """ | ||||||
|  |         Responds to the message (not as a reply). Shorthand for | ||||||
|  |         `telethon.telegram_client.TelegramClient.send_message` with | ||||||
|  |         ``entity`` already set. | ||||||
|  |         """ | ||||||
|  |         return self._client.send_message(self.input_chat, *args, **kwargs) | ||||||
|  | 
 | ||||||
|     def reply(self, *args, **kwargs): |     def reply(self, *args, **kwargs): | ||||||
|         """ |         """ | ||||||
|         Replies to the message (as a reply). Shorthand for |         Replies to the message (as a reply). Shorthand for | ||||||
|  | @ -214,6 +400,20 @@ class Message: | ||||||
|         return self._client.send_message(self.original_message.to_id, |         return self._client.send_message(self.original_message.to_id, | ||||||
|                                          *args, **kwargs) |                                          *args, **kwargs) | ||||||
| 
 | 
 | ||||||
|  |     def forward_to(self, *args, **kwargs): | ||||||
|  |         """ | ||||||
|  |         Forwards the message. Shorthand for | ||||||
|  |         `telethon.telegram_client.TelegramClient.forward_messages` with | ||||||
|  |         both ``messages`` and ``from_peer`` already set. | ||||||
|  | 
 | ||||||
|  |         If you need to forward more than one message at once, don't use | ||||||
|  |         this `forward_to` method. Use a | ||||||
|  |         `telethon.telegram_client.TelegramClient` instance directly. | ||||||
|  |         """ | ||||||
|  |         kwargs['messages'] = self.original_message.id | ||||||
|  |         kwargs['from_peer'] = self.input_chat | ||||||
|  |         return self._client.forward_messages(*args, **kwargs) | ||||||
|  | 
 | ||||||
|     def edit(self, *args, **kwargs): |     def edit(self, *args, **kwargs): | ||||||
|         """ |         """ | ||||||
|         Edits the message iff it's outgoing. Shorthand for |         Edits the message iff it's outgoing. Shorthand for | ||||||
|  | @ -242,6 +442,10 @@ class Message: | ||||||
|         Shorthand for |         Shorthand for | ||||||
|         `telethon.telegram_client.TelegramClient.delete_messages` with |         `telethon.telegram_client.TelegramClient.delete_messages` with | ||||||
|         ``entity`` and ``message_ids`` already set. |         ``entity`` and ``message_ids`` already set. | ||||||
|  | 
 | ||||||
|  |         If you need to delete more than one message at once, don't use | ||||||
|  |         this `delete` method. Use a | ||||||
|  |         `telethon.telegram_client.TelegramClient` instance directly. | ||||||
|         """ |         """ | ||||||
|         return self._client.delete_messages( |         return self._client.delete_messages( | ||||||
|             self.input_chat, [self.original_message], *args, **kwargs) |             self.input_chat, [self.original_message], *args, **kwargs) | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user