\n\n\n\n J'ai créé un bot Telegram qui planifie mes messages - AI7Bot \n

J’ai créé un bot Telegram qui planifie mes messages

📖 13 min read2,526 wordsUpdated Mar 26, 2026

Salut tout le monde, c’est Marcus d’ai7bot.com. Aujourd’hui, je veux parler de quelque chose qui fait du bruit dans mes projets de développement personnels récemment : les bots Telegram. Plus précisément, je veux explorer comment faire de votre bot Telegram non seulement un répondant, mais un planificateur. Oubliez les simples trucs de « hello world » ; nous allons créer un bot qui se souvient de choses pour vous et envoie des messages à des moments spécifiques. Pensez à cela comme à votre assistant numérique personnel et silencieux, vivant directement dans vos discussions Telegram.

Je me souviens qu’il y a quelques mois, j’essayais de coordonner une session hebdomadaire de D&D avec mon groupe. Nous oublions toujours qui accueillait, à quelle heure nous étions d’accord et quels en-cas tout le monde apportait. Nous avons essayé des notes partagées, des calendriers, tout. Mais le dénominateur commun était toujours Telegram. C’est alors que j’ai eu une révélation : pourquoi ne pas créer un bot qui nous rappelle simplement ? Pas juste un rappel unique, mais quelque chose de récurrent, quelque chose qui s’adapte. Cette petite frustration m’a conduit dans un terrier de lapin, et ce que j’ai trouvé était étonnamment simple à mettre en œuvre une fois que vous avez franchi l’étape de configuration initiale.

Au-delà des Réponses Simples : Le Pouvoir des Messages Planifiés

La plupart des bots Telegram de base sont réactifs. Vous leur envoyez une commande, ils renvoient une réponse. C’est super pour des requêtes simples, mais cela ne tire pas vraiment parti du potentiel complet d’un bot. La vraie magie se produit lorsque votre bot peut être proactif – lorsqu’il peut initier des conversations, envoyer des mises à jour, ou vous rappeler quelque chose sans que vous ayez à le provoquer d’abord. C’est là que les messages planifiés entrent en jeu.

Imaginez un bot qui :

  • Rappelle à votre équipe les réunions quotidiennes cinq minutes avant qu’elles ne commencent.
  • Vous envoie un bulletin météo personnalisé tous les matins à 7 heures.
  • Vous avertit des délais importants pour un projet.
  • Envoie un message à votre groupe de D&D tous les dimanches à 15 heures avec un message « session bientôt ! ».

Les possibilités sont infinies. Et le meilleur ? Ce n’est pas aussi compliqué que vous pourriez le penser. Nous allons utiliser Python, un langage populaire pour le développement de bots, et quelques bibliothèques fiables.

Ce Dont Nous Aurons Besoin : Les Essentiels

Avant de plonger dans le code, énumérons nos outils :

  1. Python 3 : Si vous ne l’avez pas, allez le chercher. C’est l’épine dorsale de notre bot.
  2. python-telegram-bot library : C’est notre interface principale avec l’API des Bots Telegram. Elle gère toute la communication délicate.
  3. APScheduler library : C’est l’étoile du spectacle pour la planification. Elle nous permet d’exécuter des fonctions à des moments ou intervalles spécifiques.

Vous pouvez installer les bibliothèques Python en utilisant pip :


pip install python-telegram-bot APScheduler

Et, bien sûr, vous aurez besoin d’un token de bot Telegram. Si vous n’avez pas encore créé de bot, allez voir BotFather sur Telegram, envoyez-lui /newbot et suivez les instructions. Il vous donnera un token – gardez-le en sécurité !

Mise en Place de la Structure de Base du Bot

Tout d’abord, mettons en route notre bot Telegram basique. Cette partie devrait être familière si vous avez déjà développé un bot auparavant.


from telegram import Update
from telegram.ext import Application, CommandHandler, ContextTypes

# Remplacez par le token réel de votre bot donné par BotFather
BOT_TOKEN = "YOUR_TELEGRAM_BOT_TOKEN"

async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
 """Envoie un message de bienvenue lorsque la commande /start est émise."""
 await update.message.reply_text("Bonjour ! Je suis votre bot de planification. Utilisez /help pour voir ce que je peux faire.")

