From 06aa4c6802478717124b57f03446992964cfa41d Mon Sep 17 00:00:00 2001
From: Poolitzer <25934244+Poolitzer@users.noreply.github.com>
Date: Fri, 25 Mar 2022 13:41:01 +0100
Subject: [PATCH 01/14] Fix: await coroutines
Also put one logging line where it belongs
---
examples/chatmemberbot.py | 4 ++--
examples/contexttypesbot.py | 2 +-
examples/nestedconversationbot.py | 22 +++++++++++-----------
examples/rawapibot.py | 3 +--
4 files changed, 15 insertions(+), 16 deletions(-)
diff --git a/examples/chatmemberbot.py b/examples/chatmemberbot.py
index c3606602be2..1d5899984e2 100644
--- a/examples/chatmemberbot.py
+++ b/examples/chatmemberbot.py
@@ -127,12 +127,12 @@ async def greet_chat_members(update: Update, context: CallbackContext.DEFAULT_TY
member_name = update.chat_member.new_chat_member.user.mention_html()
if not was_member and is_member:
- update.effective_chat.send_message(
+ await update.effective_chat.send_message(
f"{member_name} was added by {cause_name}. Welcome!",
parse_mode=ParseMode.HTML,
)
elif was_member and not is_member:
- update.effective_chat.send_message(
+ await update.effective_chat.send_message(
f"{member_name} is no longer with us. Thanks a lot, {cause_name} ...",
parse_mode=ParseMode.HTML,
)
diff --git a/examples/contexttypesbot.py b/examples/contexttypesbot.py
index c931f92ca33..78f2b1282dd 100644
--- a/examples/contexttypesbot.py
+++ b/examples/contexttypesbot.py
@@ -88,7 +88,7 @@ async def count_click(update: Update, context: CustomContext) -> None:
"""Update the click count for the message."""
context.message_clicks += 1
await update.callback_query.answer()
- update.effective_message.edit_text(
+ await update.effective_message.edit_text(
f'This button was clicked {context.message_clicks} times.',
reply_markup=InlineKeyboardMarkup.from_button(
InlineKeyboardButton(text='Click me!', callback_data='button')
diff --git a/examples/nestedconversationbot.py b/examples/nestedconversationbot.py
index d80c5f7e997..d9974a8fd16 100644
--- a/examples/nestedconversationbot.py
+++ b/examples/nestedconversationbot.py
@@ -120,27 +120,27 @@ async def adding_self(update: Update, context: CallbackContext.DEFAULT_TYPE) ->
async def show_data(update: Update, context: CallbackContext.DEFAULT_TYPE) -> str:
"""Pretty print gathered data."""
- def prettyprint(user_data: Dict[str, Any], level: str) -> str:
- people = user_data.get(level)
+ def pretty_print(data: Dict[str, Any], level: str) -> str:
+ people = data.get(level)
if not people:
return '\nNo information yet.'
- text = ''
+ return_str = ''
if level == SELF:
- for person in user_data[level]:
- text += f"\nName: {person.get(NAME, '-')}, Age: {person.get(AGE, '-')}"
+ for person in data[level]:
+ return_str += f"\nName: {person.get(NAME, '-')}, Age: {person.get(AGE, '-')}"
else:
male, female = _name_switcher(level)
- for person in user_data[level]:
+ for person in data[level]:
gender = female if person[GENDER] == FEMALE else male
- text += f"\n{gender}: Name: {person.get(NAME, '-')}, Age: {person.get(AGE, '-')}"
- return text
+ return_str += f"\n{gender}: Name: {person.get(NAME, '-')}, Age: {person.get(AGE, '-')}"
+ return return_str
user_data = context.user_data
- text = f"Yourself:{prettyprint(user_data, SELF)}"
- text += f"\n\nParents:{prettyprint(user_data, PARENTS)}"
- text += f"\n\nChildren:{prettyprint(user_data, CHILDREN)}"
+ text = f"Yourself:{pretty_print(user_data, SELF)}"
+ text += f"\n\nParents:{pretty_print(user_data, PARENTS)}"
+ text += f"\n\nChildren:{pretty_print(user_data, CHILDREN)}"
buttons = [[InlineKeyboardButton(text='Back', callback_data=str(END))]]
keyboard = InlineKeyboardMarkup(buttons)
diff --git a/examples/rawapibot.py b/examples/rawapibot.py
index 19a9d512fe0..78c855fa46f 100644
--- a/examples/rawapibot.py
+++ b/examples/rawapibot.py
@@ -15,6 +15,7 @@
UPDATE_ID = None
+logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
async def main() -> NoReturn:
@@ -30,8 +31,6 @@ async def main() -> NoReturn:
except IndexError:
UPDATE_ID = None
- logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
-
while True:
try:
await echo(bot)
From eeb4ce56da68e040d19c8a41f664c8a98380aec7 Mon Sep 17 00:00:00 2001
From: Poolitzer <25934244+Poolitzer@users.noreply.github.com>
Date: Sun, 27 Mar 2022 20:22:01 +0200
Subject: [PATCH 02/14] Feat: switch all markdown mentions to hml
---
examples/deeplinking.py | 4 ++--
examples/echobot.py | 4 ++--
examples/inlinebot.py | 6 +++---
3 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/examples/deeplinking.py b/examples/deeplinking.py
index f0644d16aef..3043155ce60 100644
--- a/examples/deeplinking.py
+++ b/examples/deeplinking.py
@@ -73,9 +73,9 @@ async def deep_linked_level_2(update: Update, context: CallbackContext.DEFAULT_T
"""Reached through the SO_COOL payload"""
bot = context.bot
url = helpers.create_deep_linked_url(bot.username, USING_ENTITIES)
- text = f"You can also mask the deep-linked URLs as links: [▶️ CLICK HERE]({url})."
+ text = f"You can also mask the deep-linked URLs as links: ▶️ CLICK HERE."
await update.message.reply_text(
- text, parse_mode=ParseMode.MARKDOWN, disable_web_page_preview=True
+ text, parse_mode=ParseMode.HTML, disable_web_page_preview=True
)
diff --git a/examples/echobot.py b/examples/echobot.py
index 95c34d2d084..584c77fc580 100644
--- a/examples/echobot.py
+++ b/examples/echobot.py
@@ -39,8 +39,8 @@
async def start(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
"""Send a message when the command /start is issued."""
user = update.effective_user
- await update.message.reply_markdown_v2(
- fr'Hi {user.mention_markdown_v2()}\!',
+ await update.message.reply_html(
+ fr'Hi {user.mention_html()}\!',
reply_markup=ForceReply(selective=True),
)
diff --git a/examples/inlinebot.py b/examples/inlinebot.py
index c1cfac18547..499ed3f4df9 100644
--- a/examples/inlinebot.py
+++ b/examples/inlinebot.py
@@ -17,7 +17,7 @@
from telegram import InlineQueryResultArticle, InputTextMessageContent, Update
from telegram.constants import ParseMode
-from telegram.helpers import escape_markdown
+from html import escape
from telegram.ext import Application, InlineQueryHandler, CommandHandler, CallbackContext
# Enable logging
@@ -56,14 +56,14 @@ async def inlinequery(update: Update, context: CallbackContext.DEFAULT_TYPE) ->
id=str(uuid4()),
title="Bold",
input_message_content=InputTextMessageContent(
- f"*{escape_markdown(query)}*", parse_mode=ParseMode.MARKDOWN
+ f"*{escape(query)}*", parse_mode=ParseMode.HTML
),
),
InlineQueryResultArticle(
id=str(uuid4()),
title="Italic",
input_message_content=InputTextMessageContent(
- f"_{escape_markdown(query)}_", parse_mode=ParseMode.MARKDOWN
+ f"_{escape(query)}_", parse_mode=ParseMode.MARKDOWN
),
),
]
From 1ac48099b315b1534e79da705d0d2d673bf3f349 Mon Sep 17 00:00:00 2001
From: poolitzer
Date: Thu, 31 Mar 2022 09:11:01 +0200
Subject: [PATCH 03/14] Feat: readd pre-commits for examples
---
.pre-commit-config.yaml | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index b78c12611f7..ff7196ea707 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -44,6 +44,18 @@ repos:
- APScheduler==3.6.3
- cachetools==4.2.2
- . # this basically does `pip install -e .`n
+ - id: mypy
+ name: mypy-examples
+ files: ^examples/.*\.py$
+ args:
+ - --no-strict-optional
+ - --follow-imports=silent
+ additional_dependencies:
+ - certifi
+ - tornado>=6.1
+ - APScheduler==3.6.3
+ - cachetools==4.2.2
+ - . # this basically does `pip install -e .`
- repo: https://github.com/asottile/pyupgrade
rev: v2.29.0
hooks:
From 99ac29812ee5d87e1733d8fd9a173e553e032c67 Mon Sep 17 00:00:00 2001
From: poolitzer
Date: Thu, 31 Mar 2022 09:23:03 +0200
Subject: [PATCH 04/14] Fix: Apply Black
---
examples/deeplinking.py | 4 +---
examples/nestedconversationbot.py | 4 +++-
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/examples/deeplinking.py b/examples/deeplinking.py
index 3043155ce60..659c2245d3c 100644
--- a/examples/deeplinking.py
+++ b/examples/deeplinking.py
@@ -74,9 +74,7 @@ async def deep_linked_level_2(update: Update, context: CallbackContext.DEFAULT_T
bot = context.bot
url = helpers.create_deep_linked_url(bot.username, USING_ENTITIES)
text = f"You can also mask the deep-linked URLs as links: ▶️ CLICK HERE."
- await update.message.reply_text(
- text, parse_mode=ParseMode.HTML, disable_web_page_preview=True
- )
+ await update.message.reply_text(text, parse_mode=ParseMode.HTML, disable_web_page_preview=True)
async def deep_linked_level_3(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
diff --git a/examples/nestedconversationbot.py b/examples/nestedconversationbot.py
index d9974a8fd16..d08137636f5 100644
--- a/examples/nestedconversationbot.py
+++ b/examples/nestedconversationbot.py
@@ -134,7 +134,9 @@ def pretty_print(data: Dict[str, Any], level: str) -> str:
for person in data[level]:
gender = female if person[GENDER] == FEMALE else male
- return_str += f"\n{gender}: Name: {person.get(NAME, '-')}, Age: {person.get(AGE, '-')}"
+ return_str += (
+ f"\n{gender}: Name: {person.get(NAME, '-')}, Age: {person.get(AGE, '-')}"
+ )
return return_str
user_data = context.user_data
From 188a79c41757f234a1c0a1cd33c25b2b233954d3 Mon Sep 17 00:00:00 2001
From: poolitzer
Date: Thu, 31 Mar 2022 09:38:11 +0200
Subject: [PATCH 05/14] Fix: mypy caught wrong application definition
---
examples/arbitrarycallbackdatabot.py | 10 +++++-----
examples/chatmemberbot.py | 2 +-
examples/errorhandlerbot.py | 3 ---
examples/inlinebot.py | 2 +-
examples/inlinekeyboard.py | 6 +++---
examples/passportbot.py | 3 ---
examples/persistentconversationbot.py | 3 ---
7 files changed, 10 insertions(+), 19 deletions(-)
diff --git a/examples/arbitrarycallbackdatabot.py b/examples/arbitrarycallbackdatabot.py
index 354ec934c2f..15adac4f994 100644
--- a/examples/arbitrarycallbackdatabot.py
+++ b/examples/arbitrarycallbackdatabot.py
@@ -97,13 +97,13 @@ def main() -> None:
.build()
)
- application.application.add_handler(CommandHandler('start', start))
- application.application.add_handler(CommandHandler('help', help_command))
- application.application.add_handler(CommandHandler('clear', clear))
- application.application.add_handler(
+ application.add_handler(CommandHandler('start', start))
+ application.add_handler(CommandHandler('help', help_command))
+ application.add_handler(CommandHandler('clear', clear))
+ application.add_handler(
CallbackQueryHandler(handle_invalid_button, pattern=InvalidCallbackData)
)
- application.application.add_handler(CallbackQueryHandler(list_button))
+ application.add_handler(CallbackQueryHandler(list_button))
# Run the bot until the user presses Ctrl-C
application.run_polling()
diff --git a/examples/chatmemberbot.py b/examples/chatmemberbot.py
index 1d5899984e2..30f7138bc86 100644
--- a/examples/chatmemberbot.py
+++ b/examples/chatmemberbot.py
@@ -153,7 +153,7 @@ def main() -> None:
# Run the bot until the user presses Ctrl-C
# We pass 'allowed_updates' handle *all* updates including `chat_member` updates
# To reset this, simply pass `allowed_updates=[]`
- application.run_polling()(allowed_updates=Update.ALL_TYPES)
+ application.run_polling(allowed_updates=Update.ALL_TYPES)
if __name__ == "__main__":
diff --git a/examples/errorhandlerbot.py b/examples/errorhandlerbot.py
index 8b0079d1648..80e2d049dea 100644
--- a/examples/errorhandlerbot.py
+++ b/examples/errorhandlerbot.py
@@ -72,9 +72,6 @@ def main() -> None:
# Create the Application and pass it your bot's token.
application = Application.builder().token(BOT_TOKEN).build()
- # Get the application to register handlers
- application = application.application
-
# Register the commands...
application.add_handler(CommandHandler('start', start))
application.add_handler(CommandHandler('bad_command', bad_command))
diff --git a/examples/inlinebot.py b/examples/inlinebot.py
index 499ed3f4df9..04da9c897e6 100644
--- a/examples/inlinebot.py
+++ b/examples/inlinebot.py
@@ -14,10 +14,10 @@
"""
import logging
from uuid import uuid4
+from html import escape
from telegram import InlineQueryResultArticle, InputTextMessageContent, Update
from telegram.constants import ParseMode
-from html import escape
from telegram.ext import Application, InlineQueryHandler, CommandHandler, CallbackContext
# Enable logging
diff --git a/examples/inlinekeyboard.py b/examples/inlinekeyboard.py
index 730e70b23cd..b618d4b85ee 100644
--- a/examples/inlinekeyboard.py
+++ b/examples/inlinekeyboard.py
@@ -60,9 +60,9 @@ def main() -> None:
# Create the Application and pass it your bot's token.
application = Application.builder().token("TOKEN").build()
- application.application.add_handler(CommandHandler('start', start))
- application.application.add_handler(CallbackQueryHandler(button))
- application.application.add_handler(CommandHandler('help', help_command))
+ application.add_handler(CommandHandler('start', start))
+ application.add_handler(CallbackQueryHandler(button))
+ application.add_handler(CommandHandler('help', help_command))
# Run the bot until the user presses Ctrl-C
application.run_polling()
diff --git a/examples/passportbot.py b/examples/passportbot.py
index 47d5402ab7d..469de003bd6 100644
--- a/examples/passportbot.py
+++ b/examples/passportbot.py
@@ -109,9 +109,6 @@ def main() -> None:
Application.builder().token("TOKEN").private_key(private_key.read_bytes()).build()
)
- # Get the application to register handlers
- application = application.application
-
# On messages that include passport data call msg
application.add_handler(MessageHandler(filters.PASSPORT_DATA, msg))
diff --git a/examples/persistentconversationbot.py b/examples/persistentconversationbot.py
index 71eb2f5bcba..4aebcd58d83 100644
--- a/examples/persistentconversationbot.py
+++ b/examples/persistentconversationbot.py
@@ -135,9 +135,6 @@ def main() -> None:
persistence = PicklePersistence(filepath='conversationbot')
application = Application.builder().token("TOKEN").persistence(persistence).build()
- # Get the application to register handlers
- application = application.application
-
# Add conversation handler with the states CHOOSING, TYPING_CHOICE and TYPING_REPLY
conv_handler = ConversationHandler(
entry_points=[CommandHandler('start', start)],
From 2d28f1201308ce4e53b0360b1d0c6ce9acc1f4c1 Mon Sep 17 00:00:00 2001
From: poolitzer
Date: Thu, 31 Mar 2022 09:46:58 +0200
Subject: [PATCH 06/14] Fix: missed contexttype
---
examples/contexttypesbot.py | 1 -
1 file changed, 1 deletion(-)
diff --git a/examples/contexttypesbot.py b/examples/contexttypesbot.py
index 78f2b1282dd..6338ff0a39a 100644
--- a/examples/contexttypesbot.py
+++ b/examples/contexttypesbot.py
@@ -116,7 +116,6 @@ def main() -> None:
context_types = ContextTypes(context=CustomContext, chat_data=ChatData)
application = Application.builder().token("TOKEN").context_types(context_types).build()
- application = application.application
# run track_users in its own group to not interfere with the user handlers
application.add_handler(TypeHandler(Update, track_users), group=-1)
application.add_handler(CommandHandler("start", start))
From c3eda6f2b679ee65d0362f88bbc2e990b98aacf9 Mon Sep 17 00:00:00 2001
From: poolitzer
Date: Thu, 31 Mar 2022 09:57:26 +0200
Subject: [PATCH 07/14] Fix: Temporarily fixing black dependency
---
.pre-commit-config.yaml | 2 ++
requirements-dev.txt | 2 ++
2 files changed, 4 insertions(+)
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index ff7196ea707..31751c4477e 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -9,6 +9,8 @@ repos:
args:
- --diff
- --check
+ additional_dependencies:
+ - click==8.0.2
- repo: https://gitlab.com/pycqa/flake8
rev: 4.0.1
hooks:
diff --git a/requirements-dev.txt b/requirements-dev.txt
index ee7a8b6c744..9f3ae43d89d 100644
--- a/requirements-dev.txt
+++ b/requirements-dev.txt
@@ -4,6 +4,8 @@ cryptography!=3.4,!=3.4.1,!=3.4.2,!=3.4.3
pre-commit
# Make sure that the versions specified here match the pre-commit settings!
black==21.9b0
+# hardpinned dependency for black
+click==8.0.2
flake8==4.0.1
pylint==2.12.1
mypy==0.910
From 4007fe0212c79a3a1c54fc6f6608b1cde1dd76c2 Mon Sep 17 00:00:00 2001
From: Poolitzer
Date: Thu, 31 Mar 2022 19:24:16 +0200
Subject: [PATCH 08/14] Fix: Remove markdown leftovers
Co-authored-by: Harshil <37377066+harshil21@users.noreply.github.com>
---
examples/inlinebot.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/examples/inlinebot.py b/examples/inlinebot.py
index 04da9c897e6..3fc31937933 100644
--- a/examples/inlinebot.py
+++ b/examples/inlinebot.py
@@ -63,7 +63,7 @@ async def inlinequery(update: Update, context: CallbackContext.DEFAULT_TYPE) ->
id=str(uuid4()),
title="Italic",
input_message_content=InputTextMessageContent(
- f"_{escape(query)}_", parse_mode=ParseMode.MARKDOWN
+ f"{escape(query)}", parse_mode=ParseMode.HTML
),
),
]
From 7ce6b7836b1cc88e12ba00bd1e192509135ada7e Mon Sep 17 00:00:00 2001
From: Harshil <37377066+harshil21@users.noreply.github.com>
Date: Thu, 31 Mar 2022 23:30:43 +0530
Subject: [PATCH 09/14] verify examples by running them
---
examples/contexttypesbot.py | 7 ++++
examples/conversationbot.py | 2 +-
examples/conversationbot2.py | 2 +-
examples/errorhandlerbot.py | 7 +---
examples/inlinebot.py | 12 +++---
examples/inlinekeyboard2.py | 20 +++++-----
examples/persistentconversationbot.py | 2 +-
examples/pollbot.py | 20 +++++-----
examples/rawapibot.py | 57 +++++++++++++++------------
examples/timerbot.py | 9 ++---
10 files changed, 73 insertions(+), 65 deletions(-)
diff --git a/examples/contexttypesbot.py b/examples/contexttypesbot.py
index 6338ff0a39a..8bbcbe5f3ed 100644
--- a/examples/contexttypesbot.py
+++ b/examples/contexttypesbot.py
@@ -10,6 +10,7 @@
bot.
"""
+import logging
from collections import defaultdict
from typing import DefaultDict, Optional, Set
@@ -25,6 +26,12 @@
Application,
)
+# Enable logging
+logging.basicConfig(
+ format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO
+)
+logger = logging.getLogger(__name__)
+
class ChatData:
"""Custom class for chat_data. Here we store data per message."""
diff --git a/examples/conversationbot.py b/examples/conversationbot.py
index 691e982c13f..3fb171cfe78 100644
--- a/examples/conversationbot.py
+++ b/examples/conversationbot.py
@@ -69,7 +69,7 @@ async def photo(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
"""Stores the photo and asks for a location."""
user = update.message.from_user
photo_file = await update.message.photo[-1].get_file()
- photo_file.download('user_photo.jpg')
+ await photo_file.download('user_photo.jpg')
logger.info("Photo of %s: %s", user.first_name, 'user_photo.jpg')
await update.message.reply_text(
'Gorgeous! Now, send me your location please, or send /skip if you don\'t want to.'
diff --git a/examples/conversationbot2.py b/examples/conversationbot2.py
index 6d5737e8f8b..2e8f854a7f0 100644
--- a/examples/conversationbot2.py
+++ b/examples/conversationbot2.py
@@ -89,7 +89,7 @@ async def received_information(update: Update, context: CallbackContext.DEFAULT_
await update.message.reply_text(
"Neat! Just so you know, this is what you already told me:"
- f"{facts_to_str(user_data)} You can tell me more, or change your opinion"
+ f"{facts_to_str(user_data)}You can tell me more, or change your opinion"
" on something.",
reply_markup=markup,
)
diff --git a/examples/errorhandlerbot.py b/examples/errorhandlerbot.py
index 80e2d049dea..4e59a0341dc 100644
--- a/examples/errorhandlerbot.py
+++ b/examples/errorhandlerbot.py
@@ -18,12 +18,9 @@
)
logger = logging.getLogger(__name__)
-# The token you got from @botfather when you created the bot
-BOT_TOKEN = "TOKEN"
-
# This can be your own ID, or one for a developer group/channel.
# You can use the /start command of this bot to see your chat id.
-DEVELOPER_CHAT_ID = 123456789
+DEVELOPER_CHAT_ID = 476269395
async def error_handler(update: object, context: CallbackContext.DEFAULT_TYPE) -> None:
@@ -70,7 +67,7 @@ async def start(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
def main() -> None:
"""Run the bot."""
# Create the Application and pass it your bot's token.
- application = Application.builder().token(BOT_TOKEN).build()
+ application = Application.builder().token("TOKEN").build()
# Register the commands...
application.add_handler(CommandHandler('start', start))
diff --git a/examples/inlinebot.py b/examples/inlinebot.py
index 3fc31937933..fb6f782e9e0 100644
--- a/examples/inlinebot.py
+++ b/examples/inlinebot.py
@@ -28,7 +28,7 @@
# Define a few command handlers. These usually take the two arguments update and
-# context. Error handlers also receive the raised TelegramError object in error.
+# context.
async def start(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
"""Send a message when the command /start is issued."""
await update.message.reply_text('Hi!')
@@ -39,8 +39,8 @@ async def help_command(update: Update, context: CallbackContext.DEFAULT_TYPE) ->
await update.message.reply_text('Help!')
-async def inlinequery(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
- """Handle the inline query."""
+async def inline_query(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
+ """Handle the inline query. This is run when you type: @botusername """
query = update.inline_query.query
if query == "":
@@ -56,14 +56,14 @@ async def inlinequery(update: Update, context: CallbackContext.DEFAULT_TYPE) ->
id=str(uuid4()),
title="Bold",
input_message_content=InputTextMessageContent(
- f"*{escape(query)}*", parse_mode=ParseMode.HTML
+ f"{escape(query)}", parse_mode=ParseMode.HTML
),
),
InlineQueryResultArticle(
id=str(uuid4()),
title="Italic",
input_message_content=InputTextMessageContent(
- f"{escape(query)}", parse_mode=ParseMode.HTML
+ f"{escape(query)}", parse_mode=ParseMode.HTML
),
),
]
@@ -81,7 +81,7 @@ def main() -> None:
application.add_handler(CommandHandler("help", help_command))
# on non command i.e message - echo the message on Telegram
- application.add_handler(InlineQueryHandler(inlinequery))
+ application.add_handler(InlineQueryHandler(inline_query))
# Run the bot until the user presses Ctrl-C
application.run_polling()
diff --git a/examples/inlinekeyboard2.py b/examples/inlinekeyboard2.py
index cb95637e666..24f67b2adfd 100644
--- a/examples/inlinekeyboard2.py
+++ b/examples/inlinekeyboard2.py
@@ -32,7 +32,7 @@
logger = logging.getLogger(__name__)
# Stages
-FIRST, SECOND = range(2)
+START_ROUTES, END_ROUTES = range(2)
# Callback data
ONE, TWO, THREE, FOUR = range(4)
@@ -56,7 +56,7 @@ async def start(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
# Send message with text and appended InlineKeyboard
await update.message.reply_text("Start handler, Choose a route", reply_markup=reply_markup)
# Tell ConversationHandler that we're in state `FIRST` now
- return FIRST
+ return START_ROUTES
async def start_over(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
@@ -77,7 +77,7 @@ async def start_over(update: Update, context: CallbackContext.DEFAULT_TYPE) -> i
# originated the CallbackQuery. This gives the feeling of an
# interactive menu.
await query.edit_message_text(text="Start handler, Choose a route", reply_markup=reply_markup)
- return FIRST
+ return START_ROUTES
async def one(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
@@ -94,7 +94,7 @@ async def one(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
await query.edit_message_text(
text="First CallbackQueryHandler, Choose a route", reply_markup=reply_markup
)
- return FIRST
+ return START_ROUTES
async def two(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
@@ -111,11 +111,11 @@ async def two(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
await query.edit_message_text(
text="Second CallbackQueryHandler, Choose a route", reply_markup=reply_markup
)
- return FIRST
+ return START_ROUTES
async def three(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
- """Show new choice of buttons"""
+ """Show new choice of buttons. This is the end point of the conversation."""
query = update.callback_query
await query.answer()
keyboard = [
@@ -129,7 +129,7 @@ async def three(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
text="Third CallbackQueryHandler. Do want to start over?", reply_markup=reply_markup
)
# Transfer to conversation state `SECOND`
- return SECOND
+ return END_ROUTES
async def four(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
@@ -146,7 +146,7 @@ async def four(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
await query.edit_message_text(
text="Fourth CallbackQueryHandler, Choose a route", reply_markup=reply_markup
)
- return FIRST
+ return START_ROUTES
async def end(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
@@ -173,13 +173,13 @@ def main() -> None:
conv_handler = ConversationHandler(
entry_points=[CommandHandler('start', start)],
states={
- FIRST: [
+ START_ROUTES: [
CallbackQueryHandler(one, pattern='^' + str(ONE) + '$'),
CallbackQueryHandler(two, pattern='^' + str(TWO) + '$'),
CallbackQueryHandler(three, pattern='^' + str(THREE) + '$'),
CallbackQueryHandler(four, pattern='^' + str(FOUR) + '$'),
],
- SECOND: [
+ END_ROUTES: [
CallbackQueryHandler(start_over, pattern='^' + str(ONE) + '$'),
CallbackQueryHandler(end, pattern='^' + str(TWO) + '$'),
],
diff --git a/examples/persistentconversationbot.py b/examples/persistentconversationbot.py
index 4aebcd58d83..1e871de8b84 100644
--- a/examples/persistentconversationbot.py
+++ b/examples/persistentconversationbot.py
@@ -123,7 +123,7 @@ async def done(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
del context.user_data['choice']
await update.message.reply_text(
- f"I learned these facts about you: {facts_to_str(context.user_data)} Until next time!",
+ f"I learned these facts about you: {facts_to_str(context.user_data)}Until next time!",
reply_markup=ReplyKeyboardRemove(),
)
return ConversationHandler.END
diff --git a/examples/pollbot.py b/examples/pollbot.py
index 2b7898cd1f3..dc4091f724a 100644
--- a/examples/pollbot.py
+++ b/examples/pollbot.py
@@ -69,9 +69,9 @@ async def poll(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
async def receive_poll_answer(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
"""Summarize a users poll vote"""
answer = update.poll_answer
- poll_id = answer.poll_id
+ answered_poll = context.bot_data[answer.poll_id]
try:
- questions = context.bot_data[poll_id]["questions"]
+ questions = answered_poll["questions"]
# this means this poll answer update is from an old poll, we can't do our answering then
except KeyError:
return
@@ -83,16 +83,14 @@ async def receive_poll_answer(update: Update, context: CallbackContext.DEFAULT_T
else:
answer_string += questions[question_id]
await context.bot.send_message(
- context.bot_data[poll_id]["chat_id"],
+ answered_poll["chat_id"],
f"{update.effective_user.mention_html()} feels {answer_string}!",
parse_mode=ParseMode.HTML,
)
- context.bot_data[poll_id]["answers"] += 1
+ answered_poll["answers"] += 1
# Close poll after three participants voted
- if context.bot_data[poll_id]["answers"] == 3:
- await context.bot.stop_poll(
- context.bot_data[poll_id]["chat_id"], context.bot_data[poll_id]["message_id"]
- )
+ if answered_poll["answers"] == 3:
+ await context.bot.stop_poll(answered_poll["chat_id"], answered_poll["message_id"])
async def quiz(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
@@ -158,12 +156,12 @@ def main() -> None:
application = Application.builder().token("TOKEN").build()
application.add_handler(CommandHandler('start', start))
application.add_handler(CommandHandler('poll', poll))
- application.add_handler(PollAnswerHandler(receive_poll_answer))
application.add_handler(CommandHandler('quiz', quiz))
- application.add_handler(PollHandler(receive_quiz_answer))
application.add_handler(CommandHandler('preview', preview))
- application.add_handler(MessageHandler(filters.POLL, receive_poll))
application.add_handler(CommandHandler('help', help_handler))
+ application.add_handler(MessageHandler(filters.POLL, receive_poll))
+ application.add_handler(PollAnswerHandler(receive_poll_answer))
+ application.add_handler(PollHandler(receive_quiz_answer))
# Run the bot until the user presses Ctrl-C
application.run_polling()
diff --git a/examples/rawapibot.py b/examples/rawapibot.py
index 78c855fa46f..eaa964d5b45 100644
--- a/examples/rawapibot.py
+++ b/examples/rawapibot.py
@@ -10,50 +10,57 @@
import logging
from typing import NoReturn
-import telegram
+from telegram import Bot
from telegram.error import NetworkError, Forbidden
-UPDATE_ID = None
-logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
+logging.basicConfig(
+ format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO
+)
+logger = logging.getLogger(__name__)
async def main() -> NoReturn:
"""Run the bot."""
- global UPDATE_ID
- # Telegram Bot Authorization Token
- bot = telegram.Bot('TOKEN')
- # get the first pending update_id, this is so we can skip over it in case
- # we get an "Forbidden" exception.
- try:
- UPDATE_ID = (await bot.get_updates())[0].update_id
- except IndexError:
- UPDATE_ID = None
-
- while True:
+ # Here we use the `async with` syntax to properly initialize and shutdown resources.
+ async with Bot("TOKEN") as bot:
+ # get the first pending update_id, this is so we can skip over it in case
+ # we get a "Forbidden" exception.
try:
- await echo(bot)
- except NetworkError:
- await asyncio.sleep(1)
- except Forbidden:
- # The user has removed or blocked the bot.
- UPDATE_ID += 1
+ update_id = (await bot.get_updates())[0].update_id
+ except IndexError:
+ update_id = None
+ logger.info("listening for new messages...")
+ while True:
+ try:
+ update_id = await echo(bot, update_id)
+ except NetworkError:
+ await asyncio.sleep(1)
+ except Forbidden:
+ # The user has removed or blocked the bot.
+ update_id += 1
-async def echo(bot: telegram.Bot) -> None:
+
+async def echo(bot: Bot, update_id: int) -> None:
"""Echo the message the user sent."""
- global UPDATE_ID
# Request updates after the last update_id
- for update in await bot.get_updates(offset=UPDATE_ID, timeout=10):
- UPDATE_ID = update.update_id + 1
+ updates = await bot.get_updates(offset=update_id, timeout=10)
+ for update in updates:
+ next_update_id = update.update_id + 1
# your bot can receive updates without messages
# and not all messages contain text
if update.message and update.message.text:
# Reply to the message
+ logger.info("Found message %s!", update.message.text)
await update.message.reply_text(update.message.text)
+ return next_update_id
if __name__ == '__main__':
- asyncio.run(main())
+ try:
+ asyncio.run(main())
+ except KeyboardInterrupt: # Ignore exception when Ctrl-C is pressed
+ pass
diff --git a/examples/timerbot.py b/examples/timerbot.py
index 0d04241b5f8..8ff874dea96 100644
--- a/examples/timerbot.py
+++ b/examples/timerbot.py
@@ -31,7 +31,7 @@
# Define a few command handlers. These usually take the two arguments update and
-# context. Error handlers also receive the raised TelegramError object in error.
+# context.
# Best practice would be to replace context with an underscore,
# since context is an unused local variable.
# This being an example and not having context present confusing beginners,
@@ -59,7 +59,7 @@ def remove_job_if_exists(name: str, context: CallbackContext.DEFAULT_TYPE) -> bo
async def set_timer(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
"""Add a job to the queue."""
- chat_id = update.message.chat_id
+ chat_id = update.effective_message.chat_id
try:
# args[0] should contain the time for the timer in seconds
due = int(context.args[0])
@@ -76,7 +76,7 @@ async def set_timer(update: Update, context: CallbackContext.DEFAULT_TYPE) -> No
await update.message.reply_text(text)
except (IndexError, ValueError):
- await update.message.reply_text('Usage: /set ')
+ await update.effective_message.reply_text('Usage: /set ')
async def unset(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
@@ -93,8 +93,7 @@ def main() -> None:
application = Application.builder().token("TOKEN").build()
# on different commands - answer in Telegram
- application.add_handler(CommandHandler("start", start))
- application.add_handler(CommandHandler("help", start))
+ application.add_handler(CommandHandler(["start", "help"], start))
application.add_handler(CommandHandler("set", set_timer))
application.add_handler(CommandHandler("unset", unset))
From bc955d3437906aaafece58973e03e3585630f4da Mon Sep 17 00:00:00 2001
From: "deepsource-autofix[bot]"
<62050782+deepsource-autofix[bot]@users.noreply.github.com>
Date: Thu, 31 Mar 2022 18:04:26 +0000
Subject: [PATCH 10/14] Autofix issues in 1 file
Resolved issues in examples/rawapibot.py via DeepSource Autofix
---
examples/rawapibot.py | 1 -
1 file changed, 1 deletion(-)
diff --git a/examples/rawapibot.py b/examples/rawapibot.py
index eaa964d5b45..c08a1b42fb9 100644
--- a/examples/rawapibot.py
+++ b/examples/rawapibot.py
@@ -22,7 +22,6 @@
async def main() -> NoReturn:
"""Run the bot."""
-
# Here we use the `async with` syntax to properly initialize and shutdown resources.
async with Bot("TOKEN") as bot:
# get the first pending update_id, this is so we can skip over it in case
From bcf0248743532dd346dd9a7dc96757eecf62daf4 Mon Sep 17 00:00:00 2001
From: Harshil <37377066+harshil21@users.noreply.github.com>
Date: Thu, 31 Mar 2022 23:36:41 +0530
Subject: [PATCH 11/14] dont use my dev chat id
---
examples/errorhandlerbot.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/examples/errorhandlerbot.py b/examples/errorhandlerbot.py
index 4e59a0341dc..8f78be734ac 100644
--- a/examples/errorhandlerbot.py
+++ b/examples/errorhandlerbot.py
@@ -20,7 +20,7 @@
# This can be your own ID, or one for a developer group/channel.
# You can use the /start command of this bot to see your chat id.
-DEVELOPER_CHAT_ID = 476269395
+DEVELOPER_CHAT_ID = 123456789
async def error_handler(update: object, context: CallbackContext.DEFAULT_TYPE) -> None:
From 31d178e201127c62802c7e5530cfa40d1ce4ef11 Mon Sep 17 00:00:00 2001
From: Harshil <37377066+harshil21@users.noreply.github.com>
Date: Thu, 31 Mar 2022 23:39:05 +0530
Subject: [PATCH 12/14] remove unused backslash from string
---
examples/echobot.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/examples/echobot.py b/examples/echobot.py
index 584c77fc580..9a011091cff 100644
--- a/examples/echobot.py
+++ b/examples/echobot.py
@@ -40,7 +40,7 @@ async def start(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
"""Send a message when the command /start is issued."""
user = update.effective_user
await update.message.reply_html(
- fr'Hi {user.mention_html()}\!',
+ fr'Hi {user.mention_html()}!',
reply_markup=ForceReply(selective=True),
)
From 411a5f03374af85259c2d30427b3ec68937baf89 Mon Sep 17 00:00:00 2001
From: Harshil <37377066+harshil21@users.noreply.github.com>
Date: Sat, 2 Apr 2022 14:25:27 +0530
Subject: [PATCH 13/14] Apply suggestions from code review
Co-authored-by: Bibo-Joshi <22366557+Bibo-Joshi@users.noreply.github.com>
---
examples/rawapibot.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/examples/rawapibot.py b/examples/rawapibot.py
index c08a1b42fb9..2d451dc3b37 100644
--- a/examples/rawapibot.py
+++ b/examples/rawapibot.py
@@ -42,7 +42,7 @@ async def main() -> NoReturn:
update_id += 1
-async def echo(bot: Bot, update_id: int) -> None:
+async def echo(bot: Bot, update_id: int) -> int:
"""Echo the message the user sent."""
# Request updates after the last update_id
updates = await bot.get_updates(offset=update_id, timeout=10)
@@ -56,6 +56,7 @@ async def echo(bot: Bot, update_id: int) -> None:
logger.info("Found message %s!", update.message.text)
await update.message.reply_text(update.message.text)
return next_update_id
+ return update_id
if __name__ == '__main__':
From f5f28388ea211d212d1704225c3c18b81e624eca Mon Sep 17 00:00:00 2001
From: Hinrich Mahler <22366557+Bibo-Joshi@users.noreply.github.com>
Date: Sun, 10 Apr 2022 15:43:36 +0200
Subject: [PATCH 14/14] Update passportbot.html, minor tweak in {passport,
payment}bot.py
---
examples/passportbot.html | 39 ++++++++++++++++++++++-----------------
examples/passportbot.py | 4 ++--
examples/paymentbot.py | 8 ++++----
3 files changed, 28 insertions(+), 23 deletions(-)
diff --git a/examples/passportbot.html b/examples/passportbot.html
index 4e37f0c69c1..b25c51f6a50 100644
--- a/examples/passportbot.html
+++ b/examples/passportbot.html
@@ -3,27 +3,32 @@
Telegram passport test!
-
-
-
-
-
-
+
+
Telegram passport test
+
+
+
+