Tutoriels

Piloter des appareils depuis un bot Telegram via MQTT

Créez un bot Telegram en Python qui publie des commandes MQTT vers vos appareils, affiche leur état et relaie les alertes capteurs dans le chat, avec allowlist et tests.

Mis à jour · 9 min de lecture

Piloter des appareils depuis un bot Telegram via MQTT

Un bot Telegram est l'un des moyens les plus rapides d'obtenir une télécommande et un canal d'alertes pour des appareils MQTT : interface de chat gratuite et multiplateforme, notifications push, et aucune application à développer. Le bot tourne comme un petit service qui fait deux choses : il publie des commandes comme ON sur devices/lamp/set quand vous tapez /on lamp, et il s'abonne aux topics d'alerte et d'état pour les relayer dans votre chat.

Ce tutoriel construit cette passerelle en Python avec python-telegram-bot et aiomqtt, la restreint à votre propre chat ID et teste chaque chemin avec mosquitto_pub et mosquitto_sub avant de brancher le moindre matériel.

Architecture

Flux des messages
You (Telegram app) ──/on lamp──▶ Telegram API ──▶ bot.py ──PUBLISH testmqtt/tgbot/lamp/set "ON"──▶ broker ──▶ device
device ──PUBLISH testmqtt/tgbot/lamp/state "ON" (retained)──▶ broker ──▶ bot.py (cache for /status)
device ──PUBLISH testmqtt/tgbot/greenhouse/alert "..."──▶ broker ──▶ bot.py ──▶ Telegram chat

L'appareil ne parle jamais à Telegram. Il ne parle que MQTT : un ESP32 ou un Raspberry Pi n'a donc besoin ni du token du bot ni d'un client HTTPS, et vous pourrez ajouter plus tard un dashboard ou Home Assistant comme second contrôleur sur les mêmes topics. L'arborescence suit la séparation habituelle commande/état décrite dans commande et contrôle avec MQTT :

TopicSensPayloadRetenu
testmqtt/tgbot/<device>/setbot → appareilON / OFFnon
testmqtt/tgbot/<device>/stateappareil → botON / OFFoui
testmqtt/tgbot/<device>/alertappareil → bottexte librenon

Créer le bot

  1. Dans Telegram, ouvrez une conversation avec @BotFather, envoyez /newbot, choisissez un nom et un username se terminant par bot.
  2. Copiez le token renvoyé par BotFather. C'est un secret : quiconque le possède peut se faire passer pour votre bot.
  3. Envoyez éventuellement /setcommands à BotFather avec on - switch a device on, off - switch a device off, status - show device states, pour que les commandes apparaissent dans le menu du chat.

Installez les deux bibliothèques (Python 3.10+) :

Installer les dépendances
pip install "python-telegram-bot>=21" "aiomqtt>=2"

Ce sont deux bibliothèques asyncio, d'où leur bonne entente : la boucle de polling du bot et la connexion MQTT tournent dans le même event loop, et un handler de commande peut directement faire await client.publish(...). Voir MQTT asynchrone en Python avec aiomqtt pour en savoir plus sur le client.

Le bot

@@BOTCODE@@

Quelques choix de conception à noter :

  • Une seule connexion MQTT pour tout le bot. Le worker possède la connexion et la stocke dans bot_data ; les handlers la réutilisent au lieu de se connecter à chaque commande. Si le broker tombe, la boucle se reconnecte après cinq secondes et, en attendant, les handlers répondent "Broker not connected".
  • Les états viennent des messages retenus. Comme les appareils publient state avec le flag retain, le bot connaît le dernier état de chaque appareil dès qu'il s'abonne, même après un redémarrage. Voir messages retenus.
  • Les chats inconnus n'obtiennent aucune réponse. Seul /whoami répond à tout le monde, pour que vous puissiez trouver votre chat ID. Chaque commande qui publie vérifie d'abord l'allowlist.
  • Les alertes passent par un debounce. Sinon, un capteur instable atteindrait les limites de Telegram et noierait les vraies alertes.

Lancer et tester sans matériel

Démarrez le bot avec seulement TELEGRAM_TOKEN, envoyez /whoami dans le chat et notez le numéro. Relancez avec l'allowlist :

Démarrer le bot
export TELEGRAM_TOKEN="123456:ABC..."        # fourni par BotFather
export ALLOWED_CHAT_IDS="111111111"          # votre chat ID obtenu via /whoami
export MQTT_USER="username" MQTT_PASS="password"   # si votre broker exige une authentification
python bot.py

Jouez maintenant le rôle de l'appareil. Dans un terminal, observez ce que publie le bot :

