Aller au contenu principal

WhatsApp pour les enquêtes de satisfaction via l'API : tutoriel pour les éditeurs

Tutoriel enquête satisfaction WhatsApp API : créer un template NPS, configurer le webhook de réponse, collecter les verbatims et agréger les scores en temps réel.

Implémenter une enquête de satisfaction NPS ou CSAT via l'API WhatsApp Business demande de maîtriser quatre composants : le template de question avec boutons de note, l'envoi déclenché par un événement, la réception de la réponse via webhook, et la relance pour le verbatim. Ce tutoriel couvre chaque étape avec des exemples de code concrets.


Prérequis avant de commencer

Avant d'écrire la première ligne de code, assurez-vous d'avoir :

  • Un accès API Whakup actif (Meta Tech Provider certifié, pas de démarche Meta directe nécessaire)
  • Un API_KEY et un phone_number_id pour le numéro expéditeur
  • Un endpoint HTTPS exposé publiquement pour recevoir les webhooks
  • Un template WhatsApp approuvé par Meta (procédure dans l'étape 2)
  • Une base de données pour stocker les réponses et les message_id

Pour les fondamentaux de l'architecture, consultez le guide complet de l'API WhatsApp Business.


Étape 1 : Concevoir la séquence d'enquête

Une enquête WhatsApp efficace se déroule en deux temps :

Temps 1 — Template de note (envoi proactif, nécessite un template approuvé) :

Bonjour Marie, comment évaluez-vous votre expérience avec notre service client ce matin ? Appuyez sur une note. [Très satisfaite] [Neutre] [Déçue]

Temps 2 — Relance verbatim (message session, dans les 24h suivant la réponse) :

Merci pour votre retour ! Pouvez-vous nous dire ce qui vous a le plus marquée ?

Cette séquence donne un score ET un verbatim sans rediriger vers un formulaire externe. Le taux de complétion est nettement supérieur à un lien URL.


Étape 2 : Créer et soumettre le template de note

Structure du template NPS simplifié (3 boutons)

{
  "name": "enquete_satisfaction_livraison",
  "language": "fr",
  "category": "UTILITY",
  "components": [
    {
      "type": "body",
      "text": "Bonjour {{1}}, votre commande {{2}} a été livrée. Comment s'est passée votre expérience de livraison ?\n\nAppuyez sur une note pour répondre en 2 secondes.",
      "example": {
        "body_text": [["Marie Dupont", "#CMD-45821"]]
      }
    },
    {
      "type": "buttons",
      "buttons": [
        {
          "type": "quick_reply",
          "text": "😊 Très bien"
        },
        {
          "type": "quick_reply",
          "text": "😐 Correct"
        },
        {
          "type": "quick_reply",
          "text": "😕 Décevant"
        }
      ]
    }
  ]
}

Soumettez ce template via le dashboard Whakup ou l'API de gestion de templates. Le délai de validation est généralement inférieur à 1 heure pour un template simple sans lien externe.

Template NPS numérique (avec lien formulaire pour granularité)

Si vous avez besoin d'une échelle 0-10 standard, un bouton URL vers un formulaire externe est plus adapté :

{
  "type": "buttons",
  "buttons": [
    {
      "type": "url",
      "text": "Donner ma note (0 à 10)",
      "url": "https://votreplateforme.com/nps/{{1}}",
      "example": ["token_membre_abc123"]
    }
  ]
}

Le {{1}} dans l'URL est remplacé à l'envoi par un token unique par répondant, ce qui permet le tracking sans authentification.


Étape 3 : Envoyer le template au bon moment

Déclenchement après un événement

import requests
from datetime import datetime

WHAKUP_API_KEY = "your_api_key"
PHONE_NUMBER_ID = "your_phone_number_id"

def envoyer_enquete_satisfaction(commande):
    """
    Appelé 1 heure après confirmation de livraison.
    """
    payload = {
        "to": commande["client_telephone"],
        "phone_number_id": PHONE_NUMBER_ID,
        "type": "template",
        "template": {
            "name": "enquete_satisfaction_livraison",
            "language": {"code": "fr"},
            "components": [
                {
                    "type": "body",
                    "parameters": [
                        {"type": "text", "text": commande["client_prenom"]},
                        {"type": "text", "text": commande["numero_commande"]}
                    ]
                }
            ]
        }
    }
    
    response = requests.post(
        "https://api.whakup.com/v1/messages",
        headers={"Authorization": f"Bearer {WHAKUP_API_KEY}"},
        json=payload,
        timeout=10
    )
    
    data = response.json()
    message_id = data.get("message_id")
    
    if message_id:
        # Stocker le message_id pour corréler la réponse
        save_enquete_envoi(
            commande_id=commande["id"],
            client_tel=commande["client_telephone"],
            message_id=message_id,
            envoyee_le=datetime.utcnow()
        )
    
    return message_id

Planification avec un scheduler

Si votre plateforme envoie les enquêtes 1h après livraison, utilisez votre système de tâches différées :

# Exemple avec Celery
from celery import Celery
app = Celery()

@app.task
def task_enquete_post_livraison(commande_id):
    commande = get_commande(commande_id)
    if commande and commande["client_optout_whatsapp"] is False:
        envoyer_enquete_satisfaction(commande)

# Déclenché depuis votre logique de confirmation livraison :
task_enquete_post_livraison.apply_async(
    args=[commande.id],
    countdown=3600  # 1 heure
)

Étape 4 : Recevoir et traiter les réponses via webhook

Endpoint webhook

from flask import Flask, request, jsonify
import json

app = Flask(__name__)

@app.route("/webhook/whatsapp", methods=["POST"])
def webhook_handler():
    data = request.json
    event_type = data.get("type")
    
    if event_type == "button":
        # Réponse à un bouton quick_reply
        traiter_reponse_note(data)
    
    elif event_type == "message":
        # Message texte libre (verbatim)
        traiter_verbatim(data)
    
    elif event_type == "message_status":
        # Mise à jour de statut (sent, delivered, read, failed)
        mettre_a_jour_statut(data)
    
    return jsonify({"status": "ok"})


def traiter_reponse_note(data):
    sender = data["from"]
    bouton_texte = data["button"]["text"]
    
    # Mapper le libellé du bouton vers un score
    scores = {
        "😊 Très bien": 5,
        "😐 Correct": 3,
        "😕 Décevant": 1
    }
    score = scores.get(bouton_texte)
    
    # Retrouver l'enquête liée à ce numéro (dernière non-répondue)
    enquete = get_enquete_en_cours(sender)
    
    if enquete and score is not None:
        save_note_enquete(enquete["id"], score, bouton_texte)
        # Envoyer la relance verbatim
        envoyer_relance_verbatim(sender, enquete)


def traiter_verbatim(data):
    sender = data["from"]
    verbatim = data["text"]["body"]
    
    enquete = get_enquete_en_cours_verbatim(sender)
    if enquete:
        save_verbatim_enquete(enquete["id"], verbatim)
        # Remercier le client
        envoyer_remerciement(sender)
        cloturer_enquete(enquete["id"])

Envoyer la relance verbatim (message session)

Après réception de la note, envoyez un message libre (pas besoin de template dans la fenêtre de 24h) :

def envoyer_relance_verbatim(telephone, enquete):
    payload = {
        "to": telephone,
        "phone_number_id": PHONE_NUMBER_ID,
        "type": "text",
        "text": {
            "body": "Merci pour votre retour ! Pouvez-vous nous dire ce qui vous a le plus marqué(e) ? (Quelques mots suffisent)"
        }
    }
    
    requests.post(
        "https://api.whakup.com/v1/messages",
        headers={"Authorization": f"Bearer {WHAKUP_API_KEY}"},
        json=payload
    )

Étape 5 : Stocker et agréger les scores

Schéma de base de données minimal

CREATE TABLE enquetes_satisfaction (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    commande_id UUID REFERENCES commandes(id),
    client_telephone VARCHAR(20) NOT NULL,
    message_id VARCHAR(100),  -- ID retourné par Whakup
    statut VARCHAR(20) DEFAULT 'envoyee',  -- envoyee, vue, note_recue, complete
    score SMALLINT,  -- 1, 3 ou 5 pour 3 boutons
    bouton_clique VARCHAR(50),
    verbatim TEXT,
    envoyee_le TIMESTAMP NOT NULL,
    repondue_le TIMESTAMP,
    INDEX idx_telephone (client_telephone),
    INDEX idx_message_id (message_id)
);

Calcul du CSAT en temps réel

def calculer_csat(periode_debut, periode_fin):
    """
    CSAT = % de répondants avec score >= 4 (sur 5).
    Avec 3 boutons (scores 1/3/5), CSAT = % de "Très bien".
    """
    total = count_enquetes_completes(periode_debut, periode_fin)
    positifs = count_enquetes_score_5(periode_debut, periode_fin)
    
    if total == 0:
        return None
    
    return round((positifs / total) * 100, 1)

FAQ

Comment gérer le cas où le répondant envoie un message hors contexte ?

Si le client envoie un texte libre qui n'est pas un verbatim attendu (par exemple, une question sur sa commande), votre webhook le reçoit comme un message ordinaire. Décidez si votre plateforme a un chatbot de fallback ou si vous renvoyez vers votre support. Dans tous les cas, répondez dans la fenêtre de 24h pour rester dans la session gratuite.

Peut-on envoyer plusieurs enquêtes différentes depuis le même numéro ?

Oui. Un seul numéro peut avoir plusieurs templates actifs. Assurez-vous que la logique de corrélation (quel template correspond à quelle enquête en cours pour ce numéro) est solide côté base de données.

Les boutons quick_reply sont-ils limités en nombre de caractères ?

Oui. Chaque bouton quick_reply est limité à 20 caractères. Tenez-en compte dans la rédaction de vos libellés. Avec les emojis, comptez bien les caractères Unicode.

Comment éviter d'envoyer deux enquêtes au même client dans un court délai ?

Ajoutez une vérification avant l'envoi : si le client a déjà une enquête ouverte (statut envoyee ou vue) depuis moins de 7 jours, ne renvoyez pas. Définissez cette règle de déduplication côté base de données.


Conclusion

Ce tutoriel couvre l'implémentation complète d'une enquête de satisfaction WhatsApp : template avec boutons de note, envoi déclenché par événement, webhook de réponse, relance verbatim et stockage des scores. L'architecture est reproductible pour chaque nouveau client via l'embedded signup Whakup.

Pour choisir le bon niveau d'accès API selon votre volume, consultez la page API WhatsApp de Whakup. Pour une vue sur les tarifs, l'article sur les prix de l'API WhatsApp Business en 2026 détaille les coûts par catégorie et par pays. Pour comprendre l'offre Whakup en tant que Meta Tech Provider, lisez la page Meta Tech Provider WhatsApp.

#intégration whatsapp#enquête satisfaction whatsapp#tutoriel
Stéphane Haouzi
Stéphane HaouziHead of Growth

Head of Growth chez Whakup, Stéphane pilote la stratégie d'acquisition et les partenariats en Afrique francophone. Expert en marketing digital et expansion marché.

🚀

Prêt à passer à l'action ?

Essayez Whakup gratuitement pendant 15 jours. Aucune carte bancaire requise.

Démarrer l'essai gratuit