\n\n\n\n Mon parcours avec l'API Telegram Bot : Au-delà des simples notifications - AI7Bot \n

Mon parcours avec l’API Telegram Bot : Au-delà des simples notifications

📖 13 min read2,582 wordsUpdated Mar 26, 2026

Salut tout le monde, 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 silencieux dans le monde des bots : l’API Bot de Telegram. Ce n’est pas le dernier cri, pas aussi spectaculaire que certains des cadres d’IA qui font la une des journaux, mais bon sang, c’est 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 pour des notifications simples. Nous allons explorer comment vous pouvez l’utiliser pour construire des outils interactifs étonnamment sophistiqués – spécifiquement, une expérience utilisateur en plusieurs étapes pour la collecte de données ou l’exécution de commandes complexes. Oubliez les exemples de « envoyer un message » ; nous visons quelque chose de plus substantiel.

Je me souviens de ma première incursion dans les bots Telegram en 2018. J’ai construit un bot super basique qui répétait simplement tout ce que vous lui envoyiez. Révolutionnaire, je sais. Mais même à l’époque, la simplicité pour commencer avec l’API était frappante. Avance rapide 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 arriéré de plus en plus grand 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 arracher 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 de bot vraiment engageante.

Au-delà des commandes simples : construire un flux de travail en plusieurs étapes

Le plus grand obstacle auquel les gens font face lorsqu’ils passent au-delà des « commandes slash » basiques est la gestion du contexte. Si votre bot pose une question, comment sait-il que le message suivant 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 d’une base de données à part entière ici, bien que vous puissiez 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 voulions construire un bot qui aide un utilisateur à enregistrer une nouvelle « tâche » ou une « idée. » Il doit demander un titre, puis une description, puis peut-être un niveau de priorité. Trois étapes distinctes, trois morceaux d’informations distincts que nous devons collecter dans l’ordre. Si nous avons juste une série de commandes /start et /log, cela devient rapidement ingérable.

L’idée principale : état utilisateur et flux de conversation

Mon approche consiste généralement à 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 peut 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 morceaux d’informations collectées jusqu’à présent pour le flux de travail actuel (par exemple, {'title': 'Mon Nouvel Idée', 'description': ''}).

Lorsque qu’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 entrée pour cette étape. Sinon, il le considère comme une commande générale.

Exemple pratique : un bot de journal de tâches simple

Mettons les mains à la pâte. Nous allons construire un bot de journal de tâches très simplifié. L’utilisateur lancera une commande « nouvelle tâche », le bot demandera un titre, puis une description, et enfin confirmera. Pour simplifier, nous stockerons l’état dans un dictionnaire Python. En production, vous voudrez probablement quelque chose de plus persistant comme Redis ou une petite base de données SQLite.

Configurer votre bot et obtenir le jeton API

Pour commencer, vous avez besoin d’un bot. Rendez-vous sur BotFather sur Telegram (recherchez @BotFather), envoyez-lui /newbot, suivez les instructions, et il vous donnera un jeton API. Gardez ce jeton secret !

Nous utiliserons la bibliothèque python-telegram-bot, qui simplifie considérablement l’interaction avec l’API Bot de Telegram. Installez-la avec pip install python-telegram-bot.

La structure du code : gestion de l’état et gestionnaires

Voici un squelette de base pour notre bot. Remarquez comment nous allons utiliser un dictionnaire global user_states pour suivre où chaque utilisateur en est dans sa conversation. Dans un scénario réel, vous voudriez persister cela entre les redémarrages du bot.


from telegram import Update, ForceReply
from telegram.ext import Application, CommandHandler, MessageHandler, filters, ContextTypes

# Remplacez par votre véritable jeton bot
BOT_TOKEN = "YOUR_BOT_TOKEN_HERE"

# --- Gestion d'état de l'utilisateur ---
# Dans une vraie application, cela 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 journal 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 la 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 de flux de travail ---