Terminal 1 — faux appareil : écouter les commandes
mosquitto_sub -h broker.connectmq.com -p 1883 -t 'testmqtt/tgbot/+/set' -v

Envoyez /on lamp dans Telegram. Le terminal 1 affiche testmqtt/tgbot/lamp/set ON. Publiez le nouvel état comme le ferait un appareil, puis déclenchez une alerte :

Terminal 2 — faux appareil : état et alertes
mosquitto_pub -h broker.connectmq.com -p 1883 -q 1 -r \
  -t testmqtt/tgbot/lamp/state -m ON

mosquitto_pub -h broker.connectmq.com -p 1883 -q 1 \
  -t testmqtt/tgbot/pump/alert -m 'Water level low (12 %)'

/status doit maintenant afficher lamp: ON, et le chat reçoit ⚠️ pump: Water level low (12 %). Republiez l'alerte en moins de 60 secondes et vérifiez qu'elle est ignorée. Vous pouvez aussi tout faire depuis le client MQTT en ligne au lieu du terminal. Enfin, effacez l'état retenu pour qu'il ne traîne pas : mosquitto_pub -h broker.connectmq.com -t testmqtt/tgbot/lamp/state -r -n.

Observer les topics du bot dans le navigateur

Côté appareil

Sur du vrai matériel, l'appareil s'abonne à son topic set, commute la sortie et publie l'état obtenu avec retain. En MicroPython avec umqtt.simple, l'essentiel tient en quelques lignes :

@@DEVCODE@@

Publier l'état après avoir agi, c'est ce qui rend /status fiable : le bot rapporte ce que l'appareil a fait, pas ce que vous avez demandé. Ajoutez un Last Will sur l'état ou un topic availability pour que le bot vous prévienne quand un appareil passe hors ligne.

Sécuriser le bot

N'importe qui sur Telegram peut atteindre un bot ; traitez-le comme une API publique :

  1. Allowlist des chats, comme montré. Pour un groupe, le chat ID est négatif ; ajoutez-le à la liste comme les autres.
  2. Gardez le token hors du code — variables d'environnement ou gestionnaire de secrets, jamais un dépôt Git.
  3. Utilisez TLS vers le broker. L'exemple se connecte sur le port 8883 ; le 1883 en clair ne convient qu'aux essais locaux.
  4. Restreignez l'utilisateur broker du bot. Il a besoin d'écrire sur .../set et de lire .../state et .../alert, rien d'autre. Vérifiez les règles avec un test des permissions ACL.

Alternatives sans code

Si vous préférez un outil visuel, la même passerelle fonctionne dans n8n (MQTT Trigger → nœud Telegram, et Telegram Trigger → nœud MQTT — voir automatisations MQTT avec n8n) ou dans Node-RED avec un nœud Telegram communautaire. La version Python l'emporte quand vous voulez un seul petit service avec allowlist explicite, debounce et tests dans votre propre dépôt.

OptionIdéal pourContrepartie
Bot Python (ce guide)Contrôle total, testable, empreinte minimaleVous maintenez le code
Workflow n8nMise en place rapide, nombreuses autres intégrationsUne exécution par message
Flux Node-REDNode-RED tourne déjà chez vousLa logique vit dans un éditeur de flux

Un bot Telegram fait de MQTT quelque chose que vous pilotez depuis votre poche : les commandes partent en publish, l'état revient en messages retenus et les alertes arrivent en notifications push. Faites parler l'appareil uniquement en MQTT, limitez le bot à votre chat, appliquez un debounce aux alertes et testez toute la boucle avec mosquitto avant de câbler un relais.

Questions fréquentes

L'appareil doit-il parler directement à Telegram ou passer par MQTT ?

Passer par MQTT. Les appareils n'ont alors besoin que d'une connexion légère au broker, le token du bot reste sur un serveur et non sur chaque appareil, et vous pouvez ajouter d'autres contrôleurs (dashboards, Home Assistant, n8n) sans toucher au firmware.

Comment empêcher des inconnus de piloter mes appareils via le bot ?

Les bots Telegram sont publics : quiconque trouve le username peut envoyer des commandes. Comparez update.effective_chat.id à une allowlist avant de publier quoi que ce soit, et donnez à l'utilisateur broker du bot une ACL limitée aux topics de commande nécessaires.

Pourquoi le bot cesse-t-il d'envoyer des alertes quand beaucoup de capteurs se déclenchent ?

Telegram limite la vitesse d'envoi d'un bot, environ un message par seconde et par chat, moins dans les groupes. Appliquez un debounce par appareil, regroupez les rafales en un seul message et ne relayez jamais de télémétrie brute à haute fréquence dans le chat.