async def help_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
 """Envoie un message d'aide."""
 await update.message.reply_text("Je peux planifier des messages pour vous. Essayez /schedule pour définir un rappel !")

def main() -> None:
 """Démarre le bot."""
 application = Application.builder().token(BOT_TOKEN).build()

 application.add_handler(CommandHandler("start", start))
 application.add_handler(CommandHandler("help", help_command))

 print("Bot démarré et à l'écoute...")
 application.run_polling(allowed_updates=Update.ALL_TYPES)

if __name__ == "__main__":
 main()

Exécutez ce script, et si vous envoyez /start ou /help à votre bot, vous devriez recevoir une réponse. C’est notre fondation. Maintenant, intégrons le planificateur.

Présentation d’APScheduler : Votre Gardien du Temps

APScheduler signifie « Advanced Python Scheduler ». C’est une bibliothèque solide qui vous permet de planifier des fonctions Python pour qu’elles s’exécutent à des moments, des dates ou des intervalles spécifiques. Nous utiliserons son BlockingScheduler, qui s’exécute dans le fil principal de notre application.

L’idée de base est la suivante : lorsque un utilisateur demande à notre bot de planifier quelque chose, nous allons stocker cette demande et ensuite utiliser APScheduler pour ajouter un travail. Lorsque le moment est venu, APScheduler exécutera une fonction qui enverra le message à l’utilisateur.

Planification de Notre Premier Message

Modifions notre bot pour inclure des capacités de planification. Nous commencerons par une commande simple, /schedule, qui prendra un message et un temps (par exemple, « dans 5 minutes »).


from telegram import Update
from telegram.ext import Application, CommandHandler, ContextTypes
from apscheduler.schedulers.blocking import BlockingScheduler
from datetime import datetime, timedelta
import asyncio

# Remplacez par le token réel de votre bot
BOT_TOKEN = "YOUR_TELEGRAM_BOT_TOKEN"

# Initialiser le planificateur
scheduler = BlockingScheduler()

async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
 """Envoie un message de bienvenue."""
 await update.message.reply_text("Bonjour ! Je suis votre bot de planification. Utilisez /help pour voir ce que je peux faire.")

async def help_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
 """Envoie un message d'aide."""
 await update.message.reply_text(
 "Je peux planifier des messages pour vous. Essayez /schedule <minutes> <votre message>.\n"
 "Exemple : /schedule 5 N'oubliez pas d'acheter des courses!"
 )

async def send_scheduled_message(chat_id: int, message_text: str, application: Application) -> None:
 """Envoie le message planifié réel."""
 # Nous devons obtenir l'instance du bot pour envoyer des messages en dehors d'un contexte Update
 await application.bot.send_message(chat_id=chat_id, text=message_text)
 print(f"Envoyé message planifié à {chat_id} : {message_text}")

async def schedule_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
 """Planifie un message."""
 if not context.args or len(context.args) < 2:
 await update.message.reply_text(
 "Utilisation : /schedule <minutes> <votre message>.\n"
 "Exemple : /schedule 5 N'oubliez pas d'acheter des courses!"
 )
 return

 try:
 minutes = int(context.args[0])
 if minutes <= 0:
 await update.message.reply_text("Les minutes doivent être un nombre positif.")
 return
 
 message_to_schedule = " ".join(context.args[1:])
 
 # Calculer l'heure future
 run_time = datetime.now() + timedelta(minutes=minutes)
 
 # Ajouter le travail au planificateur
 # Nous devons passer l'instance de l'application pour que send_scheduled_message puisse y accéder
 scheduler.add_job(
 send_scheduled_message, 
 'date', 
 run_date=run_time, 
 args=[update.effective_chat.id, message_to_schedule, context.application]
 )
 
 await update.message.reply_text(
 f"D'accord, je vous rappellerai dans {minutes} minute(s) à {run_time.strftime('%H:%M:%S')}!"
 )
 print(f"Travail planifié pour {update.effective_chat.id} à {run_time} avec message : {message_to_schedule}")

 except ValueError:
 await update.message.reply_text("Veuillez fournir un nombre valide pour les minutes.")
 except Exception as e:
 await update.message.reply_text(f"Quelque chose a mal tourné : {e}")