async def handle_message(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
 """Gère tous les messages entrants et les achemine 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'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 sauvegarderiez 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 la tâche pour cet utilisateur
 user_states[user_id]['task_data'] = {}
 
 else:
 # Si aucun flux de travail spécifique n'est actif, répondre 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écuter le bot jusqu'à ce que l'utilisateur appuie sur Ctrl-C
 application.run_polling(allowed_updates=Update.ALL_TYPES)

if __name__ == "__main__":
 main()

Quelques points à noter ici :

  • user_states : Ce dictionnaire est notre simple machine à états. Chaque ID d’utilisateur correspond à son étape actuelle et à toutes les données collectées.
  • start et new_task commandes : Celles-ci initient ou réinitialisent l’état. new_task définit spécifiquement l’état de l’utilisateur sur 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. Si STATE_AWAITING_TITLE, il suppose que le message est le titre. Si STATE_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 : Cela est crucial pour handle_message. Cela garantit que ce gestionnaire ne traite que les messages en texte brut qui NE SONT PAS des commandes (comme /start ou /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 se passerait-il si nous voulions demander un niveau de priorité, et donner aux utilisateurs 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 une priorité 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

# ... (start, new_task les commandes 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'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 à un nouvel état
 
 keyboard = [
 [InlineKeyboardButton("Élevée", callback_data="priority_high")],
 [InlineKeyboardButton("Moyenne", callback_data="priority_medium")],
 [InlineKeyboardButton("Basse", callback_data="priority_low")],
 ]
 reply_markup = InlineKeyboardMarkup(keyboard)
 await update.message.reply_text('Merci pour la description ! Quelle est la priorité de 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 de 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 # Ceci 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
 
 # Modifier le message pour retirer 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.'
 )
 # Effacer les données de la tâche pour cet utilisateur
 user_states[user_id]['task_data'] = {}
 else:
 await query.edit_message_text('Un problème est survenu ou votre session a expiré. Veuillez recommencer avec /new_task.')

# --- Configuration du bot principal (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.
  • InlineKeyboardButton et InlineKeyboardMarkup : 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, alors gardez-le succinct.
  • 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 attend une réponse rapide à une requête de rappel, même si elle est vide, pour montrer à l’utilisateur que son appui 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 fluide, car le clavier en ligne disparaît une fois qu’un choix est fait.

Cette approche transforme une série de prompts textuels potentiellement encombrants 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 plus de boutons en ligne), ou à la confirmation d’actions avant qu’elles ne soient exécutées.

Conseils pratiques pour votre prochain projet de bot

  1. Adoptez la gestion des états dès le début : Pour tout ce qui dépasse les bots à commande unique, vous *devrez* suivre l’état de l’utilisateur. Commencez simplement avec un dictionnaire, mais prévoyez une persistance si votre bot doit se souvenir des conversations entre les redémarrages.
  2. 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 à l’utilisateur si vous pouvez offrir un bouton.
  3. Modularisez vos gestionnaires : À mesure que votre bot grandit, séparez votre logique en fonctions distinctes ou même en modules. Une gigantesque fonction handle_message devient rapidement ingérable.
  4. Gérez les cas particuliers et les réinitialisations : Que se passe-t-il si un utilisateur tape /new_task au milieu d’un autre flux de travail ? Que se passe-t-il s’il cesse de répondre ? Implémentez des moyens de réinitialiser gracieusement les conversations ou de les ramener dans le flux. Mon exemple gère implicitement cela en réinitialisant l’état avec /new_task.
  5. Testez, testez, testez : Utilisez un bot de test (depuis BotFather) pour le développement. Testez différents flux utilisateurs, des saisies inattendues et une utilisation simultanée.

L’API Bot de Telegram, surtout avec des bibliothèques comme python-telegram-bot, offre un terrain de jeu fantastique pour construire des applications interactives. Ce n’est plus seulement pour envoyer des photos de chats ; vous pouvez construire des outils véritablement utiles avec étonnamment peu d’efforts. Donc, allez-y, expérimentez ces concepts et construisez quelque chose de cool !

Articles connexes

🕒 Published:

💬
Written by Jake Chen

Bot developer who has built 50+ chatbots across Discord, Telegram, Slack, and WhatsApp. Specializes in conversational AI and NLP.

Learn more →
Browse Topics: Best Practices | Bot Building | Bot Development | Business | Operations
Scroll to Top