From bb89e949e88d5e2a0c2c56ebb27e990164fa96dc Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sat, 23 May 2020 13:42:49 +0200 Subject: [PATCH 1/6] Update send_dice: add basketball "dice" --- pyrogram/client/methods/messages/send_dice.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/pyrogram/client/methods/messages/send_dice.py b/pyrogram/client/methods/messages/send_dice.py index f90bc852..4ed9b926 100644 --- a/pyrogram/client/methods/messages/send_dice.py +++ b/pyrogram/client/methods/messages/send_dice.py @@ -38,7 +38,7 @@ class SendDice(BaseClient): "pyrogram.ForceReply" ] = None ) -> Union["pyrogram.Message", None]: - """Send a dice. + """Send a dice with a random value from 1 to 6. Parameters: chat_id (``int`` | ``str``): @@ -47,8 +47,8 @@ class SendDice(BaseClient): For a contact that exists in your Telegram address book you can use his phone number (str). emoji (``str``, *optional*): - Emoji on which the dice throw animation is based. Currently, must be one of "🎲" or "🎯". - Defauts to "🎲". + Emoji on which the dice throw animation is based. Currently, must be one of "🎲", "🎯" or "🏀". + Defaults to "🎲". disable_notification (``bool``, *optional*): Sends the message silently. @@ -75,6 +75,9 @@ class SendDice(BaseClient): # Send a dart app.send_dice("pyrogramlounge", "🎯") + + # Send a basketball + app.send_dice("pyrogramlounge", "🏀") """ r = self.send( From d5a18eb0633ea6f78d0c140e02924f9227cdf9de Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sat, 23 May 2020 14:50:14 +0200 Subject: [PATCH 2/6] Add search_global method --- compiler/docs/compiler.py | 1 + pyrogram/client/methods/messages/__init__.py | 8 +- .../client/methods/messages/search_global.py | 96 +++++++++++++++++++ 3 files changed, 102 insertions(+), 3 deletions(-) create mode 100644 pyrogram/client/methods/messages/search_global.py diff --git a/compiler/docs/compiler.py b/compiler/docs/compiler.py index 6b596b2f..8afd99f8 100644 --- a/compiler/docs/compiler.py +++ b/compiler/docs/compiler.py @@ -176,6 +176,7 @@ def pyrogram_api(): retract_vote send_dice search_messages + search_global download_media """, chats=""" diff --git a/pyrogram/client/methods/messages/__init__.py b/pyrogram/client/methods/messages/__init__.py index 3df4e7ce..e78d2bc5 100644 --- a/pyrogram/client/methods/messages/__init__.py +++ b/pyrogram/client/methods/messages/__init__.py @@ -33,11 +33,14 @@ from .get_messages import GetMessages from .iter_history import IterHistory from .read_history import ReadHistory from .retract_vote import RetractVote +from .search_global import SearchGlobal +from .search_messages import SearchMessages from .send_animation import SendAnimation from .send_audio import SendAudio from .send_cached_media import SendCachedMedia from .send_chat_action import SendChatAction from .send_contact import SendContact +from .send_dice import SendDice from .send_document import SendDocument from .send_location import SendLocation from .send_media_group import SendMediaGroup @@ -51,8 +54,6 @@ from .send_video_note import SendVideoNote from .send_voice import SendVoice from .stop_poll import StopPoll from .vote_poll import VotePoll -from .send_dice import SendDice -from .search_messages import SearchMessages class Messages( @@ -92,6 +93,7 @@ class Messages( EditInlineMedia, EditInlineReplyMarkup, SendDice, - SearchMessages + SearchMessages, + SearchGlobal ): pass diff --git a/pyrogram/client/methods/messages/search_global.py b/pyrogram/client/methods/messages/search_global.py new file mode 100644 index 00000000..45262d78 --- /dev/null +++ b/pyrogram/client/methods/messages/search_global.py @@ -0,0 +1,96 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-2020 Dan +# +# This file is part of Pyrogram. +# +# Pyrogram is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pyrogram is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with Pyrogram. If not, see . + +from typing import Generator + +import pyrogram +from pyrogram.api import functions, types +from pyrogram.client.ext import BaseClient, utils + + +class SearchGlobal(BaseClient): + def search_global( + self, + query: str, + limit: int = 0, + ) -> Generator["pyrogram.Message", None, None]: + """Search messages globally from all of your chats. + + .. note:: + + Due to server-side limitations, you can only get up to around ~10,000 messages and each message + retrieved will not have any *reply_to_message* field. + + Parameters: + query (``str``): + Text query string. + + limit (``int``, *optional*): + Limits the number of messages to be retrieved. + By default, no limit is applied and all messages are returned. + + Returns: + ``Generator``: A generator yielding :obj:`Message` objects. + + Example: + .. code-block:: python + + # Search for "pyrogram". Get the first 420 results + for message in app.search_global("pyrogram", limit=420): + print(message.text) + """ + current = 0 + # There seems to be an hard limit of 10k, beyond which Telegram starts spitting one message at a time. + total = abs(limit) or (1 << 31) + limit = min(100, total) + + offset_date = 0 + offset_peer = types.InputPeerEmpty() + offset_id = 0 + + while True: + messages = utils.parse_messages( + self, + self.send( + functions.messages.SearchGlobal( + q=query, + offset_rate=offset_date, + offset_peer=offset_peer, + offset_id=offset_id, + limit=limit + ) + ), + replies=0 + ) + + if not messages: + return + + last = messages[-1] + + offset_date = last.date + offset_peer = self.resolve_peer(last.chat.id) + offset_id = last.message_id + + for message in messages: + yield message + + current += 1 + + if current >= total: + return From d93b9275f3e73082507d781a94e51095102857e8 Mon Sep 17 00:00:00 2001 From: SuperCz1 <62919067+SuperCz1@users.noreply.github.com> Date: Sat, 23 May 2020 14:52:14 +0200 Subject: [PATCH 3/6] Bugfixes in chat.py (#411) - Fixed this bug: https://t.me/pyrogramchat/169553 (which was caused because pyrogram trying to parse linked_chat even if it was None). - Fixed another related bug (which was caused because pyrogram trying to get linked_chat_id even with basic groups causing an AttributeError). --- pyrogram/client/types/user_and_chats/chat.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/pyrogram/client/types/user_and_chats/chat.py b/pyrogram/client/types/user_and_chats/chat.py index db2b3ef6..4a7904ce 100644 --- a/pyrogram/client/types/user_and_chats/chat.py +++ b/pyrogram/client/types/user_and_chats/chat.py @@ -251,9 +251,10 @@ class Chat(Object): for c in chat_full.chats: if full_chat.id == c.id: chat = c - - if full_chat.linked_chat_id == c.id: - linked_chat = c + + if isinstance(chat_full, types.ChannelFull): + if full_chat.linked_chat_id == c.id: + linked_chat = c if isinstance(full_chat, types.ChatFull): parsed_chat = Chat._parse_chat_chat(client, chat) @@ -268,7 +269,8 @@ class Chat(Object): # TODO: Add StickerSet type parsed_chat.can_set_sticker_set = full_chat.can_set_stickers parsed_chat.sticker_set_name = getattr(full_chat.stickerset, "short_name", None) - parsed_chat.linked_chat = Chat._parse_channel_chat(client, linked_chat) + if linked_chat: + parsed_chat.linked_chat = Chat._parse_channel_chat(client, linked_chat) if full_chat.pinned_msg_id: parsed_chat.pinned_message = client.get_messages( From 4a9cfa42ded8ae7f16392a3204a1569a7adf17c0 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sat, 23 May 2020 15:01:29 +0200 Subject: [PATCH 4/6] Make CallbackQuery.answer optional arguments actually optional --- .../client/methods/bots/answer_callback_query.py | 15 +++++++++------ .../types/bots_and_keyboards/callback_query.py | 8 ++++---- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/pyrogram/client/methods/bots/answer_callback_query.py b/pyrogram/client/methods/bots/answer_callback_query.py index 53cd6c49..2e00c07c 100644 --- a/pyrogram/client/methods/bots/answer_callback_query.py +++ b/pyrogram/client/methods/bots/answer_callback_query.py @@ -36,20 +36,20 @@ class AnswerCallbackQuery(BaseClient): callback_query_id (``str``): Unique identifier for the query to be answered. - text (``str``): + text (``str`` *optional*): Text of the notification. If not specified, nothing will be shown to the user, 0-200 characters. - show_alert (``bool``): + show_alert (``bool``, *optional*): If true, an alert will be shown by the client instead of a notification at the top of the chat screen. Defaults to False. - url (``str``): + url (``str``, *optional*): URL that will be opened by the user's client. If you have created a Game and accepted the conditions via @Botfather, specify the URL that opens your game – note that this will only work if the query comes from a callback_game button. Otherwise, you may use links like t.me/your_bot?start=XXXX that open your bot with a parameter. - cache_time (``int``): + cache_time (``int``, *optional*): The maximum amount of time in seconds that the result of the callback query may be cached client-side. Telegram apps will support caching starting in version 3.14. Defaults to 0. @@ -59,6 +59,9 @@ class AnswerCallbackQuery(BaseClient): Example: .. code-block:: python + # Answer only (remove the spinning circles) + app.answer_callback_query(query_id) + # Answer without alert app.answer_callback_query(query_id, text=text) @@ -70,7 +73,7 @@ class AnswerCallbackQuery(BaseClient): query_id=int(callback_query_id), cache_time=cache_time, alert=show_alert or None, - message=text, - url=url + message=text or None, + url=url or None ) ) diff --git a/pyrogram/client/types/bots_and_keyboards/callback_query.py b/pyrogram/client/types/bots_and_keyboards/callback_query.py index 9820e560..ec4048fc 100644 --- a/pyrogram/client/types/bots_and_keyboards/callback_query.py +++ b/pyrogram/client/types/bots_and_keyboards/callback_query.py @@ -143,20 +143,20 @@ class CallbackQuery(Object, Update): callback_query.answer("Hello", show_alert=True) Parameters: - text (``str``): + text (``str``, *optional*): Text of the notification. If not specified, nothing will be shown to the user, 0-200 characters. - show_alert (``bool``): + show_alert (``bool`` *optional*): If true, an alert will be shown by the client instead of a notification at the top of the chat screen. Defaults to False. - url (``str``): + url (``str`` *optional*): URL that will be opened by the user's client. If you have created a Game and accepted the conditions via @Botfather, specify the URL that opens your game – note that this will only work if the query comes from a callback_game button. Otherwise, you may use links like t.me/your_bot?start=XXXX that open your bot with a parameter. - cache_time (``int``): + cache_time (``int`` *optional*): The maximum amount of time in seconds that the result of the callback query may be cached client-side. Telegram apps will support caching starting in version 3.14. Defaults to 0. """ From e30b9c52555f3ca66a64471a6e2862d216954320 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sat, 23 May 2020 15:03:52 +0200 Subject: [PATCH 5/6] Fix small typos --- pyrogram/client/types/user_and_chats/chat.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pyrogram/client/types/user_and_chats/chat.py b/pyrogram/client/types/user_and_chats/chat.py index 4a7904ce..d95c5b37 100644 --- a/pyrogram/client/types/user_and_chats/chat.py +++ b/pyrogram/client/types/user_and_chats/chat.py @@ -251,7 +251,7 @@ class Chat(Object): for c in chat_full.chats: if full_chat.id == c.id: chat = c - + if isinstance(chat_full, types.ChannelFull): if full_chat.linked_chat_id == c.id: linked_chat = c @@ -547,13 +547,13 @@ class Chat(Object): client.restrict_chat_member( chat_id=chat_id, user_id=user_id, - permissions=ChatPermission() + permissions=ChatPermissions() ) Example: .. code-block:: python - chat.restrict_member(user_id, ChatPermission()) + chat.restrict_member(user_id, ChatPermissions()) Parameters: user_id (``int`` | ``str``): From b4467e82af1df67a025732a6b6c7f05a16d7ce9a Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Mon, 25 May 2020 14:31:31 +0200 Subject: [PATCH 6/6] Update Bot API diagram in docs --- docs/source/faq.rst | 2 +- docs/source/topics/mtproto-vs-botapi.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/source/faq.rst b/docs/source/faq.rst index b064e10b..e56736d8 100644 --- a/docs/source/faq.rst +++ b/docs/source/faq.rst @@ -85,7 +85,7 @@ Requests against the official bot API endpoint are made via JSON/HTTP, but are h application that implements the MTProto protocol -- just like Pyrogram -- and uses its own API key, which is always required, but hidden to the public. -.. figure:: https://i.imgur.com/C108qkX.png +.. figure:: https://i.imgur.com/WvwBoZo.png :align: center Using MTProto is the only way to communicate with the actual Telegram servers, and the main API requires developers to diff --git a/docs/source/topics/mtproto-vs-botapi.rst b/docs/source/topics/mtproto-vs-botapi.rst index 3668d0da..12b73b53 100644 --- a/docs/source/topics/mtproto-vs-botapi.rst +++ b/docs/source/topics/mtproto-vs-botapi.rst @@ -35,7 +35,7 @@ accounts that are authorized via tokens instead of phone numbers. The Bot API is Telegram API, but runs on an intermediate server application that in turn communicates with the actual Telegram servers using MTProto. -.. figure:: https://i.imgur.com/C108qkX.png +.. figure:: https://i.imgur.com/WvwBoZo.png :align: center .. _Bot API: https://core.telegram.org/bots/api