def main() -> None:
 """Démarre le bot et le planificateur."""
 application = Application.builder().token(BOT_TOKEN).build()

 application.add_handler(CommandHandler("start", start))
 application.add_handler(CommandHandler("help", help_command))
 application.add_handler(CommandHandler("schedule", schedule_command))

 # Démarrer le planificateur dans un fil ou un processus séparé si vous avez besoin d'un comportement non bloquant
 # Pour plus de simplicité, nous allons l'exécuter dans le fil principal avec run_polling.
 # Le BlockingScheduler d'APScheduler bloque, donc nous devons l'exécuter de manière concurrente.
 # Un schéma courant est d'exécuter le planificateur dans un fil séparé.
 
 # Démarrons le planificateur de manière non bloquante pour un usage en production
 # en utilisant BackgroundScheduler ou en plaçant BlockingScheduler dans un fil séparé.
 # Pour cet exemple, nous allons légèrement ajuster la manière dont main s'exécute.
 
 # Le BlockingScheduler d'APScheduler bloquera le fil principal.
 # Pour le faire fonctionner avec application.run_polling() de python-telegram-bot,
 # nous devons nous assurer que le planificateur s'exécute sans bloquer les mises à jour du bot.
 # Une manière simple de faire cela est d'utiliser un BackgroundScheduler.

 from apscheduler.schedulers.background import BackgroundScheduler
 global scheduler # Réinitialiser le planificateur pour BackgroundScheduler
 scheduler = BackgroundScheduler()
 scheduler.start()

 print("Bot démarré et à l'écoute...")
 application.run_polling(allowed_updates=Update.ALL_TYPES)
 
 # Arrêter le planificateur lorsque le bot s'arrête
 scheduler.shutdown()

if __name__ == "__main__":
 main()

Une petite note sur BlockingScheduler vs. BackgroundScheduler : Dans mes premiers tests pour cet article, j’ai rapidement réalisé que BlockingScheduler (comme son nom l’indique) bloque le fil principal. Cela signifie que votre bot ne pourrait pas recevoir de nouvelles mises à jour de Telegram pendant que le planificateur est en cours d’exécution. Pas idéal ! La solution consiste à utiliser BackgroundScheduler, qui s’exécute dans son propre fil, permettant à votre bot de rester réactif. J’ai mis à jour la fonction main() dans le code ci-dessus pour refléter cela.

Maintenant, si vous exécutez ce script mis à jour, vous pouvez envoyer à votre bot quelque chose comme /schedule 1 Test reminder! et après une minute, votre bot devrait vous envoyer « Test reminder! ». C’est cool, non ?

Rendre cela plus flexible : Tâches récurrentes

Les rappels ponctuels sont bons, mais qu’en est-il des événements récurrents ? APScheduler facilite énormément cela avec ses déclencheurs interval et cron. Ajoutons une commande pour programmer un message toutes les X minutes.


# ... (importations et initialisations précédentes) ...

async def schedule_recurring_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
 """Planifie un message récurrent."""
 if not context.args or len(context.args) < 2:
 await update.message.reply_text(
 "Utilisation : /schedule_every <minutes> <votre message>.\n"
 "Exemple : /schedule_every 60 Rappel horaire !"
 )
 return

 try:
 minutes_interval = int(context.args[0])
 if minutes_interval <= 0:
 await update.message.reply_text("Les minutes doivent être un nombre positif.")
 return
 
 message_to_schedule = " ".join(context.args[1:])
 chat_id = update.effective_chat.id
 
 # Ajouter la tâche récurrente à l'ordonnanceur
 job_id = f"recurring_job_{chat_id}_{datetime.now().timestamp()}" # ID unique pour une éventuelle suppression
 scheduler.add_job(
 send_scheduled_message, 
 'interval', 
 minutes=minutes_interval, 
 args=[chat_id, message_to_schedule, context.application],
 id=job_id,
 replace_existing=True # Optionnel : remplacer si l'ID existe
 )
 
 await update.message.reply_text(
 f"D'accord, je te rappellerai toutes les {minutes_interval} minute(s) avec : '{message_to_schedule}'"
 )
 print(f"Tâche récurrente planifiée '{job_id}' pour {chat_id} toutes les {minutes_interval} minutes.")

 except ValueError:
 await update.message.reply_text("Veuillez fournir un nombre valide pour les minutes.")
 except Exception as e:
 await update.message.reply_text(f"Quelque chose a mal tourné : {e}")

