Ton groupe Telegram a besoin d'un membre qui ne dort jamais ? Un bot peut répondre aux messages, planifier des rappels et poster des infos pendant que tu fais autre chose. python-telegram-bot est la bibliothèque Python de référence pour ça : gratuite, asynchrone, et elle gère les commandes, les messages libres et l'envoi programmé sans que tu touches à l'API HTTP de Telegram. En vingt minutes, ton bot tourne sur ta machine.
Crée ton bot chez BotFather
Avant d'écrire une ligne de code, il te faut un jeton d'identification. Ouvre Telegram, cherche @BotFather (le bot officiel qui crée les bots), envoie /newbot, choisis un nom puis un identifiant qui finit par « bot ». BotFather te répond avec un token de la forme 123456789:AAE... Copie-le, on s'en sert tout de suite. Ne le partage jamais : c'est la clé qui donne accès à ton bot.
Installe python-telegram-bot
La bibliothèque s'installe en une commande. On parle ici de la version 21, qui repose sur asyncio : le code est plus lisible et le bot reste réactif même quand plusieurs personnes lui écrivent en même temps.
pip install python-telegram-botLe squelette : /echo et /start
Commençons par un bot minimal. Trois ingrédients suffisent : un objet Application qui porte ton token, des handlers qui réagissent aux commandes, et run_polling() qui écoute Telegram en continu. Colle ton token, enregistre le script sous bot.py, lance-le avec python bot.py, puis envoie /echo bonjour à ton bot.
from telegram import Update
from telegram.ext import Application, CommandHandler, ContextTypes
TOKEN = "COLLE_ICI_TON_TOKEN"
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
await update.message.reply_text("Salut ! Tape /echo suivi d'un texte.")
async def echo(update: Update, context: ContextTypes.DEFAULT_TYPE):
texte = " ".join(context.args)
await update.message.reply_text(texte if texte else "Usage : /echo ton texte")
def main():
app = Application.builder().token(TOKEN).build()
app.add_handler(CommandHandler("start", start))
app.add_handler(CommandHandler("echo", echo))
app.run_polling()
if __name__ == "__main__":
main()
Décortiquons : CommandHandler("echo", echo) attache la fonction echo à la commande /echo, et context.args contient les mots tapés après la commande. run_polling() interroge Telegram toutes les secondes environ pour récupérer les nouveaux messages. C'est le mode le plus simple pour démarrer, sans serveur web à configurer.
Réponds aux messages sans commande
Les commandes, c'est bien. Mais un vrai bot réagit aussi aux phrases libres. Un MessageHandler équipé de filters.TEXT attrape tout ce qui n'est pas une commande, et on répond selon le contenu du message.
from telegram.ext import MessageHandler, filters
async def repondre(update: Update, context: ContextTypes.DEFAULT_TYPE):
message = update.message.text.lower()
if "salut" in message or "bonjour" in message:
await update.message.reply_text("Salut ! Comment je peux t'aider ?")
elif "qui es-tu" in message:
await update.message.reply_text("Un bot propulsé par python-telegram-bot.")
else:
await update.message.reply_text("Je ne sais pas encore répondre à ça. Tape /aide.")
# dans main(), juste avant run_polling() :
app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, repondre))
Planifie des rappels avec JobQueue
Le JobQueue de python-telegram-bot programme des envois dans le temps : parfait pour des rappels, des messages quotidiens ou un ping toutes les heures. run_once() lance un job unique après N secondes ; run_daily() ferait la même chose à heure fixe, et run_repeating() à intervalle régulier.
async def rappel(context: ContextTypes.DEFAULT_TYPE):
await context.bot.send_message(
chat_id=context.job.chat_id,
text=f"Rappel : {context.job.data}",
)
async def programmer_rappel(update: Update, context: ContextTypes.DEFAULT_TYPE):
if not context.args:
await update.message.reply_text("Usage : /rappel <secondes> <message>")
return
try:
secondes = int(context.args[0])
except ValueError:
await update.message.reply_text("Le premier argument doit être un nombre de secondes.")
return
message = " ".join(context.args[1:]) or "C'est l'heure !"
context.job_queue.run_once(rappel, when=secondes, chat_id=update.effective_chat.id, data=message)
await update.message.reply_text(f"Rappel programmé dans {secondes} secondes.")
# dans main() :
app.add_handler(CommandHandler("rappel", programmer_rappel))
Assemble le tout
Voici le script complet. Les handlers s'ajoutent dans main() : les CommandHandler d'abord, puis le MessageHandler en dernier pour attraper tout le reste. À chaque fonction correspond un morceau déjà vu, rien de neuf.
from telegram import Update
from telegram.ext import (
Application,
CommandHandler,
MessageHandler,
ContextTypes,
filters,
)
TOKEN = "COLLE_ICI_TON_TOKEN"
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
await update.message.reply_text("Salut ! Tape /aide pour la liste des commandes.")
async def aide(update: Update, context: ContextTypes.DEFAULT_TYPE):
await update.message.reply_text(
"/start - me réveiller\n"
"/echo <texte> - répéter ton texte\n"
"/rappel <secondes> <message> - programmer un rappel"
)
async def echo(update: Update, context: ContextTypes.DEFAULT_TYPE):
texte = " ".join(context.args)
await update.message.reply_text(texte if texte else "Usage : /echo ton texte")
async def repondre(update: Update, context: ContextTypes.DEFAULT_TYPE):
message = update.message.text.lower()
if "salut" in message or "bonjour" in message:
await update.message.reply_text("Salut ! Comment je peux t'aider ?")
elif "qui es-tu" in message:
await update.message.reply_text("Un bot propulsé par python-telegram-bot.")
else:
await update.message.reply_text("Je ne sais pas encore répondre à ça. Tape /aide.")
async def rappel(context: ContextTypes.DEFAULT_TYPE):
await context.bot.send_message(
chat_id=context.job.chat_id,
text=f"Rappel : {context.job.data}",
)
async def programmer_rappel(update: Update, context: ContextTypes.DEFAULT_TYPE):
if not context.args:
await update.message.reply_text("Usage : /rappel <secondes> <message>")
return
try:
secondes = int(context.args[0])
except ValueError:
await update.message.reply_text("Le premier argument doit être un nombre de secondes.")
return
message = " ".join(context.args[1:]) or "C'est l'heure !"
context.job_queue.run_once(rappel, when=secondes, chat_id=update.effective_chat.id, data=message)
await update.message.reply_text(f"Rappel programmé dans {secondes} secondes.")
def main():
app = Application.builder().token(TOKEN).build()
app.add_handler(CommandHandler("start", start))
app.add_handler(CommandHandler("aide", aide))
app.add_handler(CommandHandler("echo", echo))
app.add_handler(CommandHandler("rappel", programmer_rappel))
app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, repondre))
print("Bot en marche. Ctrl+C pour arrêter.")
app.run_polling()
if __name__ == "__main__":
main()
Le résultat
En une soixantaine de lignes, tu as un bot qui répond, répète et planifie des rappels. La suite logique : brancher un LLM dans repondre() pour des réponses intelligentes, ou remplacer run_once() par run_daily() pour un message chaque matin à 8 h. Le bot ne demande qu'à grandir, et lui ne prend jamais de pause.
Auteur
Vincent
Développeur fullstack & responsable informatique
Développeur fullstack et responsable informatique. Vulgarise l'IA au quotidien : décryptages sans langue de bois, tutoriels concrets et comparatifs d'outils testés sur le terrain.






