python-telegram-bot
This library provides a pure Python, asynchronous interface for the Telegram Bot API. It's compatible with Python versions 3.10+. It features convenience methods, shortcuts, and high-level classes within the `telegram.ext` submodule to simplify bot development. It supports all types and methods of the Telegram Bot API 9.5 and receives frequent updates, with new releases typically coming out every few weeks/months.
Warnings
- breaking Version 20.0 introduced significant breaking changes. The `Updater` class was removed and replaced by `Application`. The architecture shifted to `asyncio`, requiring async/await for handler functions. The `File.download` method was split into `File.download_to_drive` and `File.download_to_memory`. Most third-party dependencies became optional, requiring explicit installation for certain features.
- gotcha Since v20.0, `python-telegram-bot` is built on `asyncio` and is generally not thread-safe. Avoid using `telegram.ext.Application/Updater.update_queue`, `telegram.ext.ConversationHandler.check/handle_update`, `telegram.ext.CallbackDataCache`, and runtime modifications to `telegram.ext.filters` classes in multi-threaded environments to prevent race conditions.
- deprecated Timeout arguments (`read_timeout`, `write_timeout`, `connect_timeout`, `pool_timeout`) for `Application.run_polling()` were removed in v22.0.
- deprecated Attributes representing durations/time periods (e.g., `ChatFullInfo.slow_mode_delay`) are migrating from `int` to `datetime.timedelta`. While `int` is currently supported, it's deprecated and will be removed in a future major version.
- gotcha For new Telegram Bot API update types (e.g., `MESSAGE_REACTION_COUNT`, `BUSINESS_CONNECTION`), you must explicitly list them in `Application.run_polling(allowed_updates=...)` or `Bot.set_webhook(allowed_updates=...)` to receive them. Using `Update.ALL_TYPES` is generally safer for comprehensive update reception.
- breaking Version 22.5 addressed a breaking change accidentally introduced in v22.4 regarding the `ReplyParameters` class, where adding a new parameter broke positional arguments.
Install
-
pip install python-telegram-bot -
pip install "python-telegram-bot[all]"
Imports
- Application
from telegram.ext import Application
- CommandHandler
from telegram.ext import CommandHandler
- MessageHandler
from telegram.ext import MessageHandler
- filters
from telegram.ext import filters
- ContextTypes
from telegram.ext import ContextTypes
- Update
from telegram import Update
- Updater
N/A
Quickstart
import os
import logging
from telegram import Update
from telegram.ext import Application, CommandHandler, MessageHandler, filters, ContextTypes
# Enable logging
logging.basicConfig(
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", level=logging.INFO
)
# set higher logging level for httpx to avoid all GET and POST requests being logged
logging.getLogger("httpx").setLevel(logging.WARNING)
logger = logging.getLogger(__name__)
async def start_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""Sends a message when the command /start is issued."""
user = update.effective_user
await update.message.reply_html(
f"Hi {user.mention_html()}!\nI'm an echo bot. Send me anything!",
)
async def help_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""Sends a message when the command /help is issued."""
await update.message.reply_text("Help! Send me a message and I will echo it back!")
async def echo(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""Echo the user message."""
await update.message.reply_text(update.message.text)
async def main() -> None:
"""Start the bot."""
# Replace with your bot's token from BotFather. Get from environment variable.
BOT_TOKEN = os.environ.get('TELEGRAM_BOT_TOKEN')
if not BOT_TOKEN:
raise ValueError("TELEGRAM_BOT_TOKEN environment variable not set.")
# Create the Application and pass it your bot's token.
application = Application.builder().token(BOT_TOKEN).build()
# On different commands - add handlers
application.add_handler(CommandHandler("start", start_command))
application.add_handler(CommandHandler("help", help_command))
# On non command messages - echo the message on Telegram
application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, echo))
# Run the bot until the user presses Ctrl-C
logger.info("Starting bot polling...")
await application.run_polling(allowed_updates=Update.ALL_TYPES)
if __name__ == "__main__":
import asyncio
asyncio.run(main())