\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,516 wordsUpdated Mar 26, 2026

Salut tout le monde, Marcus ici de ai7bot.com. Aujourd’hui, je veux parler de quelque chose qui fait le buzz dans mes projets de développement personnel ces derniers temps : les bots Telegram. Plus précisément, je veux explorer comment faire de votre bot Telegram non seulement un répondeur, mais un planificateur. Oubliez les simples trucs de « hello world » ; nous allons construire un bot qui se souvient des choses pour vous et envoie des messages à des moments spécifiques. Pensez-y comme à votre assistant numérique personnel et silencieux, vivant juste 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 avions du mal à nous souvenir de qui était l’hôte, à quelle heure nous étions d’accord et quels snacks tout le monde apportait. Nous avons essayé des notes partagées, des calendriers, tout. Mais le dénominateur commun était toujours Telegram. C’est là que ça m’est venu : pourquoi ne pas créer un bot qui nous rappelle simplement ? Pas juste un rappel ponctuel, 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 passez la configuration initiale.

Au-delà des Réponses Simples : Le Pouvoir des Messages Programmé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 n’exploite pas vraiment le potentiel complet d’un bot. La vraie magie se produit lorsque votre bot peut être proactif – quand il peut initier des conversations, envoyer des mises à jour ou vous rappeler quelque chose sans que vous ayez besoin de l’interpeller d’abord. C’est ici que les messages programmés entrent en jeu.

Imaginez un bot qui :

  • Rappelle à votre équipe les stand-ups quotidiens cinq minutes avant qu’ils ne commencent.
  • Vous envoie un bulletin météo personnalisé chaque matin à 7 heures.
  • Vous notifie des délais importants pour un projet.
  • Ping votre groupe de D&D chaque dimanche à 15 heures avec un message « session commençant bientôt ! ».

Les possibilités sont infinies. Et le meilleur dans tout ça ? Ce n’est pas aussi compliqué que vous pourriez le penser. Nous utiliserons 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, récapitulons nos outils :

  1. Python 3 : Si vous ne l’avez pas, allez le chercher. C’est la colonne vertébrale de notre bot.
  2. python-telegram-bot bibliothèque : C’est notre interface principale avec l’API Bot de Telegram. Elle gère toute la communication complexe.
  3. APScheduler bibliothèque : C’est la star du spectacle pour la planification. Elle nous permet d’exécuter des fonctions à des moments ou des 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, rendez-vous sur BotFather sur Telegram, envoyez-lui /newbot, et suivez les instructions. Il vous donnera un token – gardez-le en sécurité !

Configurer la Structure de Base du Bot

Tout d’abord, faisons fonctionner notre bot Telegram de base. Cette partie devrait être familière si vous avez déjà fait du développement de bots auparavant.


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

# Remplacez par votre token de bot réel de BotFather
BOT_TOKEN = "VOTRE_TOKEN_DE_BOT_TELEGRAM"

async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
 """Envoie un message de salutation 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 programmer 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 obtenir une réponse. C’est notre fondation. Maintenant, ajoutons le planificateur.

Présentation d’APScheduler : Votre Garde-Temps

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

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

Programmation de Notre Premier Message

Modifions notre bot pour inclure des capacités de programmation. 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 votre token de bot réel
BOT_TOKEN = "VOTRE_TOKEN_DE_BOT_TELEGRAM"

# Initialiser le planificateur
scheduler = BlockingScheduler()

async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
 """Envoie un message de salutation."""
 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 programmer 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 programmé réel."""
 # Nous devons obtenir l'instance du bot pour envoyer des messages en dehors d'un contexte de mise à jour
 await application.bot.send_message(chat_id=chat_id, text=message_text)
 print(f"Message programmé envoyé à {chat_id} : {message_text}")

