mirror of
				https://github.com/LonamiWebs/Telethon.git
				synced 2025-10-31 16:07:44 +03:00 
			
		
		
		
	Add a NewMessage event to handle incoming messages
This commit is contained in:
		
							parent
							
								
									5ec984dd82
								
							
						
					
					
						commit
						ef837b1a53
					
				|  | @ -12,3 +12,243 @@ class _EventBuilder(abc.ABC): | |||
|     @abc.abstractmethod | ||||
|     def resolve(self, client): | ||||
|         """Helper method to allow event builders to be resolved before usage""" | ||||
| 
 | ||||
| 
 | ||||
| # Classes defined here are actually Event builders | ||||
| # for their inner Event classes. Inner ._client is | ||||
| # set later by the creator TelegramClient. | ||||
| class NewMessage(_EventBuilder): | ||||
|     """ | ||||
|     Represents a new message event builder. | ||||
| 
 | ||||
|     Args: | ||||
|         incoming (:obj:`bool`, optional): | ||||
|             If set to ``True``, only **incoming** messages will be handled. | ||||
|             Mutually exclusive with ``outgoing`` (can only set one of either). | ||||
| 
 | ||||
|         outgoing (:obj:`bool`, optional): | ||||
|             If set to ``True``, only **outgoing** messages will be handled. | ||||
|             Mutually exclusive with ``incoming`` (can only set one of either). | ||||
| 
 | ||||
|         chats (:obj:`entity`, optional): | ||||
|             May be one or more entities (username/peer/etc.). By default, | ||||
|             only matching chats will be handled. | ||||
| 
 | ||||
|         blacklist_chats (:obj:`bool`, optional): | ||||
|             Whether to treat the the list of chats as a blacklist (if | ||||
|             it matches it will NOT be handled) or a whitelist (default). | ||||
|     """ | ||||
|     def __init__(self, incoming=None, outgoing=None, | ||||
|                  chats=None, blacklist_chats=False, | ||||
|                  require_input=True): | ||||
|         if incoming and outgoing: | ||||
|             raise ValueError('Can only set either incoming or outgoing') | ||||
| 
 | ||||
|         self.incoming = incoming | ||||
|         self.outgoing = outgoing | ||||
|         self.chats = chats | ||||
|         self.blacklist_chats = blacklist_chats | ||||
| 
 | ||||
|     def resolve(self, client): | ||||
|         if hasattr(self.chats, '__iter__') and not isinstance(self.chats, str): | ||||
|             self.chats = set(utils.get_peer_id(x) | ||||
|                              for x in client.get_input_entity(self.chats)) | ||||
|         elif self.chats is not None: | ||||
|             self.chats = {utils.get_peer_id( | ||||
|                           client.get_input_entity(self.chats))} | ||||
| 
 | ||||
|     def build(self, update): | ||||
|         if isinstance(update, | ||||
|                       (types.UpdateNewMessage, types.UpdateNewChannelMessage)): | ||||
|             event = NewMessage.Event(update.message) | ||||
|         elif isinstance(update, types.UpdateShortMessage): | ||||
|             event = NewMessage.Event(types.Message( | ||||
|                 out=update.out, | ||||
|                 mentioned=update.mentioned, | ||||
|                 media_unread=update.media_unread, | ||||
|                 silent=update.silent, | ||||
|                 id=update.id, | ||||
|                 to_id=types.PeerUser(update.user_id), | ||||
|                 message=update.message, | ||||
|                 date=update.date, | ||||
|                 fwd_from=update.fwd_from, | ||||
|                 via_bot_id=update.via_bot_id, | ||||
|                 reply_to_msg_id=update.reply_to_msg_id, | ||||
|                 entities=update.entities | ||||
|             )) | ||||
|         else: | ||||
|             return | ||||
| 
 | ||||
|         # Short-circuit if we let pass all events | ||||
|         if all(x is None for x in (self.incoming, self.outgoing, self.chats)): | ||||
|             return event | ||||
| 
 | ||||
|         if self.incoming and event.message.out: | ||||
|             return | ||||
|         if self.outgoing and not event.message.out: | ||||
|             return | ||||
| 
 | ||||
|         if self.chats is not None: | ||||
|             inside = utils.get_peer_id(event.input_chat) in self.chats | ||||
|             if inside == self.blacklist_chats: | ||||
|                 # If this chat matches but it's a blacklist ignore. | ||||
|                 # If it doesn't match but it's a whitelist ignore. | ||||
|                 return | ||||
| 
 | ||||
|         # Tests passed so return the event | ||||
|         return event | ||||
| 
 | ||||
