From 834fff88dae61558d510b1a3e6ed59d3759adeef Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sun, 25 Feb 2018 14:22:18 +0100 Subject: [PATCH 01/19] Remove print --- pyrogram/client/client.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pyrogram/client/client.py b/pyrogram/client/client.py index ccc615b5..dd98ee2a 100644 --- a/pyrogram/client/client.py +++ b/pyrogram/client/client.py @@ -370,7 +370,6 @@ class Client: except Exception as e: log.error(e, exc_info=True) finally: - print(done) done.set() try: From 64ebf979e5e77fb25ceff3d6f948cb252ffab3b4 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sun, 25 Feb 2018 14:30:17 +0100 Subject: [PATCH 02/19] Fix file extension --- pyrogram/client/client.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pyrogram/client/client.py b/pyrogram/client/client.py index dd98ee2a..deb99904 100644 --- a/pyrogram/client/client.py +++ b/pyrogram/client/client.py @@ -311,7 +311,8 @@ class Client: if not file_name: file_name = "doc_{}{}".format( datetime.fromtimestamp(document.date).strftime("%Y-%m-%d_%H-%M-%S"), - mimetypes.guess_extension(document.mime_type) or ".unknown" + ".txt" if document.mime_type == "text/plain" else + mimetypes.guess_extension(document.mime_type) if document.mime_type else ".unknown" ) for i in document.attributes: From bce7d5b6e84cdfde61c657a72b094cb0918c4157 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sun, 25 Feb 2018 18:43:30 +0100 Subject: [PATCH 03/19] Fix signal handler not working on Windows --- pyrogram/client/client.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/pyrogram/client/client.py b/pyrogram/client/client.py index deb99904..cf21d754 100644 --- a/pyrogram/client/client.py +++ b/pyrogram/client/client.py @@ -159,7 +159,7 @@ class Client: self.session = None - self.is_idle = Event() + self.is_idle = None self.updates_queue = Queue() self.update_queue = Queue() @@ -472,7 +472,7 @@ class Client: def signal_handler(self, *args): self.stop() - self.is_idle.set() + self.is_idle = False def idle(self, stop_signals: tuple = (SIGINT, SIGTERM, SIGABRT)): """Blocks the program execution until one of the signals are received, @@ -486,7 +486,10 @@ class Client: for s in stop_signals: signal(s, self.signal_handler) - self.is_idle.wait() + self.is_idle = True + + while self.is_idle: + time.sleep(1) def set_update_handler(self, callback: callable): """Use this method to set the update handler. From eada298e8cd1f23bc6d66a05496029acf9df0793 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Mon, 26 Feb 2018 15:09:24 +0100 Subject: [PATCH 04/19] Add hello_world example --- examples/hello_world.py | 19 +++++++++++++++++++ examples/pyrogram.png | Bin 0 -> 41329 bytes 2 files changed, 19 insertions(+) create mode 100644 examples/hello_world.py create mode 100644 examples/pyrogram.png diff --git a/examples/hello_world.py b/examples/hello_world.py new file mode 100644 index 00000000..96934f32 --- /dev/null +++ b/examples/hello_world.py @@ -0,0 +1,19 @@ +from pyrogram import Client + +# Create a new Client +client = Client("example") + +# Start the Client +client.start() + +# Send a message to yourself, Markdown is enabled by default +client.send_message("me", "Hi there! I'm using **Pyrogram**") + +# Send a photo with a formatted caption to yourself +client.send_photo("me", "pyrogram.png", "__This is a formatted__ **caption**") + +# Send a location to yourself +client.send_location("me", 51.500729, -0.124583) + +# Stop the client +client.stop() diff --git a/examples/pyrogram.png b/examples/pyrogram.png new file mode 100644 index 0000000000000000000000000000000000000000..57bfefe86b814585d8260a62585417f1b7af9849 GIT binary patch literal 41329 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 Date: Mon, 26 Feb 2018 15:44:08 +0100 Subject: [PATCH 05/19] Always fetch peers (when applicable) --- pyrogram/client/client.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/pyrogram/client/client.py b/pyrogram/client/client.py index cf21d754..681ab8b1 100644 --- a/pyrogram/client/client.py +++ b/pyrogram/client/client.py @@ -546,7 +546,12 @@ class Client: Raises: :class:`pyrogram.Error` """ - return self.session.send(data) + r = self.session.send(data) + + self.fetch_peers(getattr(r, "users", [])) + self.fetch_peers(getattr(r, "chats", [])) + + return r def authorize(self): phone_number_invalid_raises = self.phone_number is not None @@ -772,9 +777,6 @@ class Client: def get_dialogs(self): def parse_dialogs(d): - self.fetch_peers(d.chats) - self.fetch_peers(d.users) - for m in reversed(d.messages): if isinstance(m, types.MessageEmpty): continue @@ -2513,8 +2515,6 @@ class Client: ) ) - self.fetch_peers(imported_contacts.users) - return imported_contacts def delete_contacts(self, ids: list): @@ -2559,6 +2559,5 @@ class Client: else: if isinstance(contacts, types.contacts.Contacts): log.info("Contacts count: {}".format(len(contacts.users))) - self.fetch_peers(contacts.users) return contacts From 4561d04c67d98d1882cf72fcd10b0aa8cfbedcc5 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Mon, 26 Feb 2018 15:43:03 +0100 Subject: [PATCH 06/19] Add get_history example --- examples/get_history.py | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 examples/get_history.py diff --git a/examples/get_history.py b/examples/get_history.py new file mode 100644 index 00000000..f1f36eca --- /dev/null +++ b/examples/get_history.py @@ -0,0 +1,35 @@ +import time + +from pyrogram import Client +from pyrogram.api import functions +from pyrogram.api.errors import FloodWait + +client = Client("example") +client.start() + +target = "me" # "me" refers to your own chat (Saved Messages) +history = [] # List that will contain all the messages of the target chat +limit = 100 # Amount of messages to retrieve for each API call +offset = 0 # Offset starts at 0 + +while True: + try: + messages = client.send( + functions.messages.GetHistory( + client.resolve_peer(target), + 0, 0, offset, limit, 0, 0, 0 + ) + ) + except FloodWait as e: + # For very large chats the method call can raise a FloodWait + time.sleep(e.x) # Sleep X seconds before continuing + continue + + if not messages.messages: + break # No more messages left + + history.extend(messages.messages) + offset += limit + +# Now the "history" list contains all the messages sorted by date in +# descending order (from the most recent to the oldest one) From 8ad2b69bedb2292a65afd1c9a5fe75ff6b5ddce7 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Mon, 26 Feb 2018 15:49:07 +0100 Subject: [PATCH 07/19] Add get_participants example --- examples/get_participants.py | 38 ++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 examples/get_participants.py diff --git a/examples/get_participants.py b/examples/get_participants.py new file mode 100644 index 00000000..3397eb42 --- /dev/null +++ b/examples/get_participants.py @@ -0,0 +1,38 @@ +import time + +from pyrogram import Client +from pyrogram.api import functions, types +from pyrogram.api.errors import FloodWait + +client = Client("example") +client.start() + +target = "username" # Target channel/supergroup +users = [] # List that will contain all the users of the target chat +limit = 200 # Amount of users to retrieve for each API call +offset = 0 # Offset starts at 0 + +while True: + try: + participants = client.send( + functions.channels.GetParticipants( + channel=client.resolve_peer(target), + filter=types.ChannelParticipantsSearch(""), # Filter by empty string (search for all) + offset=offset, + limit=limit, + hash=0 + ) + ) + except FloodWait as e: + # Very large channels will trigger FloodWait. + # When happens, wait X seconds before continuing + time.sleep(e.x) + continue + + if not participants.participants: + break # No more participants left + + users.extend(participants.users) + offset += limit + +# Now the "users" list contains all the members of the target chat From 0219ac0b5a3388598ce455aaabb1f52d3e9c3cf2 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Mon, 26 Feb 2018 15:51:31 +0100 Subject: [PATCH 08/19] Move non-code files into data folder --- examples/{ => data}/pyrogram.png | Bin examples/hello_world.py | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename examples/{ => data}/pyrogram.png (100%) diff --git a/examples/pyrogram.png b/examples/data/pyrogram.png similarity index 100% rename from examples/pyrogram.png rename to examples/data/pyrogram.png diff --git a/examples/hello_world.py b/examples/hello_world.py index 96934f32..5c3f0304 100644 --- a/examples/hello_world.py +++ b/examples/hello_world.py @@ -10,7 +10,7 @@ client.start() client.send_message("me", "Hi there! I'm using **Pyrogram**") # Send a photo with a formatted caption to yourself -client.send_photo("me", "pyrogram.png", "__This is a formatted__ **caption**") +client.send_photo("me", "data/pyrogram.png", "__This is a formatted__ **caption**") # Send a location to yourself client.send_location("me", 51.500729, -0.124583) From 1fca99c7124c1fff7002a9bd8bf571409be2a265 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Mon, 26 Feb 2018 16:07:48 +0100 Subject: [PATCH 09/19] Add updates example --- examples/updates.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 examples/updates.py diff --git a/examples/updates.py b/examples/updates.py new file mode 100644 index 00000000..db28eeb6 --- /dev/null +++ b/examples/updates.py @@ -0,0 +1,25 @@ +from pyrogram import Client + + +# This function will be called every time a new Update is received from Telegram +def update_handler(client, update, users, chats): + # Send EVERY update that arrives to your own chat (Saved Messages) + # Use triple backticks to make the text look nicer. + client.send_message("me", "```\n" + str(update) + "```") + + +def main(): + # Pyrogram setup + client = Client("example") + + # Set the update_handler callback function + client.set_update_handler(update_handler) + client.start() + + # Blocks the program execution until you press CTRL+C then + # automatically stops the Client by closing the underlying connection + client.idle() + + +if __name__ == "__main__": + main() From b6cd30d281cb1124cda58aecdf62d8670c24a148 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Mon, 26 Feb 2018 16:26:11 +0100 Subject: [PATCH 10/19] Add simple_echo example --- examples/simple_echo.py | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 examples/simple_echo.py diff --git a/examples/simple_echo.py b/examples/simple_echo.py new file mode 100644 index 00000000..14abce2e --- /dev/null +++ b/examples/simple_echo.py @@ -0,0 +1,34 @@ +from pyrogram import Client +from pyrogram.api import types + +"""This simple example bot will reply to all private text messages""" + + +def update_handler(client, update, users, chats): + if isinstance(update, types.UpdateNewMessage): # Filter by UpdateNewMessage (Private Messages) + message = update.message # type: types.Message + + if isinstance(message, types.Message): # Filter by Message to exclude MessageService and MessageEmpty + if isinstance(message.to_id, types.PeerUser): # Private Messages (Message from user) + client.send_message( + chat_id=message.from_id, + text=message.message, + reply_to_message_id=message.id + ) + + +def main(): + # Pyrogram setup + client = Client("example") + + # Set the update_handler callback function + client.set_update_handler(update_handler) + client.start() + + # Blocks the program execution until you press CTRL+C then + # automatically stops the Client by closing the underlying connection + client.idle() + + +if __name__ == "__main__": + main() From 40917988c3a3e1b4158d056290e4038c154bcdcd Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Mon, 26 Feb 2018 16:38:52 +0100 Subject: [PATCH 11/19] Add advanced_echo example --- examples/advanced_echo.py | 64 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 examples/advanced_echo.py diff --git a/examples/advanced_echo.py b/examples/advanced_echo.py new file mode 100644 index 00000000..9cc2fb6e --- /dev/null +++ b/examples/advanced_echo.py @@ -0,0 +1,64 @@ +from pyrogram import Client +from pyrogram.api import types + +"""This is a more advanced example bot that will reply to all private and basic groups text messages +by also mentioning the Users. + +Beware! This script will make you reply to ALL new messages in private chats and in every basic group you are in. +Make sure you add an extra check to filter them: + +# Filter Groups by ID +if message.to_id.chat_id == MY_GROUP_ID: + ... +""" + + +def update_handler(client, update, users, chats): + if isinstance(update, types.UpdateNewMessage): # Filter by UpdateNewMessage (PM and Chats) + message = update.message + + if isinstance(message, types.Message): # Filter by Message to exclude MessageService and MessageEmpty + if isinstance(message.to_id, types.PeerUser): # Private Messages + text = '[{}](tg://user?id={}) said "{}" to me ([{}](tg://user?id={}))'.format( + users[message.from_id].first_name, + users[message.from_id].id, + message.message, + users[message.to_id.user_id].first_name, + users[message.to_id.user_id].id + ) + + client.send_message( + message.from_id, # Send the message to the private chat (from_id) + text, + reply_to_message_id=message.id + ) + else: # Group chats + text = '[{}](tg://user?id={}) said "{}" in **{}** group'.format( + users[message.from_id].first_name, + users[message.from_id].id, + message.message, + chats[message.to_id.chat_id].title + ) + + client.send_message( + message.to_id, # Send the message to the group chat (to_id) + text, + reply_to_message_id=message.id + ) + + +def main(): + # Pyrogram setup + client = Client("example") + + # Set the update_handler callback function + client.set_update_handler(update_handler) + client.start() + + # Blocks the program execution until you press CTRL+C then + # automatically stops the Client by closing the underlying connection + client.idle() + + +if __name__ == "__main__": + main() From 5cab0b42bb9984641277835894d15f20cedf4d63 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Mon, 26 Feb 2018 16:49:14 +0100 Subject: [PATCH 12/19] Add advanced_echo2 example --- examples/advanced_echo2.py | 55 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 examples/advanced_echo2.py diff --git a/examples/advanced_echo2.py b/examples/advanced_echo2.py new file mode 100644 index 00000000..460c4cf8 --- /dev/null +++ b/examples/advanced_echo2.py @@ -0,0 +1,55 @@ +from pyrogram import Client +from pyrogram.api import types + +"""This example is similar to advanced_echo.py, except for the fact that it will reply to Supergroup text messages only. + +Beware! This script will make you reply to ALL new messages in every single supergroup you are in. +Make sure you add an extra check to filter them: + +# Filter Supergroups by ID +if message.to_id.channel_id == MY_SUPERGROUP_ID: + ... + +# Filter Supergroups by Username +if chats[message.to_id.channel_id].username == MY_SUPERGROUP_USERNAME: + ... +""" + + +def update_handler(client, update, users, chats): + # Channels and Supergroups share the same type (Channel). The .megagroup field is used to tell them apart, and is + # True for Supegroups, False for Channels. + if isinstance(update, types.UpdateNewChannelMessage): # Filter by UpdateNewChannelMessage (Channels/Supergroups) + message = update.message + + if isinstance(message, types.Message): # Filter by Message to exclude MessageService and MessageEmpty + if chats[message.to_id.channel_id].megagroup: # Only handle messages from Supergroups not Channels + text = '[{}](tg://user?id={}) said "{}" in **{}** supergroup'.format( + users[message.from_id].first_name, + users[message.from_id].id, + message.message, + chats[message.to_id.channel_id].title + ) + + client.send_message( + message.to_id, + text, + reply_to_message_id=message.id + ) + + +def main(): + # Pyrogram setup + client = Client("example") + + # Set the update_handler callback function + client.set_update_handler(update_handler) + client.start() + + # Blocks the program execution until you press CTRL+C then + # automatically stops the Client by closing the underlying connection + client.idle() + + +if __name__ == "__main__": + main() From 0f6e89e6b36991d989e239fae3a215564f918796 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Mon, 26 Feb 2018 17:01:33 +0100 Subject: [PATCH 13/19] Add missing client.stop() --- examples/get_history.py | 2 ++ examples/get_participants.py | 2 ++ 2 files changed, 4 insertions(+) diff --git a/examples/get_history.py b/examples/get_history.py index f1f36eca..34e6a34c 100644 --- a/examples/get_history.py +++ b/examples/get_history.py @@ -31,5 +31,7 @@ while True: history.extend(messages.messages) offset += limit +client.stop() + # Now the "history" list contains all the messages sorted by date in # descending order (from the most recent to the oldest one) diff --git a/examples/get_participants.py b/examples/get_participants.py index 3397eb42..89b01f60 100644 --- a/examples/get_participants.py +++ b/examples/get_participants.py @@ -35,4 +35,6 @@ while True: users.extend(participants.users) offset += limit +client.stop() + # Now the "users" list contains all the members of the target chat From f2e16c5910f3a49becc19e7afa1a90e3f74b511d Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Mon, 26 Feb 2018 17:10:58 +0100 Subject: [PATCH 14/19] Create README.md --- examples/README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 examples/README.md diff --git a/examples/README.md b/examples/README.md new file mode 100644 index 00000000..3e4a7b85 --- /dev/null +++ b/examples/README.md @@ -0,0 +1,14 @@ +# Examples + +This folder contains example scripts to show you how **Pyrogram** looks like. +You can start with [hello_world.py](https://github.com/pyrogram/pyrogram/blob/master/examples/hello_world.py) and continue +with the more advanced examples. Every script is working right away, meaning you can simply copy-paste and run, the only things +you have to change are the target chats (username, id) and file paths for sending media (photo, video, ...). + +- [**hello_world.py**](https://github.com/pyrogram/pyrogram/blob/master/examples/hello_world.py) +- [**get_history.py**](https://github.com/pyrogram/pyrogram/blob/master/examples/get_history.py) +- [**get_participants.py**](https://github.com/pyrogram/pyrogram/blob/master/examples/get_participants.py) +- [**updates.py**](https://github.com/pyrogram/pyrogram/blob/master/examples/updates.py) +- [**simple_echo.py**](https://github.com/pyrogram/pyrogram/blob/master/examples/simple_echo.py) +- [**advanced_echo.py**](https://github.com/pyrogram/pyrogram/blob/master/examples/advanced_echo.py) +- [**advanced_echo2.py**](https://github.com/pyrogram/pyrogram/blob/master/examples/advanced_echo2.py) From 342b2c36b6fd2d673a05ec2f5db3914b179539d7 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Tue, 27 Feb 2018 10:53:35 +0100 Subject: [PATCH 15/19] Update CHAT_ADMIN_REQUIRED description --- compiler/error/source/400_BAD_REQUEST.tsv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/error/source/400_BAD_REQUEST.tsv b/compiler/error/source/400_BAD_REQUEST.tsv index ac1989b8..bd3561ee 100644 --- a/compiler/error/source/400_BAD_REQUEST.tsv +++ b/compiler/error/source/400_BAD_REQUEST.tsv @@ -42,7 +42,7 @@ CDN_METHOD_INVALID The method can't be used on CDN DCs VOLUME_LOC_NOT_FOUND The volume location can't be found FILE_ID_INVALID The file id is invalid LOCATION_INVALID The file location is invalid -CHAT_ADMIN_REQUIRED The method requires admin privileges +CHAT_ADMIN_REQUIRED The method requires chat admin privileges PHONE_NUMBER_BANNED The phone number is banned ABOUT_TOO_LONG The about text is too long MULTI_MEDIA_TOO_LONG The album contains more than 10 items From 9500e9c1caa4819744835e60912b7665c3ca7b91 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Tue, 27 Feb 2018 10:55:08 +0100 Subject: [PATCH 16/19] Add BOT_INLINE_DISABLED error --- compiler/error/source/400_BAD_REQUEST.tsv | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/error/source/400_BAD_REQUEST.tsv b/compiler/error/source/400_BAD_REQUEST.tsv index bd3561ee..abef742f 100644 --- a/compiler/error/source/400_BAD_REQUEST.tsv +++ b/compiler/error/source/400_BAD_REQUEST.tsv @@ -47,3 +47,4 @@ PHONE_NUMBER_BANNED The phone number is banned ABOUT_TOO_LONG The about text is too long MULTI_MEDIA_TOO_LONG The album contains more than 10 items USERNAME_OCCUPIED The username is already in use +BOT_INLINE_DISABLED The inline feature of the bot is disabled \ No newline at end of file From fbd13bec767d3a2cbec6691d92ad833c079009a5 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Tue, 27 Feb 2018 14:49:50 +0100 Subject: [PATCH 17/19] Add INLINE_RESULT_EXPIRED error --- compiler/error/source/400_BAD_REQUEST.tsv | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/compiler/error/source/400_BAD_REQUEST.tsv b/compiler/error/source/400_BAD_REQUEST.tsv index abef742f..ffba8987 100644 --- a/compiler/error/source/400_BAD_REQUEST.tsv +++ b/compiler/error/source/400_BAD_REQUEST.tsv @@ -47,4 +47,5 @@ PHONE_NUMBER_BANNED The phone number is banned ABOUT_TOO_LONG The about text is too long MULTI_MEDIA_TOO_LONG The album contains more than 10 items USERNAME_OCCUPIED The username is already in use -BOT_INLINE_DISABLED The inline feature of the bot is disabled \ No newline at end of file +BOT_INLINE_DISABLED The inline feature of the bot is disabled +INLINE_RESULT_EXPIRED The inline bot query expired \ No newline at end of file From 536efa5f4a86070d872d0fee8864fb05450bb5fe Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Tue, 27 Feb 2018 14:50:43 +0100 Subject: [PATCH 18/19] Add get_inline_bot_results and send_inline_bot_result methods --- pyrogram/client/client.py | 87 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/pyrogram/client/client.py b/pyrogram/client/client.py index 681ab8b1..0a5e6ef1 100644 --- a/pyrogram/client/client.py +++ b/pyrogram/client/client.py @@ -2561,3 +2561,90 @@ class Client: log.info("Contacts count: {}".format(len(contacts.users))) return contacts + + def get_inline_bot_results(self, + bot: int or str, + query: str, + offset: str = "", + location: tuple = None): + """Use this method to get bot results via inline queries. + You can then send a result using :obj:`send_inline_bot_result ` + + Args: + bot (:obj:`int` | :obj:`str`): + Unique identifier of the inline bot you want to get results from. You can specify + a @username (str) or a bot ID (int). + + query (:obj:`str`): + Text of the query (up to 512 characters). + + offset (:obj:`str`): + Offset of the results to be returned. + + location (:obj:`tuple`, optional): + Your location in tuple format (latitude, longitude), e.g.: (51.500729, -0.124583). + Useful for location-based results only. + + Returns: + On Success, `BotResults `_ is returned. + + Raises: + :class:`pyrogram.Error` + """ + return self.send( + functions.messages.GetInlineBotResults( + bot=self.resolve_peer(bot), + peer=types.InputPeerSelf(), + query=query, + offset=offset, + geo_point=types.InputGeoPoint( + lat=location[0], + long=location[1] + ) if location else None + ) + ) + + def send_inline_bot_result(self, + chat_id: int or str, + query_id: int, + result_id: str, + disable_notification: bool = None, + reply_to_message_id: int = None): + """Use this method to send an inline bot result. + Bot results can be retrieved using :obj:`get_inline_bot_results ` + + Args: + chat_id (:obj:`int` | :obj:`str`): + Unique identifier for the target chat or username of the target channel/supergroup + (in the format @username). For your personal cloud storage (Saved Messages) you can + simply use "me" or "self". Phone numbers that exist in your Telegram address book are also supported. + + query_id (:obj:`int`): + Unique identifier for the answered query. + + result_id (:obj:`str`): + Unique identifier for the result that was chosen. + + disable_notification (:obj:`bool`, optional): + Sends the message silently. + Users will receive a notification with no sound. + + reply_to_message_id (:obj:`bool`, optional): + If the message is a reply, ID of the original message. + + Returns: + On success, the sent Message is returned. + + Raises: + :class:`pyrogram.Error` + """ + return self.send( + functions.messages.SendInlineBotResult( + peer=self.resolve_peer(chat_id), + query_id=query_id, + id=result_id, + random_id=self.rnd_id(), + silent=disable_notification or None, + reply_to_msg_id=reply_to_message_id + ) + ) From 5c753d8c77228dc1c30e497f70a6d4a69c12006a Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Tue, 27 Feb 2018 14:57:00 +0100 Subject: [PATCH 19/19] Add inline_bots example --- examples/inline_bots.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 examples/inline_bots.py diff --git a/examples/inline_bots.py b/examples/inline_bots.py new file mode 100644 index 00000000..d5bd43fb --- /dev/null +++ b/examples/inline_bots.py @@ -0,0 +1,15 @@ +from pyrogram import Client + +# Create a new Client +client = Client("example") + +# Start the Client +client.start() + +# Get bot results for "Fuzz Universe" from the inline bot @vid +bot_results = client.get_inline_bot_results("vid", "Fuzz Universe") +# Send the first result (bot_results.results[0]) to your own chat (Saved Messages) +client.send_inline_bot_result("me", bot_results.query_id, bot_results.results[0].id) + +# Stop the client +client.stop()