# ... (ajoutez ce handler dans la fonction main()) ...
# application.add_handler(CommandHandler("schedule_every", schedule_recurring_command))

N’oubliez pas d’ajouter le nouveau gestionnaire de commandes dans votre fonction main() :


def main() -> None:
 # ... gestionnaires existants ...
 application.add_handler(CommandHandler("schedule_every", schedule_recurring_command))
 # ... reste de main() ...

Vous pouvez maintenant dire à votre bot /schedule_every 15 N'oubliez pas de vous étirer ! et il vous rappellera fidèlement toutes les 15 minutes. C’est là que le rappel de la séance de D&D a vraiment cliqué pour moi. Je pouvais le définir une fois, et cela fonctionnerait simplement chaque semaine.

Gestion de l’état et persistance (une étape nécessaire)

En ce moment, si vous redémarrez votre bot, toutes les tâches programmées sont perdues. Ce n’est pas idéal pour un ordonnanceur fiable. Pour un bot dans le monde réel, vous voudriez stocker ces tâches programmées dans une base de données (comme SQLite, PostgreSQL, ou même un simple fichier JSON) et les recharger lorsque le bot démarre. APScheduler prend en charge les magasins de tâches, ce qui rend cela relativement simple.

Pour un bot de production, je recommanderais fortement d’ajouter un magasin de tâches. Voici un aperçu conceptuel de la façon de l’intégrer avec SQLite :


from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore

# ... (le reste de vos importations et code) ...

# Dans votre fonction main() :
def main() -> None:
 # ... configuration d'application existante ...

 jobstores = {
 'default': SQLAlchemyJobStore(url='sqlite:///jobs.sqlite')
 }
 
 # Réinitialiser l'ordonnanceur avec les magasins de tâches
 global scheduler
 scheduler = BackgroundScheduler(jobstores=jobstores)
 scheduler.start()

 # ... reste de main() ...

Lorsque vous utilisez un magasin de tâches, APScheduler gère la série et la désérialisation des tâches. Cela signifie que même si votre bot plante ou redémarre, il reprendra toutes ses anciennes tâches là où il s’était arrêté. C’est crucial pour toute application sérieuse.

Ce qu’il faut retenir pour votre propre bot

Construire un bot capable de programmer des messages ouvre un tout nouveau monde de possibilités. Voici ce que j’ai appris et ce que vous devriez considérer :

  1. Commencer simplement : N’essayez pas de construire l’ordonnanceur le plus complexe tout de suite. Faites fonctionner d’abord un rappel ponctuel basique, puis ajoutez des tâches récurrentes.
  2. La gestion des erreurs est essentielle : Les utilisateurs entreront inévitablement de mauvaises commandes ou des heures invalides. Votre bot doit être suffisamment solide pour gérer cela avec aisance. Ajoutez des blocs try-except !
  3. La persistance est non-négociable : Pour tout bot que vous attendez de faire fonctionner pendant plus de quelques minutes, vous devez absolument stocker les tâches programmées. Les magasins de tâches d’APScheduler rendent cela facile. SQLite est un excellent point de départ pour le stockage local.
  4. Retour de l’utilisateur : Confirmez toujours avec l’utilisateur que son emploi du temps a été défini. « D’accord, je te rappellerai dans 5 minutes ! » a beaucoup d’impact.
  5. Instructions claires : Fournissez de bons messages /help avec des exemples. Cela aide les utilisateurs à comprendre comment interagir avec votre bot.
  6. Considérer les fuseaux horaires : Pour un bot mondial, les fuseaux horaires peuvent être un cauchemar. APScheduler peut les gérer, mais cela ajoute de la complexité. Pour un bot personnel, vous pourriez vous en sortir en utilisant simplement l’UTC ou l’heure locale du serveur.

Ce parcours d’un simple rappel de D&D à un bot d’ordonnancement plus capable a été incroyablement gratifiant. Cela montre qu’avec quelques bonnes bibliothèques et un peu de Python, vous pouvez élever vos bots Telegram de simples répondeurs à de véritables assistants proactifs. Essayez, expérimentez et faites-moi savoir quelles idées de programmation intéressantes vous avez !

Bonne construction de bot !

🕒 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