From 7ae9a065b81d7e5af1d1964ea7ea1acd40a8bc68 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Mon, 7 Jan 2019 10:33:09 +0100 Subject: [PATCH] Update examples --- examples/README.md | 24 ++++---- ...k_query_handler.py => callback_queries.py} | 0 examples/chat_members.py | 10 ++++ examples/dialogs.py | 9 +++ examples/{echo_bot.py => echo.py} | 2 +- examples/get_chat_members.py | 31 ---------- examples/get_chat_members2.py | 50 ---------------- examples/get_history.py | 31 ---------- examples/hello.py | 16 +++++ examples/hello_world.py | 18 ------ examples/history.py | 10 ++++ .../{query_inline_bots.py => inline_bots.py} | 0 examples/keyboards.py | 59 +++++++++++++++++++ .../{raw_update_handler.py => raw_updates.py} | 0 examples/send_bot_keyboards.py | 51 ---------------- examples/welcome.py | 27 +++++++++ examples/welcome_bot.py | 45 -------------- .../types/bots/reply_keyboard_markup.py | 4 +- 18 files changed, 146 insertions(+), 241 deletions(-) rename examples/{callback_query_handler.py => callback_queries.py} (100%) create mode 100644 examples/chat_members.py create mode 100644 examples/dialogs.py rename examples/{echo_bot.py => echo.py} (90%) delete mode 100644 examples/get_chat_members.py delete mode 100644 examples/get_chat_members2.py delete mode 100644 examples/get_history.py create mode 100644 examples/hello.py delete mode 100644 examples/hello_world.py create mode 100644 examples/history.py rename examples/{query_inline_bots.py => inline_bots.py} (100%) create mode 100644 examples/keyboards.py rename examples/{raw_update_handler.py => raw_updates.py} (100%) delete mode 100644 examples/send_bot_keyboards.py create mode 100644 examples/welcome.py delete mode 100644 examples/welcome_bot.py diff --git a/examples/README.md b/examples/README.md index 763db699..6f56ab89 100644 --- a/examples/README.md +++ b/examples/README.md @@ -2,21 +2,21 @@ This folder contains example scripts to show you how **Pyrogram** looks like. -Every script is working right away (provided you correctly set up your credentials), meaning -you can simply copy-paste and run. The only things you have to change are session names and target chats. +Every script is working right away (provided you correctly set up your credentials), meaning you can simply copy-paste +and run. The only things you have to change are session names and target chats. All the examples listed in this directory are licensed under the terms of the [CC0 1.0 Universal](LICENSE) license and can be freely used as basic building blocks for your own applications without worrying about copyrights. Example | Description ---: | :--- -[**hello_world**](hello_world.py) | Demonstration of basic API usages -[**echo_bot**](echo_bot.py) | Echo bot that replies to every private text message -[**welcome_bot**](welcome_bot.py) | The Welcome Bot source code in [@PyrogramChat](https://t.me/pyrogramchat) -[**get_history**](get_history.py) | How to retrieve the full message history of a chat -[**get_chat_members**](get_chat_members.py) | How to get the first 10.000 members of a supergroup/channel -[**get_chat_members2**](get_chat_members2.py) | Improved version to get more than 10.000 members -[**query_inline_bots**](query_inline_bots.py) | How to query an inline bot and send a result to a chat -[**send_bot_keyboards**](send_bot_keyboards.py) | How to send normal and inline keyboards using regular bots -[**callback_query_handler**](callback_query_handler.py) | How to handle queries coming from inline button presses -[**raw_update_handler**](raw_update_handler.py) | How to handle raw updates (old, should be avoided) +[**hello**](hello.py) | Demonstration of basic API usage +[**echo**](echo.py) | Reply to every private text message +[**welcome**](welcome.py) | The Welcome Bot in [@PyrogramChat](https://t.me/pyrogramchat) +[**history**](history.py) | Get the full message history of a chat +[**chat_members**](chat_members.py) | Get all the members of a chat +[**dialogs**](dialogs.py) | Get all of your dialog chats +[**inline_bots**](inline_bots.py) | Query an inline bot and send a result to a chat +[**keyboards**](keyboards.py) | Send normal and inline keyboards using regular bots +[**callback_queries**](callback_queries.py) | Handle queries coming from inline button presses +[**raw_updates**](raw_updates.py) | Handle raw updates (old, should be avoided) diff --git a/examples/callback_query_handler.py b/examples/callback_queries.py similarity index 100% rename from examples/callback_query_handler.py rename to examples/callback_queries.py diff --git a/examples/chat_members.py b/examples/chat_members.py new file mode 100644 index 00000000..87f8613d --- /dev/null +++ b/examples/chat_members.py @@ -0,0 +1,10 @@ +"""This example shows how to get all the members of a chat.""" + +from pyrogram import Client + +app = Client("my_count") +target = "pyrogramchat" # Target channel/supergroup + +with app: + for member in app.iter_chat_members(target): + print(member.user.first_name) diff --git a/examples/dialogs.py b/examples/dialogs.py new file mode 100644 index 00000000..08c769e2 --- /dev/null +++ b/examples/dialogs.py @@ -0,0 +1,9 @@ +"""This example shows how to get the full dialogs list of a user.""" + +from pyrogram import Client + +app = Client("my_account") + +with app: + for dialog in app.iter_dialogs(): + print(dialog.chat.title or dialog.chat.first_name) diff --git a/examples/echo_bot.py b/examples/echo.py similarity index 90% rename from examples/echo_bot.py rename to examples/echo.py index 7a2b0aa7..c60ae291 100644 --- a/examples/echo_bot.py +++ b/examples/echo.py @@ -11,7 +11,7 @@ app = Client("my_account") @app.on_message(Filters.text & Filters.private) def echo(client, message): - message.reply(message.text, quote=True) + message.reply(message.text) app.run() # Automatically start() and idle() diff --git a/examples/get_chat_members.py b/examples/get_chat_members.py deleted file mode 100644 index e0f8c3fa..00000000 --- a/examples/get_chat_members.py +++ /dev/null @@ -1,31 +0,0 @@ -"""This example shows you how to get the first 10.000 members of a chat. -Refer to get_chat_members2.py for more than 10.000 members. -""" - -import time - -from pyrogram import Client -from pyrogram.api.errors import FloodWait - -app = Client("my_account") - -target = "pyrogramchat" # Target channel/supergroup -members = [] # List that will contain all the members of the target chat -offset = 0 # Offset starts at 0 -limit = 200 # Amount of users to retrieve for each API call (max 200) - -with app: - while True: - try: - chunk = app.get_chat_members(target, offset) - except FloodWait as e: # Very large chats could trigger FloodWait - time.sleep(e.x) # When it happens, wait X seconds and try again - continue - - if not chunk.chat_members: - break # No more members left - - members.extend(chunk.chat_members) - offset += len(chunk.chat_members) - -# Now the "members" list contains all the members of the target chat diff --git a/examples/get_chat_members2.py b/examples/get_chat_members2.py deleted file mode 100644 index a4fa9daa..00000000 --- a/examples/get_chat_members2.py +++ /dev/null @@ -1,50 +0,0 @@ -"""This is an improved version of get_chat_members.py - -Since Telegram will return at most 10.000 members for a single query, this script -repeats the search using numbers ("0" to "9") and all the available ascii letters ("a" to "z"). - -This can be further improved by also searching for non-ascii characters (e.g.: Japanese script), -as some user names may not contain ascii letters at all. -""" - -import time -from string import ascii_lowercase - -from pyrogram import Client -from pyrogram.api.errors import FloodWait - -app = Client("my_account") - -target = "pyrogramchat" # Target channel/supergroup -members = {} # List that will contain all the members of the target chat -limit = 200 # Amount of users to retrieve for each API call (max 200) - -# "" + "0123456789" + "abcdefghijklmnopqrstuvwxyz" (as list) -queries = [""] + [str(i) for i in range(10)] + list(ascii_lowercase) - -with app: - for q in queries: - print('Searching for "{}"'.format(q)) - offset = 0 # For each query, offset restarts from 0 - - while True: - try: - chunk = app.get_chat_members(target, offset, query=q) - except FloodWait as e: # Very large chats could trigger FloodWait - print("Flood wait: {} seconds".format(e.x)) - time.sleep(e.x) # When it happens, wait X seconds and try again - continue - - if not chunk.chat_members: - print('Done searching for "{}"'.format(q)) - print() - break # No more members left - - members.update({i.user.id: i for i in chunk.chat_members}) - offset += len(chunk.chat_members) - - print("Total members: {}".format(len(members))) - - print("Grand total: {}".format(len(members))) - -# Now the "members" list contains all the members of the target chat diff --git a/examples/get_history.py b/examples/get_history.py deleted file mode 100644 index 628b5692..00000000 --- a/examples/get_history.py +++ /dev/null @@ -1,31 +0,0 @@ -"""This example shows how to retrieve the full message history of a chat""" - -import time - -from pyrogram import Client -from pyrogram.api.errors import FloodWait - -app = Client("my_account") -target = "me" # "me" refers to your own chat (Saved Messages) -messages = [] # List that will contain all the messages of the target chat -offset_id = 0 # ID of the last message of the chunk - -with app: - while True: - try: - m = app.get_history(target, offset_id=offset_id) - except FloodWait as e: # For very large chats the method call can raise a FloodWait - print("waiting {}".format(e.x)) - time.sleep(e.x) # Sleep X seconds before continuing - continue - - if not m.messages: - break - - messages += m.messages - offset_id = m.messages[-1].message_id - - print("Messages: {}".format(len(messages))) - -# Now the "messages" list contains all the messages sorted by date in -# descending order (from the most recent to the oldest one) diff --git a/examples/hello.py b/examples/hello.py new file mode 100644 index 00000000..54e86812 --- /dev/null +++ b/examples/hello.py @@ -0,0 +1,16 @@ +"""This example demonstrates a basic API usage""" + +from pyrogram import Client + +# Create a new Client instance +app = Client("my_account") + +with app: + # Send a message, Markdown is enabled by default + app.send_message("me", "Hi there! I'm using **Pyrogram**") + + # Send a location + app.send_location("me", 51.500729, -0.124583) + + # Send a sticker + app.send_sticker("me", "CAADBAADhw4AAvLQYAHICbZ5SUs_jwI") diff --git a/examples/hello_world.py b/examples/hello_world.py deleted file mode 100644 index 010725ef..00000000 --- a/examples/hello_world.py +++ /dev/null @@ -1,18 +0,0 @@ -"""This example demonstrates a basic API usage""" - -from pyrogram import Client - -# Create a new Client instance -app = Client("my_account") - -# Start the Client before calling any API method -app.start() - -# Send a message to yourself, Markdown is enabled by default -app.send_message("me", "Hi there! I'm using **Pyrogram**") - -# Send a location to yourself -app.send_location("me", 51.500729, -0.124583) - -# Stop the client when you're done -app.stop() diff --git a/examples/history.py b/examples/history.py new file mode 100644 index 00000000..e8bb14e3 --- /dev/null +++ b/examples/history.py @@ -0,0 +1,10 @@ +"""This example shows how to get the full message history of a chat, starting from the latest message""" + +from pyrogram import Client + +app = Client("my_account") +target = "me" # "me" refers to your own chat (Saved Messages) + +with app: + for message in app.iter_history(target): + print(message.text) diff --git a/examples/query_inline_bots.py b/examples/inline_bots.py similarity index 100% rename from examples/query_inline_bots.py rename to examples/inline_bots.py diff --git a/examples/keyboards.py b/examples/keyboards.py new file mode 100644 index 00000000..147154a3 --- /dev/null +++ b/examples/keyboards.py @@ -0,0 +1,59 @@ +"""This example will show you how to send normal and inline keyboards. + +You must log-in as a regular bot in order to send keyboards (use the token from @BotFather). +Any attempt in sending keyboards with a user account will be simply ignored by the server. + +send_message() is used as example, but a keyboard can be sent with any other send_* methods, +like send_audio(), send_document(), send_location(), etc... +""" + +from pyrogram import Client, ReplyKeyboardMarkup, InlineKeyboardMarkup, InlineKeyboardButton + +# Create a client using your bot token +app = Client("123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11") + +with app: + app.send_message( + "haskell", # Edit this + "This is a ReplyKeyboardMarkup example", + reply_markup=ReplyKeyboardMarkup( + [ + ["A", "B", "C", "D"], # First row + ["E", "F", "G"], # Second row + ["H", "I"], # Third row + ["J"] # Fourth row + ], + resize_keyboard=True # Make the keyboard smaller + ) + ) + + app.send_message( + "haskell", # Edit this + "This is a InlineKeyboardMarkup example", + reply_markup=InlineKeyboardMarkup( + [ + [ # First row + + InlineKeyboardButton( # Generates a callback query when pressed + "Button", + callback_data=b"data" + ), # Note how callback_data must be bytes + InlineKeyboardButton( # Opens a web URL + "URL", + url="https://docs.pyrogram.ml" + ), + ], + [ # Second row + # Opens the inline interface + InlineKeyboardButton( + "Choose chat", + switch_inline_query="pyrogram" + ), + InlineKeyboardButton( # Opens the inline interface in the current chat + "Inline here", + switch_inline_query_current_chat="pyrogram" + ) + ] + ] + ) + ) diff --git a/examples/raw_update_handler.py b/examples/raw_updates.py similarity index 100% rename from examples/raw_update_handler.py rename to examples/raw_updates.py diff --git a/examples/send_bot_keyboards.py b/examples/send_bot_keyboards.py deleted file mode 100644 index 3a15a23a..00000000 --- a/examples/send_bot_keyboards.py +++ /dev/null @@ -1,51 +0,0 @@ -"""This example will show you how to send normal and inline keyboards. - -You must log-in as a regular bot in order to send keyboards (use the token from @BotFather). -Any attempt in sending keyboards with a user account will be simply ignored by the server. - -send_message() is used as example, but a keyboard can be sent with any other send_* methods, -like send_audio(), send_document(), send_location(), etc... -""" - -from pyrogram import Client, ReplyKeyboardMarkup, InlineKeyboardMarkup, InlineKeyboardButton - -# Create a client using your bot token -app = Client("123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11") -app.start() - -app.send_message( - "haskell", # Edit this - "This is a ReplyKeyboardMarkup example", - reply_markup=ReplyKeyboardMarkup( - [ - ["A", "B", "C", "D"], # First row - ["E", "F", "G"], # Second row - ["H", "I"], # Third row - ["J"] # Fourth row - ], - resize_keyboard=True # Make the keyboard smaller - ) -) - -app.send_message( - "haskell", # Edit this - "This is a InlineKeyboardMarkup example", - reply_markup=InlineKeyboardMarkup( - [ - [ # First row - # Generates a callback query when pressed - InlineKeyboardButton("Button", callback_data="data"), - # Opens a web URL - InlineKeyboardButton("URL", url="https://docs.pyrogram.ml"), - ], - [ # Second row - # Opens the inline interface of a bot in another chat with a pre-defined query - InlineKeyboardButton("Choose chat", switch_inline_query="pyrogram"), - # Same as the button above, but the inline interface is opened in the current chat - InlineKeyboardButton("Inline here", switch_inline_query_current_chat="pyrogram"), - ] - ] - ) -) - -app.stop() diff --git a/examples/welcome.py b/examples/welcome.py new file mode 100644 index 00000000..06a38cb7 --- /dev/null +++ b/examples/welcome.py @@ -0,0 +1,27 @@ +"""This is the Welcome Bot in @PyrogramChat. + +It uses the Emoji module to easily add emojis in your text messages and Filters +to make it only work for specific messages in a specific chat. +""" + +from pyrogram import Client, Emoji, Filters + +MENTION = "[{}](tg://user?id={})" +MESSAGE = "{} Welcome to [Pyrogram](https://docs.pyrogram.ml/)'s group chat {}!" + +app = Client("my_account") + + +@app.on_message(Filters.chat("PyrogramChat") & Filters.new_chat_members) +def welcome(client, message): + # Build the new members list (with mentions) by using their first_name + new_members = [MENTION.format(i.first_name, i.id) for i in message.new_chat_members] + + # Build the welcome message by using an emoji and the list we built above + text = MESSAGE.format(Emoji.SPARKLES, ", ".join(new_members)) + + # Send the welcome message, without the web page preview + message.reply(text, disable_web_page_preview=True) + + +app.run() # Automatically start() and idle() diff --git a/examples/welcome_bot.py b/examples/welcome_bot.py deleted file mode 100644 index 4326ed6c..00000000 --- a/examples/welcome_bot.py +++ /dev/null @@ -1,45 +0,0 @@ -"""This is the Welcome Bot in @PyrogramChat. - -It uses the Emoji module to easily add emojis in your text messages and Filters -to make it only work for specific messages in a specific chat. -""" - -from pyrogram import Client, Emoji, Filters - -USER = "**{}**" -MESSAGE = "{} Welcome to [Pyrogram](https://docs.pyrogram.ml/)'s group chat {{}}!".format(Emoji.SPARKLES) - -enabled_groups = Filters.chat("PyrogramChat") -last_welcomes = {} - -app = Client("my_account") - - -@app.on_message(enabled_groups & Filters.new_chat_members) -def welcome(client, message): - chat_id = message.chat.id - - # Get the previous welcome message and members, if any - previous_welcome, previous_members = last_welcomes.pop(chat_id, (None, [])) - - # Delete the previous message, if exists - if previous_welcome: - previous_welcome.delete() - - # Build the new members list by using their first_name. Also append the previous members, if any - new_members = [USER.format(i.first_name) for i in message.new_chat_members] + previous_members - - # Build the welcome message by using an emoji and the list we created above - text = MESSAGE.format(", ".join(new_members)) - - # Actually send the welcome and save the new message and the new members list - last_welcomes[message.chat.id] = message.reply(text, disable_web_page_preview=True), new_members - - -@app.on_message(enabled_groups) -def reset(client, message): - # Don't make the bot delete the previous welcome in case someone talks in the middle - last_welcomes.pop(message.chat.id, None) - - -app.run() # Automatically start() and idle() diff --git a/pyrogram/client/types/bots/reply_keyboard_markup.py b/pyrogram/client/types/bots/reply_keyboard_markup.py index 7840dbe5..afae236d 100644 --- a/pyrogram/client/types/bots/reply_keyboard_markup.py +++ b/pyrogram/client/types/bots/reply_keyboard_markup.py @@ -16,7 +16,7 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . -from typing import List +from typing import List, Union from pyrogram.api.types import KeyboardButtonRow from pyrogram.api.types import ReplyKeyboardMarkup as RawReplyKeyboardMarkup @@ -50,7 +50,7 @@ class ReplyKeyboardMarkup(PyrogramType): """ def __init__(self, - keyboard: List[List[KeyboardButton]], + keyboard: List[List[Union[KeyboardButton, str]]], resize_keyboard: bool = None, one_time_keyboard: bool = None, selective: bool = None):