mirror of
				https://github.com/LonamiWebs/Telethon.git
				synced 2025-11-04 01:47:27 +03:00 
			
		
		
		
	Allow getting messages by their ID
This commit is contained in:
		
							parent
							
								
									6c20f8a2c7
								
							
						
					
					
						commit
						780c66c619
					
				| 
						 | 
					@ -1016,7 +1016,8 @@ class TelegramClient(TelegramBareClient):
 | 
				
			||||||
    def iter_messages(self, entity, limit=None, offset_date=None,
 | 
					    def iter_messages(self, entity, limit=None, offset_date=None,
 | 
				
			||||||
                      offset_id=0, max_id=0, min_id=0, add_offset=0,
 | 
					                      offset_id=0, max_id=0, min_id=0, add_offset=0,
 | 
				
			||||||
                      search=None, filter=None, from_user=None,
 | 
					                      search=None, filter=None, from_user=None,
 | 
				
			||||||
                      batch_size=100, wait_time=None, _total=None):
 | 
					                      batch_size=100, wait_time=None, ids=None,
 | 
				
			||||||
 | 
					                      _total=None):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Iterator over the message history for the specified entity.
 | 
					        Iterator over the message history for the specified entity.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1076,6 +1077,15 @@ class TelegramClient(TelegramBareClient):
 | 
				
			||||||
                If left to ``None``, it will default to 1 second only if
 | 
					                If left to ``None``, it will default to 1 second only if
 | 
				
			||||||
                the limit is higher than 3000.
 | 
					                the limit is higher than 3000.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            ids (`int`, `list`):
 | 
				
			||||||
 | 
					                A single integer ID (or several IDs) for the message that
 | 
				
			||||||
 | 
					                should be returned. This parameter takes precedence over
 | 
				
			||||||
 | 
					                the rest (which will be ignored if this is set). This can
 | 
				
			||||||
 | 
					                for instance be used to get the message with ID 123 from
 | 
				
			||||||
 | 
					                a channel. Note that if the message doesn't exist, ``None``
 | 
				
			||||||
 | 
					                will appear in its place, so that zipping the list of IDs
 | 
				
			||||||
 | 
					                with the messages can match one-to-one.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            _total (`list`, optional):
 | 
					            _total (`list`, optional):
 | 
				
			||||||
                A single-item list to pass the total parameter by reference.
 | 
					                A single-item list to pass the total parameter by reference.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1094,6 +1104,13 @@ class TelegramClient(TelegramBareClient):
 | 
				
			||||||
            an higher limit, so you're free to set the ``batch_size`` that
 | 
					            an higher limit, so you're free to set the ``batch_size`` that
 | 
				
			||||||
            you think may be good.
 | 
					            you think may be good.
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
 | 
					        entity = self.get_input_entity(entity)
 | 
				
			||||||
 | 
					        if ids:
 | 
				
			||||||
 | 
					            if not utils.is_list_like(ids):
 | 
				
			||||||
 | 
					                ids = (ids,)
 | 
				
			||||||
 | 
					            yield from self._iter_ids(entity, ids, total=_total)
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Telegram doesn't like min_id/max_id. If these IDs are low enough
 | 
					        # Telegram doesn't like min_id/max_id. If these IDs are low enough
 | 
				
			||||||
        # (starting from last_id - 100), the request will return nothing.
 | 
					        # (starting from last_id - 100), the request will return nothing.
 | 
				
			||||||
        #
 | 
					        #
 | 
				
			||||||
| 
						 | 
					@ -1104,7 +1121,6 @@ class TelegramClient(TelegramBareClient):
 | 
				
			||||||
            if offset_id - min_id <= 1:
 | 
					            if offset_id - min_id <= 1:
 | 
				
			||||||
                return
 | 
					                return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        entity = self.get_input_entity(entity)
 | 
					 | 
				
			||||||
        limit = float('inf') if limit is None else int(limit)
 | 
					        limit = float('inf') if limit is None else int(limit)
 | 
				
			||||||
        if search is not None or filter or from_user:
 | 
					        if search is not None or filter or from_user:
 | 
				
			||||||
            if filter is None:
 | 
					            if filter is None:
 | 
				
			||||||
