Telegram bot v Pythonu s python-telegram-bot (v20+)
Krok za krokem k Telegram botovi v Pythonu – BotFather, příkazy, tlačítka, konverzace, upozornění a nasazení přes polling i webhook. Asynchronní API v20+.
Telegram boti jsou praktičtí na notifikace ze serveru, jednoduché asistenty nebo rodinné nástroje. Knihovna python-telegram-bot (PTB) je od verze 20 plně asynchronní a starší návody s Updater a dispatcher už nefungují. Tady je aktuální postup.
1. Vytvoření bota přes BotFather
- V Telegramu otevřete chat s @BotFather.
- Pošlete
/newbot, zadejte zobrazované jméno a uživatelské jméno končící nabot. - BotFather vrátí token ve tvaru
123456:ABC-.... Uložte ho mimo kód.
Příkazem /setcommands můžete nastavit nabídku příkazů, kterou uživatel uvidí po napsání /.
2. Instalace
python3 -m venv .venv
source .venv/bin/activate
pip install "python-telegram-bot>=21"
export TELEGRAM_TOKEN="123456:ABC..."
3. První bot
import logging
import os
from telegram import Update
from telegram.ext import (
Application, CommandHandler, MessageHandler, ContextTypes, filters,
)
logging.basicConfig(level=logging.INFO)
logging.getLogger("httpx").setLevel(logging.WARNING)
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
await update.message.reply_text(
f"Ahoj {update.effective_user.first_name}! Napiš /pomoc."
)
async def pomoc(update: Update, context: ContextTypes.DEFAULT_TYPE):
await update.message.reply_text("/start – přivítání\n/kurz – ukázka tlačítek")
async def echo(update: Update, context: ContextTypes.DEFAULT_TYPE):
await update.message.reply_text(update.message.text.upper())
def main():
app = Application.builder().token(os.environ["TELEGRAM_TOKEN"]).build()
app.add_handler(CommandHandler("start", start))
app.add_handler(CommandHandler("pomoc", pomoc))
app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, echo))
app.run_polling(allowed_updates=Update.ALL_TYPES)
if __name__ == "__main__":
main()
run_polling() se postará o smyčku událostí sama – nevolejte kolem ní asyncio.run. Ztlumení loggeru httpx je užitečné, protože jinak na úrovni INFO loguje každý dotaz na Telegram včetně URL s tokenem.
Handlery se vyhodnocují v pořadí přidání; první, který zprávu přijme, ji zpracuje. Proto filtr ~filters.COMMAND – aby echo nepřebíjelo příkazy.
4. Argumenty příkazů
async def secti(update: Update, context: ContextTypes.DEFAULT_TYPE):
try:
cisla = [float(x) for x in context.args]
except ValueError:
await update.message.reply_text("Použití: /secti 1 2 3")
return
await update.message.reply_text(f"Součet: {sum(cisla)}")
app.add_handler(CommandHandler("secti", secti))
context.args obsahuje slova za příkazem.
5. Inline tlačítka
from telegram import InlineKeyboardButton, InlineKeyboardMarkup
from telegram.ext import CallbackQueryHandler
async def kurz(update: Update, context: ContextTypes.DEFAULT_TYPE):
klavesnice = InlineKeyboardMarkup([
[InlineKeyboardButton("EUR", callback_data="mena:EUR"),
InlineKeyboardButton("USD", callback_data="mena:USD")],
])
await update.message.reply_text("Vyber měnu:", reply_markup=klavesnice)
async def tlacitko(update: Update, context: ContextTypes.DEFAULT_TYPE):
query = update.callback_query
await query.answer() # zruší „načítání“ na tlačítku
mena = query.data.split(":", 1)[1]
await query.edit_message_text(f"Vybral(a) jsi {mena}.")
app.add_handler(CommandHandler("kurz", kurz))
app.add_handler(CallbackQueryHandler(tlacitko, pattern=r"^mena:"))
callback_data má limit 64 bajtů – ukládejte do něj jen identifikátor, ne celá data.
6. Ukládání stavu
PTB nabízí slovníky context.user_data a context.chat_data. Aby přežily restart, zapněte perzistenci:
from telegram.ext import PicklePersistence
persistence = PicklePersistence(filepath="bot_data.pickle")
app = Application.builder().token(TOKEN).persistence(persistence).build()
Pro vážnější použití je lepší vlastní databáze (SQLite stačí).
7. Posílání zpráv z cronu nebo serveru
Pro jednorázovou notifikaci nepotřebujete celou aplikaci – stačí HTTP požadavek na Bot API:
curl -s "https://api.telegram.org/bot$TELEGRAM_TOKEN/sendMessage" \
-d chat_id=123456789 \
-d text="Záloha dokončena ✅"
Své chat_id zjistíte tak, že botovi napíšete a otevřete https://api.telegram.org/bot<TOKEN>/getUpdates.
Uvnitř aplikace lze plánovat úlohy přes JobQueue (instalace pip install "python-telegram-bot[job-queue]"):
async def pripominka(context: ContextTypes.DEFAULT_TYPE):
await context.bot.send_message(chat_id=context.job.chat_id, text="Napij se vody 💧")
async def zapni(update: Update, context: ContextTypes.DEFAULT_TYPE):
context.job_queue.run_repeating(pripominka, interval=3600, chat_id=update.effective_chat.id)
await update.message.reply_text("Připomínky zapnuty.")
8. Polling vs. webhook
| Polling | Webhook | |
|---|---|---|
| Nastavení | žádné | veřejná HTTPS adresa |
| Vhodné pro | vývoj, malé boty, server za NAT | produkci s vyšším provozem |
| Metoda PTB | run_polling() |
run_webhook(...) |
Pro webhook nainstalujte python-telegram-bot[webhooks] a typicky ho provozujte za Nginxem s certifikátem. Pro většinu osobních botů je polling naprosto dostačující.
Časté chyby
Conflict: terminated by other getUpdates request– běží dvě instance bota se stejným tokenem.- Bot ve skupině nereaguje na zprávy – výchozí privacy mode posílá botovi jen příkazy a odpovědi. Vypnete ho v BotFather přes
/setprivacy. - Starý kód s
Updater(token, use_context=True)– to je API verze 13. Přepište naApplication.builder().
Bota pak stačí spustit na serveru jako službu systemd, aby běžel i po restartu.