Vivant loin de nos familles respective ma femme et moi, j’ai voulu mettre en place un petit dispositif automatique pour m’assurer que tout va bien chaque jour afin que quelqu’un puisse venir s’occuper de notre fille de 8 mois 🐥 si, à tout hasard, il nous arrivait quelque chose… (brrrr)
L’idée : recevoir un message quotidien pour vérifier que je ne suis pas dans une situation d’incapacité, et qui puisse alerter rapidement quelqu’un si je ne réponds pas.
A toutes fins utiles voici un condensé de ce que j’ai mis en place... 🤓

Le plan :
On veut donc concevoir un petit bot WhatsApp capable de m’envoyer chaque jour un message automatique pour vérifier que tout va bien et d’alerter mes proches si je ne réponds pas dans les deux heures.
Les contraintes : un système simple, fiable, auto-hébergé sur mon serveur Unraid et avec un minimum de dépendance externe.
Choisir la bonne API : Cloud, pas On-Premises
Comme indiqué dans le titre, on va donc utiliser WhatsApp Cloud API de Meta. Au départ, j’étais tombé sur la documentation historique de l’API On-Premises, qui mentionne l’enregistrement d’un numéro via /v1/account. Cependant cette API est désormais obsolète pour tous les projets Cloud ; elle renvoie systématiquement :
{
"code": 1005,
"title": "Access denied",
"details": "biz_link_on_prem_reg_blocked"
}
➡️ Pour tout projet personnel ou hébergé sur Unraid, il faut utiliser la WhatsApp Cloud API, hébergée directement par Meta, accessible via https://graph.facebook.com/v24.0/.
Création de l’application WhatsApp Cloud API
Depuis https://developers.facebook.com/apps :
- Créez une nouvelle app “Business”
- Ajoutez le produit WhatsApp
- Vous obtiendrez un numéro de test (sandbox) et un token temporaire
Premier test :
curl -i -X POST \
"https://graph.facebook.com/v24.0/<PHONE_NUMBER_ID>/messages" \
-H "Authorization: Bearer <ACCESS_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"messaging_product": "whatsapp",
"to": "336XXXXXXXX",
"type": "text",
"text": {"body": "Hello from your Cloud API bot!"}
}'
Si tout est bien configuré, vous recevrez un message WhatsApp et un wamid en réponse.
Le piège du numéro “non enregistré”
Une fois le numéro de test fonctionnel, j’ai voulu utiliser un numéro perso que j’ai pris chez Free avec le forfait à 0€.
Premier curl → erreur 400 :
{"error":{"message":"(#133010) Account not registered"}}
C’est le signe que le numéro n’est pas encore validé dans le WhatsApp Manager.
La vérification ne se fait plus par API mais directement dans l’interface Meta :
- https://business.facebook.com/wa/manage
- → Gérer les numéros de téléphone
- → Ajouter un numéro
- Choisissez SMS ou Appel vocal
- Entrez le code à 6 chiffres reçu
⚠️ Si vous voyez : “En attente – Une fois le nom affiché approuvé…”, c’est que Meta doit d’abord valider le nom d’affichage.
Dans mon cas, j’avais mis Mathieu le Chat (le nom de mon chat 🐱)… Meta a demandé une validation manuelle !
J’ai fini par opter pour Mathieu le Chat (Safety Bot) et tout est passé en moins d’une heure.
Héberger le bot sur Unraid
Une fois le numéro activé, j’ai monté un petit conteneur Python avec Flask et APScheduler pour envoyer un message quotidien.
Voici un extrait du fichier docker-compose.yml :
services:
whatsapp-wellbeing-bot:
image: python:3.12-slim
container_name: whatsapp-wellbeing-bot
working_dir: /app
volumes:
- /mnt/user/appdata/whatsapp-wellbeing-bot:/app
environment:
WHATSAPP_TOKEN: "EAALZAgm..."
WHATSAPP_PHONE_ID: "92278..."
OWNER_PHONE: "336XXXXXXXX"
DAILY_HOUR: "9"
RESPONSE_TIMEOUT_MIN: "120"
command: >
sh -c "pip install --no-cache-dir flask requests apscheduler tzdata && python app.py"
restart: unless-stopped
Et côté Flask (app.py) :
from flask import Flask, request, jsonify
import requests, os
app = Flask(__name__)
@app.route("/whatsapp/webhook", methods=["POST"])
def webhook():
data = request.get_json()
for entry in data.get("entry", []):
for change in entry.get("changes", []):
msg = change.get("value", {}).get("messages", [{}])[0]
sender = msg.get("from")
text = msg.get("text", {}).get("body", "").lower()
if text in ["ok", "ça va", "👍"]:
send_message(sender, "✅ Merci, j’ai noté que tout va bien.")
return "OK"
def send_message(to, text):
url = f"https://graph.facebook.com/v24.0/{os.getenv('WHATSAPP_PHONE_ID')}/messages"
headers = {"Authorization": f"Bearer {os.getenv('WHATSAPP_TOKEN')}", "Content-Type": "application/json"}
payload = {"messaging_product": "whatsapp", "to": to, "type": "text", "text": {"body": text}}
requests.post(url, headers=headers, json=payload)
Le tout est exposé derrière Nginx Proxy Manager avec certificat SSL et domaine bot.paulsi.mn.
Validation du webhook
Côté Meta, il faut aussi valider le Webhook WhatsApp dans l’app développeur :
- URL : https://bot.paulsi.mn/whatsapp/webhook
- Token de vérification : celui défini dans les variables d’environnement
- Champs cochés :
messages,message_template_status_update
Un simple 403 forbidden sur l’URL confirme que Flask répond bien.
Résultat
Chaque matin à 9h, le bot m’envoie :
Mathieu le Chat (Safety Bot) : 👋 Check quotidien : réponds dans les 2h par « ok » ou « ça va ».
Si je ne réponds pas dans les deux heures, il prévient automatiquement mes contacts avec :
Mathieu le Chat (Safety Bot) : ⚠️ Pas de réponse de
{OWNER_PHONE}depuis le check quotidien. Merci de vérifier.
Tout tourne sur mon serveur Unraid, sans service tiers, et sans dépendance extérieure.
Conclusion
Le WhatsApp Cloud API est aujourd’hui bien plus simple que l’ancienne version on-premises, mais il reste truffé de petits pièges d’intégration.
Avec un peu de patience et une bonne lecture des logs Docker, on peut déployer un bot personnel stable, automatisé et sécurisé, parfait pour un usage quotidien, de la veille santé, ou du monitoring humain.
Un projet modeste mais utile : un chat, un bot et un peu de code pour protéger ce qui compte le plus 🐾