| 
						 | 
					@ -1173,27 +1189,7 @@ class TelegramClient(TelegramBareClient):
 | 
				
			||||||
                # IDs are returned in descending order.
 | 
					                # IDs are returned in descending order.
 | 
				
			||||||
                last_id = message.id
 | 
					                last_id = message.id
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                # Add a few extra attributes to the Message to be friendlier.
 | 
					                self._make_message_friendly(message, entities)
 | 
				
			||||||
                # To make messages more friendly, always add message
 | 
					 | 
				
			||||||
                # to service messages, and action to normal messages.
 | 
					 | 
				
			||||||
                message.message = getattr(message, 'message', None)
 | 
					 | 
				
			||||||
                message.action = getattr(message, 'action', None)
 | 
					 | 
				
			||||||
                message.to = entities[utils.get_peer_id(message.to_id)]
 | 
					 | 
				
			||||||
                message.sender = (
 | 
					 | 
				
			||||||
                    None if not message.from_id else
 | 
					 | 
				
			||||||
                    entities[utils.get_peer_id(message.from_id)]
 | 
					 | 
				
			||||||
                )
 | 
					 | 
				
			||||||
                if getattr(message, 'fwd_from', None):
 | 
					 | 
				
			||||||
                    message.fwd_from.sender = (
 | 
					 | 
				
			||||||
                        None if not message.fwd_from.from_id else
 | 
					 | 
				
			||||||
                        entities[utils.get_peer_id(message.fwd_from.from_id)]
 | 
					 | 
				
			||||||
                    )
 | 
					 | 
				
			||||||
                    message.fwd_from.channel = (
 | 
					 | 
				
			||||||
                        None if not message.fwd_from.channel_id else
 | 
					 | 
				
			||||||
                        entities[utils.get_peer_id(
 | 
					 | 
				
			||||||
                            PeerChannel(message.fwd_from.channel_id)
 | 
					 | 
				
			||||||
                        )]
 | 
					 | 
				
			||||||
                    )
 | 
					 | 
				
			||||||
                yield message
 | 
					                yield message
 | 
				
			||||||
                have += 1
 | 
					                have += 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1208,6 +1204,58 @@ class TelegramClient(TelegramBareClient):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            time.sleep(max(wait_time - (time.time() - start), 0))
 | 
					            time.sleep(max(wait_time - (time.time() - start), 0))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @staticmethod
 | 
				
			||||||
 | 
					    def _make_message_friendly(message, entities):
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        Add a few extra attributes to the :tl:`Message` to be friendlier.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        To make messages more friendly, always add message
 | 
				
			||||||
 | 
					        to service messages, and action to normal messages.
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        # TODO Create an actual friendlier class
 | 
				
			||||||
 | 
					        message.message = getattr(message, 'message', None)
 | 
				
			||||||
 | 
					        message.action = getattr(message, 'action', None)
 | 
				
			||||||
 | 
					        message.to = entities[utils.get_peer_id(message.to_id)]
 | 
				
			||||||
 | 
					        message.sender = (
 | 
				
			||||||
 | 
					            None if not message.from_id else
 | 
				
			||||||
 | 
					            entities[utils.get_peer_id(message.from_id)]
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        if getattr(message, 'fwd_from', None):
 | 
				
			||||||
 | 
					            message.fwd_from.sender = (
 | 
				
			||||||
 | 
					                None if not message.fwd_from.from_id else
 | 
				
			||||||
 | 
					                entities[utils.get_peer_id(message.fwd_from.from_id)]
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					            message.fwd_from.channel = (
 | 
				
			||||||
 | 
					                None if not message.fwd_from.channel_id else
 | 
				
			||||||
 | 
					                entities[utils.get_peer_id(
 | 
				
			||||||
 | 
					                    PeerChannel(message.fwd_from.channel_id)
 | 
				
			||||||
 | 
					                )]
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _iter_ids(self, entity, ids, total):
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        Special case for `iter_messages` when it should only fetch some IDs.
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        if total:
 | 
				
			||||||
 | 
					            total[0] = len(ids)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if isinstance(entity, InputPeerChannel):
 | 
				
			||||||
 | 
					            r = self(channels.GetMessagesRequest(entity, ids))
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            r = self(messages.GetMessagesRequest(ids))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        entities = {utils.get_peer_id(x): x
 | 
				
			||||||
 | 
					                    for x in itertools.chain(r.users, r.chats)}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Telegram seems to return the messages in the order in which
 | 
				
			||||||
 | 
					        # we asked them for, so we don't need to check it ourselves.
 | 
				
			||||||
 | 
					        for message in r.messages:
 | 
				
			||||||
 | 
					            if isinstance(message, MessageEmpty):
 | 
				
			||||||
 | 
					                yield None
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                self._make_message_friendly(message, entities)
 | 
				
			||||||
 | 
					                yield message
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_messages(self, *args, **kwargs):
 | 
					    def get_messages(self, *args, **kwargs):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Same as :meth:`iter_messages`, but returns a list instead
 | 
					        Same as :meth:`iter_messages`, but returns a list instead
 | 
				
			||||||
| 
						 | 
					@ -1220,6 +1268,10 @@ class TelegramClient(TelegramBareClient):
 | 
				
			||||||
        This is so because any integer limit would be rather arbitrary and
 | 
					        This is so because any integer limit would be rather arbitrary and
 | 
				
			||||||
        it's common to only want to fetch one message, but if a range is
 | 
					        it's common to only want to fetch one message, but if a range is
 | 
				
			||||||
        specified it makes sense that it should return the entirety of it.
 | 
					        specified it makes sense that it should return the entirety of it.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        If `ids` is present in the *named* arguments and is not a list,
 | 
				
			||||||
 | 
					        a single :tl:`Message` will be returned for convenience instead
 | 
				
			||||||
 | 
					        of a list.
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        total = [0]
 | 
					        total = [0]
 | 
				
			||||||
        kwargs['_total'] = total
 | 
					        kwargs['_total'] = total
 | 
				
			||||||
| 
						 | 
					@ -1231,6 +1283,9 @@ class TelegramClient(TelegramBareClient):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        msgs = UserList(self.iter_messages(*args, **kwargs))
 | 
					        msgs = UserList(self.iter_messages(*args, **kwargs))
 | 
				
			||||||
        msgs.total = total[0]
 | 
					        msgs.total = total[0]
 | 
				
			||||||
 | 
					        if 'ids' in kwargs and not utils.is_list_like(kwargs['ids']):
 | 
				
			||||||
 | 
					            return msgs[0]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return msgs
 | 
					        return msgs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_message_history(self, *args, **kwargs):
 | 
					    def get_message_history(self, *args, **kwargs):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user