async def schedule_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
 """Programme 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 le temps futur
 run_time = datetime.now() + timedelta(minutes=minutes)
 
 # Ajouter le travail au planificateur
 # Nous devons transmettre 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 programmé 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émarrez le planificateur dans un thread ou un processus séparé si vous avez besoin d'un comportement non-bloquant
 # Pour des raisons de simplicité, nous allons l'exécuter dans le thread principal avec run_polling.
 # Le BlockingScheduler d'APScheduler bloque, donc nous devons le faire fonctionner de manière simultanée.
 # Un modèle commun consiste à exécuter le planificateur dans un thread séparé.
 
 # Démarrons le planificateur de manière non-bloquante pour une utilisation en production
 # en utilisant BackgroundScheduler ou en plaçant BlockingScheduler dans un thread séparé.
 # Pour cet exemple, nous allons légèrement ajuster la façon dont main s'exécute.
 
 # Le BlockingScheduler d'APScheduler bloquera le thread principal.
 # Pour le faire fonctionner avec application.run_polling() de python-telegram-bot,
 # nous devons nous assurer que le planificateur fonctionne sans bloquer les mises à jour du bot.
 # Une manière simple de le faire 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êtez le planificateur lorsque le bot s'arrête
 scheduler.shutdown()

if __name__ == "__main__":
 main()

Une petite note sur BlockingScheduler vs. BackgroundScheduler : Dans mes tests initiaux pour cet article, j’ai rapidement réalisé que BlockingScheduler (comme son nom l’indique) bloque le thread principal. Cela signifie que votre bot ne pourrait pas recevoir de nouvelles mises à jour de Telegram pendant que le planificateur fonctionne. Pas idéal ! La solution est d’utiliser BackgroundScheduler, qui s’exécute dans son propre thread, permettant à votre bot de rester réactif. J’ai mis à jour la fonction main() dans l’extrait 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 plutôt cool, non ?

Le rendre plus flexible : Travaux récurrents

Les rappels ponctuels sont bien, 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 planifier 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 Vérification 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
 
 # Ajoutez le travail récurrent au planificateur
 job_id = f"recurring_job_{chat_id}_{datetime.now().timestamp()}" # ID unique pour une possible 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 vous rappellerai tous les {minutes_interval} minute(s) avec : '{message_to_schedule}'"
 )
 print(f"Travail récurrent '{job_id}' planifié 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 gestionnaire dans la fonction main() ...) 
# application.add_handler(CommandHandler("schedule_every", schedule_recurring_command))

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


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

Maintenant, vous pouvez dire à votre bot /schedule_every 15 N'oubliez pas de vous étirer ! et il vous rappellera fidèlement toutes les 15 minutes. C’est à ce moment-là que le rappel de la session D&D a vraiment pris tout son sens pour moi. Je pouvais le programmer une fois et il fonctionnait chaque semaine.

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

En ce moment, si vous redémarrez votre bot, tous les travaux planifiés sont perdus. Ce n’est pas idéal pour un planificateur fiable. Pour un bot dans le monde réel, vous voudriez stocker ces travaux planifiés 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 a un support intégré pour les magasins de travaux, ce qui rend cela relativement simple.

Pour un bot de production, je recommanderais fortement d’ajouter un magasin de travaux. Voici un plan conceptuel de la façon dont vous l’intégreriez avec SQLite :


from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore

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

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

 jobstores = {
 'default': SQLAlchemyJobStore(url='sqlite:///jobs.sqlite')
 }
 
 # Réinitialisez le planificateur avec les magasins de travaux
 global scheduler
 scheduler = BackgroundScheduler(jobstores=jobstores)
 scheduler.start()

 # ... reste du main() ...

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

Conseils pratiques 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 prendre en compte :

  1. Commencez simple : N’essayez pas de construire le planificateur le plus complexe tout de suite. Faites d’abord fonctionner un rappel ponctuel basique, puis ajoutez des travaux récurrents.
  2. La gestion des erreurs est essentielle : Les utilisateurs entreront inévitablement des commandes incorrectes ou des temps invalides. Votre bot doit être suffisamment solide pour gérer cela avec grâce. Ajoutez des blocs try-except !
  3. La persistance est non négociable : Pour tout bot que vous prévoyez de faire fonctionner pendant plus de quelques minutes, vous devez absolument stocker les travaux planifiés. Les magasins de travaux de APScheduler facilitent cela. SQLite est un excellent point de départ pour le stockage local.
  4. Retour utilisateur : Confirmez toujours à l’utilisateur que sa programmation a été définie. “D’accord, je vous rappellerai dans 5 minutes !” compte beaucoup.
  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 tirer en utilisant simplement UTC ou l’heure locale du serveur.

Ce parcours, d’un simple rappel D&D à un bot de planification 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