Bonjour à tous, Marcus ici de ai7bot.com. Nous sommes le 20 mars 2026, et j’ai beaucoup réfléchi dernièrement à quelque chose qui est devenu un peu un cheval de bataille discret dans le monde des bots : l’API Bot de Telegram. Ce n’est pas le plus nouveau sur le marché, pas aussi flashy que certains des frameworks d’IA qui font la une des journaux, mais c’est tellement puissant et, plus important encore, incroyablement accessible. Aujourd’hui, je veux parler de la façon dont l’API Bot de Telegram n’est plus seulement destinée aux simples notifications. Nous allons explorer comment vous pouvez l’utiliser pour créer des outils interactifs étonnamment sophistiqués – en particulier, une expérience utilisateur en plusieurs étapes pour la collecte de données ou l’exécution de commandes complexes. Oubliez ces exemples de « envoyer un message » ; nous allons pour quelque chose de plus substantiel.
Je me souviens de ma première incursion dans les bots Telegram en 2018. J’ai créé un bot super basique qui se contentait de répéter tout ce que vous lui envoyiez. Révolutionnaire, je sais. Mais même à l’époque, la simplicité de démarrer avec l’API était frappante. Avançons jusqu’à aujourd’hui, et je l’ai utilisée pour tout, des outils internes d’équipe qui suivent les mises à jour de projet à un bot qui m’aide à gérer mon interminable liste d’articles à écrire. Ce qui est souvent négligé, c’est à quel point Telegram a bien développé son API pour gérer des interactions complexes sans vous tirer les cheveux. Nous parlons de gestion d’état, de claviers en ligne, et de claviers personnalisés – tous les ingrédients pour une expérience bot vraiment engageante.
Au-delà des Commandes Simples : Construire un Flux de Travail en Plusieurs Étapes
Le plus grand obstacle auquel les gens sont confrontés lorsqu’ils passent au-delà des « commandes slash » de base est la gestion du contexte. Si votre bot pose une question, comment sait-il que le prochain message de l’utilisateur est la réponse à cette question spécifique, et non une nouvelle commande ou une pensée aléatoire ? C’est là que la gestion d’état entre en jeu. Nous ne parlons pas ici d’une base de données à part entière, même si vous pourriez certainement en intégrer une. Pour de nombreuses applications, un simple dictionnaire en mémoire ou un magasin clé-valeur léger est parfaitement suffisant.
Imaginons que nous voulons construire un bot qui aide un utilisateur à enregistrer une nouvelle « tâche » ou « idée. » Il doit demander un titre, puis une description, puis peut-être un niveau de priorité. Trois étapes distinctes, trois informations distinctes que nous devons collecter dans l’ordre. Si nous n’avons qu’une série de commandes /start et /log, cela devient rapidement ingérable.
L’Idée Centrale : État de l’Utilisateur et Flux de Conversation
Mon approche implique généralement de maintenir un dictionnaire où la clé est l’ID de l’utilisateur et la valeur est un objet représentant leur état de conversation actuel. Cet objet d’état pourrait contenir :
current_step: Un enum ou une chaîne indiquant où ils en sont dans le flux de travail (par exemple, ‘AWAITING_TITLE’, ‘AWAITING_DESCRIPTION’).temp_data: Un dictionnaire pour stocker les informations collectées jusqu’à présent pour le flux de travail actuel (par exemple,{'title': 'Ma Nouvelle Idée', 'description': ''}).
Lorsque un message arrive, le bot vérifie l’état de l’utilisateur. S’il est dans une étape spécifique du flux de travail, il traite son message comme une entrée pour cette étape. Sinon, il le considère comme une commande générale.
Exemple Pratique : Un Bot Simple de Journalisation de Tâches
Mettons la main à la pâte. Nous allons construire un bot de journalisation de tâches très simplifié. L’utilisateur initiera une commande « nouvelle tâche », le bot demandera un titre, puis une description, et enfin confirmera. Pour des raisons de simplicité, nous allons stocker l’état dans un dictionnaire Python. Pour la production, vous voudriez probablement quelque chose de plus persistant comme Redis ou une petite base de données SQLite.
Mise en Place de Votre Bot et Obtention du Token API
Tout d’abord, vous avez besoin d’un bot. Allez sur BotFather sur Telegram (cherchez @BotFather), envoyez-lui /newbot, suivez les instructions, et il vous donnera un token API. Gardez ce token secret !
Nous utiliserons la bibliothèque python-telegram-bot, qui simplifie énormément l’interaction avec l’API Bot de Telegram. Installez-la avec pip install python-telegram-bot.
La Structure du Code : Gestion des États et Gestionnaires
Voici un squelette de base pour notre bot. Remarquez comment nous allons utiliser un dictionnaire global user_states pour garder trace de l’endroit où chaque utilisateur en est dans sa conversation. Dans un scénario réel, vous voudriez le rendre persistant à travers les redémarrages du bot.
from telegram import Update, ForceReply
from telegram.ext import Application, CommandHandler, MessageHandler, filters, ContextTypes
# Remplacez par votre token du bot
BOT_TOKEN = "YOUR_BOT_TOKEN_HERE"
# --- Gestion de l'État de l'Utilisateur ---
# Dans une application réelle, ceci serait persistant (par exemple, Redis, base de données)
user_states = {}
# Définir les états pour notre flux de travail
STATE_NONE = 0
STATE_AWAITING_TITLE = 1
STATE_AWAITING_DESCRIPTION = 2
# --- Commandes du Bot ---
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""Envoie un message de bienvenue lorsque la commande /start est émise."""
user_id = update.effective_user.id
user_states[user_id] = {'current_step': STATE_NONE, 'task_data': {}}
await update.message.reply_text('Bonjour ! Je suis votre bot de journalisation de tâches. Utilisez /new_task pour commencer à enregistrer une tâche.')
async def new_task(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""Initie le flux de travail de nouvelle tâche."""
user_id = update.effective_user.id
user_states[user_id] = {'current_step': STATE_AWAITING_TITLE, 'task_data': {}}
await update.message.reply_text('D'accord, créons une nouvelle tâche. Quel est le titre ?')
# --- Gestionnaire de Messages pour les Étapes du Flux de Travail ---
async def handle_message(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""Gère tous les messages entrants et les dirige en fonction de l'état de l'utilisateur."""
user_id = update.effective_user.id
text = update.message.text
current_state = user_states.get(user_id, {'current_step': STATE_NONE})['current_step']
task_data = user_states.get(user_id, {'task_data': {}})['task_data']
if current_state == STATE_AWAITING_TITLE:
task_data['title'] = text
user_states[user_id]['task_data'] = task_data
user_states[user_id]['current_step'] = STATE_AWAITING_DESCRIPTION
await update.message.reply_text(f'Bien compris. Titre : "{text}". Maintenant, veuillez fournir une description pour la tâche.')
elif current_state == STATE_AWAITING_DESCRIPTION:
task_data['description'] = text
user_states[user_id]['task_data'] = task_data
user_states[user_id]['current_step'] = STATE_NONE # Réinitialiser l'état
# Ici, vous enregistreriez généralement task_data dans une base de données ou un fichier
await update.message.reply_text(
f'Tâche créée !\nTitre : {task_data["title"]}\nDescription : {task_data["description"]}\n\n'
f'Vous pouvez commencer une nouvelle tâche avec /new_task.'
)
# Effacer les données de tâche pour cet utilisateur
user_states[user_id]['task_data'] = {}
else:
# Si aucun flux de travail spécifique n'est actif, répondez avec un message par défaut
await update.message.reply_text('Je ne comprends pas cela. Essayez /new_task pour commencer à créer une tâche.')
# --- Configuration Principale du Bot ---
def main() -> None:
"""Démarre le bot."""
application = Application.builder().token(BOT_TOKEN).build()
# Enregistrer les gestionnaires
application.add_handler(CommandHandler("start", start))
application.add_handler(CommandHandler("new_task", new_task))
application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_message))
# Exécutez le bot jusqu'à ce que l'utilisateur appuie sur Ctrl-C
application.run_polling(allowed_updates=Update.ALL_TYPES)
if __name__ == "__main__":
main()
Quelques éléments à noter ici :
user_states: Ce dictionnaire est notre machine d’état simple. Chaque ID d’utilisateur est mappé à son étape actuelle et à ses données collectées.startetnew_taskcommandes : Ces commandes initient ou réinitialisent l’état.new_taskfixe spécifiquement l’état de l’utilisateur àSTATE_AWAITING_TITLE.handle_message: C’est le cheval de bataille. Il vérifie l’état actuel de l’utilisateur et agit en conséquence. SiSTATE_AWAITING_TITLE, il suppose que le message est le titre. SiSTATE_AWAITING_DESCRIPTION, il suppose que le message est la description. Après avoir collecté toutes les infos, il réinitialise l’état àSTATE_NONE.filters.TEXT & ~filters.COMMAND: C’est crucial pourhandle_message. Cela garantit que ce gestionnaire ne traite que les messages en texte brut qui ne sont PAS des commandes (comme/startou/new_task), évitant ainsi les conflits avec nos gestionnaires de commandes.
Ajouter une Touche d’Interactivité : Claviers en Ligne pour Confirmation
Au lieu de simplement demander une description, que diriez-vous de demander un niveau de priorité, et de donner à l’utilisateur des options prédéfinies ? C’est là que les Claviers en Ligne de Telegram brillent. Ils apparaissent directement attachés à un message et envoient des « données de rappel » lorsqu’ils sont tapés, plutôt qu’un message complet.
Modifions notre flux de travail pour demander la priorité en utilisant un clavier en ligne après la description.
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup
from telegram.ext import Application, CommandHandler, MessageHandler, CallbackQueryHandler, filters, ContextTypes
# ... (BOT_TOKEN, user_states, STATE_NONE, STATE_AWAITING_TITLE, STATE_AWAITING_DESCRIPTION) ...
STATE_AWAITING_PRIORITY = 3 # Nouvel état
# ... (les commandes start, new_task restent les mêmes) ...
async def handle_message(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
user_id = update.effective_user.id
text = update.message.text
current_state = user_states.get(user_id, {'current_step': STATE_NONE})['current_step']
task_data = user_states.get(user_id, {'task_data': {}})['task_data']
if current_state == STATE_AWAITING_TITLE:
task_data['title'] = text
user_states[user_id]['task_data'] = task_data
user_states[user_id]['current_step'] = STATE_AWAITING_DESCRIPTION
await update.message.reply_text(f'Bien compris. Titre : "{text}". Maintenant, veuillez fournir une description pour la tâche.')
elif current_state == STATE_AWAITING_DESCRIPTION:
task_data['description'] = text
user_states[user_id]['task_data'] = task_data
user_states[user_id]['current_step'] = STATE_AWAITING_PRIORITY # Passer au nouvel état
keyboard = [
[InlineKeyboardButton("Élevé", callback_data="priority_high")],
[InlineKeyboardButton("Moyen", callback_data="priority_medium")],
[InlineKeyboardButton("Bas", callback_data="priority_low")],
]
reply_markup = InlineKeyboardMarkup(keyboard)
await update.message.reply_text('Merci pour la description ! Quelle est la priorité pour cette tâche ?', reply_markup=reply_markup)
else:
await update.message.reply_text('Je ne comprends pas cela. Essayez /new_task pour commencer à créer une tâche.')
async def handle_callback_query(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""Gère les pressions sur les boutons du clavier en ligne."""
query = update.callback_query
await query.answer() # Répondez toujours aux requêtes de rappel, même si c'est vide
user_id = query.from_user.id
data = query.data # C'est le callback_data que nous avons défini dans les boutons
current_state = user_states.get(user_id, {'current_step': STATE_NONE})['current_step']
task_data = user_states.get(user_id, {'task_data': {}})['task_data']
if current_state == STATE_AWAITING_PRIORITY and data.startswith('priority_'):
task_data['priority'] = data.split('_')[1] # Extraire 'high', 'medium', 'low'
user_states[user_id]['task_data'] = task_data
user_states[user_id]['current_step'] = STATE_NONE # Réinitialiser l'état
# Éditez le message pour supprimer le clavier et montrer la confirmation
await query.edit_message_text(
f'Tâche créée !\nTitre : {task_data["title"]}\nDescription : {task_data["description"]}\n'
f'Priorité : {task_data["priority"].capitalize()}\n\nVous pouvez commencer une nouvelle tâche avec /new_task.'
)
# Effacez les données de la tâche pour cet utilisateur
user_states[user_id]['task_data'] = {}
else:
await query.edit_message_text('Quelque chose a mal tourné ou votre session a expiré. Veuillez recommencer avec /new_task.')
# --- Configuration principale du Bot (mise à jour) ---
def main() -> None:
application = Application.builder().token(BOT_TOKEN).build()
application.add_handler(CommandHandler("start", start))
application.add_handler(CommandHandler("new_task", new_task))
application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_message))
application.add_handler(CallbackQueryHandler(handle_callback_query)) # Nouveau gestionnaire pour les boutons en ligne
application.run_polling(allowed_updates=Update.ALL_TYPES)
if __name__ == "__main__":
main()
Les ajouts clés ici sont :
STATE_AWAITING_PRIORITY: Un nouvel état à gérer.InlineKeyboardButtonetInlineKeyboardMarkup: Utilisés pour construire les boutons interactifs.callback_data: Une chaîne associée à chaque bouton. C’est ce qui est renvoyé à votre bot lorsque le bouton est pressé. Il est limité à 64 octets, donc gardez-le concis.CallbackQueryHandler: Un nouveau type de gestionnaire dans notre configuration principale, spécifiquement pour écouter ces pressions de boutons en ligne.query.answer(): Important pour l’UX. Telegram s’attend à une réponse rapide à une requête de rappel, même si elle est vide, pour montrer à l’utilisateur que son tapotement a été enregistré.query.edit_message_text(): Au lieu d’envoyer un nouveau message, nous mettons à jour l’existant. Cela rend le flux de la conversation beaucoup plus propre, car le clavier en ligne disparaît une fois un choix fait.
Cette approche transforme une série de messages texte potentiellement maladroite en une expérience beaucoup plus intuitive et conviviale. Imaginez étendre cela à la sélection de catégories, de dates à partir d’un sélecteur de calendrier (en utilisant d’autres boutons en ligne), ou à la confirmation d’actions avant leur exécution.
Conseils concrets pour votre prochain projet de bot
- Adoptez la gestion des états tôt : Pour tout ce qui dépasse les bots à commande unique, vous *aurez* besoin de suivre l’état de l’utilisateur. Commencez simple avec un dictionnaire, mais prévoyez la persistance si votre bot doit se souvenir des conversations à travers des redémarrages.
- Utilisez les éléments UI de Telegram : Les claviers en ligne et les claviers de réponse personnalisés sont incroyablement puissants pour guider les utilisateurs, offrir des choix et simplifier l’entrée. Ne faites pas taper tout aux utilisateurs si vous pouvez offrir un bouton.
- Modularisez vos gestionnaires : Au fur et à mesure que votre bot évolue, séparez votre logique en fonctions distinctes ou même en modules. Une énorme fonction
handle_messagedevient rapidement ingérable. - Gérez les cas particuliers et les réinitialisations : Que se passe-t-il si un utilisateur tape
/new_taskau milieu d’un autre flux de travail ? Que se passe-t-il s’ils cessent simplement de répondre ? Mettez en œuvre des moyens de réinitialiser les conversations avec élégance ou de les inciter à revenir dans le flux. Mon exemple gère implicitement cela en réinitialisant l’état avec/new_task. - Testez, testez, testez : Utilisez un bot de test (de BotFather) pour le développement. Testez différents flux d’utilisateurs, des entrées inattendues et des utilisations simultanées.
L’API du bot Telegram, en particulier avec des bibliothèques comme python-telegram-bot, offre un terrain de jeu fantastique pour la construction d’applications interactives. Ce n’est plus seulement pour envoyer des photos de chats ; vous pouvez construire des outils vraiment utiles avec étonnamment peu d’efforts. Alors, allez-y, expérimentez avec ces concepts et construisez quelque chose de cool !
Articles connexes
- Débloquer la monétisation d’applications mobiles hyper-personnalisées : l’agent AI RevenueCat en 2026
- Construire des chatbots de production : une plongée pratique
- Quel est le rôle de l’IA dans la conception de chatbots
🕒 Published:
Related Articles
- L’écart de compétences en IA : Ce n’est plus seulement une question de connaître Python.
- Comment déployer des chatbots sur les réseaux sociaux
- Abonnementsüberdruss? AI7Bot’s Hat eine bessere Idee (und Nano Banana 2)
- Die Entschlüsselung der hyper-personalisierten Monetarisierung von Mobilanwendungen: Der RevenueCat AI-Agent im Jahr 2026