diff --git a/docs/source/releases/changes-in-this-fork.rst b/docs/source/releases/changes-in-this-fork.rst index d1449d103a..cbe6ded8b8 100644 --- a/docs/source/releases/changes-in-this-fork.rst +++ b/docs/source/releases/changes-in-this-fork.rst @@ -26,6 +26,7 @@ Changes in this Fork | Scheme layer used: 198 | +------------------------+ +- Added the parameter ``pinned`` and made the parameter ``chat_id`` optional in :meth:`~pyrogram.Client.get_messages`. **NOTE**: Please be aware about using the correct :doc:`Message Identifiers <../../topics/message-identifiers>`, when using this method. - Added the ``cover`` and ``start_timestamp`` parameters in :meth:`~pyrogram.Client.send_video` and :obj:`~pyrogram.types.InputPaidMediaVideo`. - Added the ``new_video_start_timestamp`` and renamed the ``send_copy`` and ``remove_caption`` parameters in :meth:`~pyrogram.Client.forward_messages` and :meth:`~pyrogram.types.Message.forward`. - Added the ``gift_count`` to the :obj:`~pyrogram.types.Chat`. diff --git a/pyrogram/methods/messages/get_messages.py b/pyrogram/methods/messages/get_messages.py index 81899c5150..df59096882 100644 --- a/pyrogram/methods/messages/get_messages.py +++ b/pyrogram/methods/messages/get_messages.py @@ -33,6 +33,7 @@ async def get_messages( chat_id: Union[int, str] = None, message_ids: Union[int, Iterable[int]] = None, reply_to_message_ids: Union[int, Iterable[int]] = None, + pinned: bool = False, replies: int = 1, is_scheduled: bool = False, link: str = None, @@ -45,7 +46,7 @@ async def get_messages( .. include:: /_includes/usable-by/users-bots.rst - You must use exactly one of ``message_ids`` OR (``chat_id``, ``message_ids``) OR (``chat_id``, ``reply_to_message_ids``) OR ``link``. + You must use exactly one of ``message_ids`` OR ``reply_to_message_ids`` OR (``chat_id``, ``message_ids``) OR (``chat_id``, ``reply_to_message_ids``) OR (``chat_id``, ``pinned``) OR ``link``. Parameters: chat_id (``int`` | ``str``, *optional*): @@ -60,15 +61,20 @@ async def get_messages( reply_to_message_ids (``int`` | Iterable of ``int``, *optional*): Pass a single message identifier or an iterable of message ids (as integers) to get the content of the previous message you replied to using this message. - If *message_ids* is set, this argument will be ignored. + + pinned (``bool``, *optional*): + Returns information about the newest pinned message in the specified ``chat_id``. Other parameters are ignored when this is set. + Use :meth:`~pyrogram.Client.search_messages` to return all the pinned messages. replies (``int``, *optional*): The number of subsequent replies to get for each message. Pass 0 for no reply at all or -1 for unlimited replies. Defaults to 1. + Is ignored if ``is_scheduled`` parameter is set. is_scheduled (``bool``, *optional*): Whether to get scheduled messages. Defaults to False. + Only supported if both ``chat_id`` and ``message_ids`` are passed. Other parameters are ignored when this is set. link (``str``): A link of the message, usually can be copied using ``Copy Link`` functionality OR obtained using :obj:`~pyrogram.raw.types.Message.link` OR :obj:`~pyrogram.raw.functions.channels.ExportMessageLink` @@ -99,46 +105,29 @@ async def get_messages( ValueError: In case of invalid arguments. """ - if not chat_id and message_ids: - is_iterable = not isinstance(message_ids, int) - ids = list(message_ids) if is_iterable else [message_ids] - ids = [raw.types.InputMessageID(id=i) for i in ids] - rpc = raw.functions.messages.GetMessages(id=ids) - r = await self.invoke(rpc, sleep_threshold=-1) - messages = await utils.parse_messages( - self, - r, - is_scheduled=is_scheduled, - replies=replies - ) - return messages if is_iterable else messages[0] if messages else None - - if chat_id: + if message_ids or reply_to_message_ids: ids, ids_type = ( (message_ids, raw.types.InputMessageID) if message_ids else (reply_to_message_ids, raw.types.InputMessageReplyTo) if reply_to_message_ids else (None, None) ) - if ids is None: - raise ValueError("No argument supplied. Either pass message_ids or reply_to_message_ids") - - peer = await self.resolve_peer(chat_id) - is_iterable = not isinstance(ids, int) ids = list(ids) if is_iterable else [ids] if replies < 0: replies = (1 << 31) - 1 - if is_scheduled: + peer = await self.resolve_peer(chat_id) if chat_id else None + + if chat_id and is_scheduled: rpc = raw.functions.messages.GetScheduledMessages( peer=peer, id=ids ) else: ids = [ids_type(id=i) for i in ids] - if isinstance(peer, raw.types.InputPeerChannel): + if chat_id and isinstance(peer, raw.types.InputPeerChannel): rpc = raw.functions.channels.GetMessages(channel=peer, id=ids) else: rpc = raw.functions.messages.GetMessages(id=ids) @@ -154,6 +143,18 @@ async def get_messages( return messages if is_iterable else messages[0] if messages else None + if chat_id and pinned: + peer = await self.resolve_peer(chat_id) + rpc = raw.functions.channels.GetMessages(channel=peer, id=[raw.types.InputMessagePinned()]) + r = await self.invoke(rpc, sleep_threshold=-1) + messages = await utils.parse_messages( + self, + r, + is_scheduled=False, + replies=replies + ) + return messages[0] if messages else None + if link: linkps = link.split("/") raw_chat_id, message_thread_id, message_id = None, None, None diff --git a/pyrogram/types/business/successful_payment.py b/pyrogram/types/business/successful_payment.py index 470548702d..a619b5cd92 100644 --- a/pyrogram/types/business/successful_payment.py +++ b/pyrogram/types/business/successful_payment.py @@ -26,7 +26,7 @@ class SuccessfulPayment(Object): - """This object contains basic information about a successful payment. + """This object contains basic information about a successful payment. Note that if the buyer initiates a chargeback with the relevant payment provider following this transaction, the funds may be debited from your balance. This is outside of Telegram's control. Parameters: currency (``str``): diff --git a/pyrogram/types/messages_and_media/message.py b/pyrogram/types/messages_and_media/message.py index f23fb8b0a9..949472b9cb 100644 --- a/pyrogram/types/messages_and_media/message.py +++ b/pyrogram/types/messages_and_media/message.py @@ -1066,15 +1066,12 @@ async def _parse( ) if isinstance(action, raw.types.MessageActionPinMessage): - try: - parsed_message.pinned_message = await client.get_messages( - chat_id=parsed_message.chat.id, - reply_to_message_ids=message.id, - replies=0 - ) - parsed_message.service = enums.MessageServiceType.PINNED_MESSAGE - except MessageIdsEmpty: - pass + parsed_message.pinned_message = await client.get_messages( + chat_id=parsed_message.chat.id, + pinned=True, + replies=0 + ) + parsed_message.service = enums.MessageServiceType.PINNED_MESSAGE if isinstance(action, raw.types.MessageActionGameScore): parsed_message.game_high_score = types.GameHighScore._parse_action(client, message, users) diff --git a/pyrogram/types/user_and_chats/chat.py b/pyrogram/types/user_and_chats/chat.py index bc47523eda..6cc88ed4b3 100644 --- a/pyrogram/types/user_and_chats/chat.py +++ b/pyrogram/types/user_and_chats/chat.py @@ -588,17 +588,10 @@ async def _parse_full(client, chat_full: Union[raw.types.messages.ChatFull, raw. ) if full_user.pinned_msg_id: - try: - parsed_chat.pinned_message = await client.get_messages( - chat_id=parsed_chat.id, - message_ids=full_user.pinned_msg_id - ) - except MessageIdsEmpty: - parsed_chat.pinned_message = types.Message( - id=full_user.pinned_msg_id, - empty=True, - client=client - ) + parsed_chat.pinned_message = await client.get_messages( + chat_id=parsed_chat.id, + pinned=True + ) if getattr(full_user, "birthday", None): parsed_chat.birthdate = types.Birthdate._parse( @@ -679,17 +672,10 @@ async def _parse_full(client, chat_full: Union[raw.types.messages.ChatFull, raw. parsed_chat.message_auto_delete_time = getattr(full_chat, "ttl_period") if full_chat.pinned_msg_id: - try: - parsed_chat.pinned_message = await client.get_messages( - chat_id=parsed_chat.id, - message_ids=full_chat.pinned_msg_id - ) - except MessageIdsEmpty: - parsed_chat.pinned_message = types.Message( - id=full_chat.pinned_msg_id, - empty=True, - client=client - ) + parsed_chat.pinned_message = await client.get_messages( + chat_id=parsed_chat.id, + pinned=True + ) if isinstance(full_chat.exported_invite, raw.types.ChatInviteExported): parsed_chat.invite_link = full_chat.exported_invite.link