|     class Event: | ||||
|         """ | ||||
|         Represents the event of a new message. | ||||
| 
 | ||||
|         Members: | ||||
|             message (:obj:`Message`): | ||||
|                 This is the original ``Message`` object. | ||||
| 
 | ||||
|             input_chat (:obj:`InputPeer`): | ||||
|                 This is the input chat (private, group, megagroup or channel) | ||||
|                 to which the message was sent. This doesn't have the title or | ||||
|                 anything, but is useful if you don't need those to avoid | ||||
|                 further requests. | ||||
| 
 | ||||
|                 Note that this might not be available if the library can't | ||||
|                 find the input chat. | ||||
| 
 | ||||
|             chat (:obj:`User` | :obj:`Chat` | :obj:`Channel`, optional): | ||||
|                 This property will make an API call the first time to get the | ||||
|                 most up to date version of the chat, so use with care as | ||||
|                 there is no caching besides local caching yet. | ||||
| 
 | ||||
|                 ``input_chat`` needs to be available (often the case). | ||||
| 
 | ||||
|             is_private (:obj:`bool`): | ||||
|                 True if the message was sent as a private message. | ||||
| 
 | ||||
|             is_group (:obj:`bool`): | ||||
|                 True if the message was sent on a group or megagroup. | ||||
| 
 | ||||
|             is_channel (:obj:`bool`): | ||||
|                 True if the message was sent on a megagroup or channel. | ||||
| 
 | ||||
|             input_sender (:obj:`InputPeer`): | ||||
|                 This 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. | ||||
| 
 | ||||
|             sender (:obj:`User`): | ||||
|                 This property will make an API call the first time to get the | ||||
|                 most up to date version of the sender, so use with care as | ||||
|                 there is no caching besides local caching yet. | ||||
| 
 | ||||
|                 ``input_sender`` needs to be available (often the case). | ||||
| 
 | ||||
|             text (:obj:`str`): | ||||
|                 The message text, markdown-formatted. | ||||
| 
 | ||||
|             raw_text (:obj:`str`): | ||||
|                 The raw message text, ignoring any formatting. | ||||
| 
 | ||||
|             is_reply (:obj:`str`): | ||||
|                 Whether the message is a reply to some other or not. | ||||
| 
 | ||||
|             reply_message (:obj:`Message`, optional): | ||||
|                 This property will make an API call the first time to get the | ||||
|                 full ``Message`` object that one was replying to, so use with | ||||
|                 care as there is no caching besides local caching yet. | ||||
| 
 | ||||
|             forward (:obj:`MessageFwdHeader`, optional): | ||||
|                 The unmodified ``MessageFwdHeader``, if present. | ||||
| 
 | ||||
|             out (:obj:`bool`): | ||||
|                 Whether the message is outgoing (i.e. you sent it from | ||||
|                 another session) or incoming (i.e. someone else sent it). | ||||
|         """ | ||||
|         def __init__(self, message): | ||||
|             self._client = None | ||||
|             self.message = message | ||||
|             self._text = None | ||||
| 
 | ||||
|             self._chat = None | ||||
|             self._sender = None | ||||
| 
 | ||||
|             self.is_private = isinstance(message.to_id, types.PeerUser) | ||||
|             self.is_group = ( | ||||
|                 isinstance(message.to_id, (types.PeerChat, types.PeerChannel)) | ||||
|                 and not message.post | ||||
|             ) | ||||
|             self.is_channel = isinstance(message.to_id, types.PeerChannel) | ||||
| 
 | ||||
|             self.is_reply = bool(message.reply_to_msg_id) | ||||
|             self._reply_message = None | ||||
| 
 | ||||
|         def reply(self, message, as_reply=True): | ||||
|             """Replies to this message""" | ||||
|             self._client.send_message(self.message.to_id, message) | ||||
| 
 | ||||
|         @property | ||||
|         def input_chat(self): | ||||
|             # TODO If not found, getMessages to find the sender and chat | ||||
|             return self._client.get_input_entity(self.message.to_id) | ||||
| 
 | ||||
|         @property | ||||
|         def chat(self): | ||||
|             if self._chat is None: | ||||
|                 # TODO Assert input entity is not None to avoid weird errors | ||||
|                 self._chat = self._client.get_entity(self.input_chat) | ||||
|             return self._chat | ||||
| 
 | ||||
|         @property | ||||
|         def input_sender(self): | ||||
|             # TODO If not found, getMessages to find the sender and chat | ||||
|             return self._client.get_input_entity(self.message.from_id) | ||||
| 
 | ||||
|         @property | ||||
|         def sender(self): | ||||
|             if self._sender is None: | ||||
|                 # TODO Assert input entity is not None to avoid weird errors | ||||
|                 self._sender = self._client.get_entity(self.input_sender) | ||||
|             return self._sender | ||||
| 
 | ||||
|         @property | ||||
|         def text(self): | ||||
|             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): | ||||
|             return self.message.message | ||||
| 
 | ||||
|         @property | ||||
|         def reply_message(self): | ||||
|             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): | ||||
|             return self.message.fwd_from | ||||
| 
 | ||||
|         @property | ||||
|         def out(self): | ||||
|             return self.message.out | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user