Aller au contenu principal
Guides & Stratégie• 7 min de lecture

Conversation analytics WhatsApp : créer un tableau de bord de pilotage

Construire un tableau de bord analytics pour piloter votre chatbot WhatsApp. Métriques clés, visualisations, alertes automatiques et reporting pour décideurs africains.

Un chatbot WhatsApp sans tableau de bord analytics, c'est comme piloter sans instruments de bord. Vous avancez, mais vous ne savez pas si vous allez dans la bonne direction, ni ce qui ne fonctionne pas. Un bon tableau de bord vous permet de répondre en 5 minutes à la question : "Est-ce que notre bot performe bien cette semaine ?"

Ce guide vous explique comment construire un tableau de bord actionnable pour les décideurs et pour l'équipe technique.

Les deux niveaux de tableau de bord

Un bon système d'analytics WhatsApp a deux niveaux distincts :

Niveau 1 : Dashboard exécutif (pour la direction, actualisé hebdomadairement)

  • Taux de résolution global
  • CSAT moyen
  • Volume de conversations
  • Économies estimées vs agents humains

Niveau 2 : Dashboard opérationnel (pour l'équipe technique, en temps réel)

  • Taux de fallback actuel
  • Files d'attente en cours
  • Flows échouants
  • Temps de réponse

Structurer la collecte de données

Avant de construire des visualisations, il faut collecter les bons événements :

// Système d'événements analytics complet
const analyticsTracker = {
  
  // Événements de conversation
  trackConversationStart: async (phone, source) => {
    await analytics.track({
      event: 'conversation_started',
      properties: {
        phone_hash: hashPhone(phone),
        source, // 'organic', 'campaign', 'click_to_whatsapp', 'agent_referral'
        timestamp: new Date(),
        day_of_week: getDayOfWeek(),
        hour: new Date().getHours(),
        is_business_hours: isBusinessHours()
      }
    });
  },
  
  trackIntentDetected: async (phone, intent, confidence) => {
    await analytics.track({
      event: 'intent_detected',
      properties: {
        phone_hash: hashPhone(phone),
        intent,
        confidence,
        is_fallback: intent === 'fallback' || confidence < 0.6,
        timestamp: new Date()
      }
    });
  },
  
  trackFlowStep: async (phone, flowId, stepId, outcome) => {
    await analytics.track({
      event: 'flow_step',
      properties: {
        phone_hash: hashPhone(phone),
        flow_id: flowId,
        step_id: stepId,
        outcome, // 'completed', 'abandoned', 'error'
        timestamp: new Date()
      }
    });
  },
  
  trackConversationEnd: async (phone, outcome) => {
    await analytics.track({
      event: 'conversation_ended',
      properties: {
        phone_hash: hashPhone(phone),
        outcome, // 'resolved_bot', 'escalated_human', 'abandoned', 'timed_out'
        duration_seconds: outcome.duration_seconds,
        messages_count: outcome.messages_count,
        csat_score: outcome.csat_score || null,
        timestamp: new Date()
      }
    });
  }
};

Dashboard niveau 1 : métriques exécutives

// Génération des métriques exécutives hebdomadaires
async function generateExecutiveDashboard(startDate, endDate) {
  
  const [conversations, csatResponses, agentCost] = await Promise.all([
    db.getConversations({ startDate, endDate }),
    db.getCSATResponses({ startDate, endDate }),
    db.getAgentCostEstimate(startDate, endDate)
  ]);
  
  // 1. Taux de résolution
  const botResolved = conversations.filter(c => c.outcome === 'resolved_bot').length;
  const resolutionRate = botResolved / conversations.length;
  
  // 2. CSAT moyen
  const avgCSAT = csatResponses.length > 0
    ? csatResponses.reduce((sum, r) => sum + r.score, 0) / csatResponses.length
    : null;
  
  // 3. Volume et tendance
  const prevPeriodConversations = await db.getConversationCount({
    startDate: subtractDays(startDate, 7),
    endDate: subtractDays(endDate, 7)
  });
  const volumeTrend = ((conversations.length - prevPeriodConversations) / prevPeriodConversations * 100).toFixed(1);
  
  // 4. Économies générées
  const avgHandlingCostHuman = 800; // FCFA par conversation agent humain (à ajuster)
  const avgHandlingCostBot = 50; // FCFA par conversation bot
  const savingsThisWeek = botResolved * (avgHandlingCostHuman - avgHandlingCostBot);
  
  return {
    period: `${formatDate(startDate)} - ${formatDate(endDate)}`,
    summary: {
      total_conversations: conversations.length,
      volume_trend_pct: volumeTrend,
      resolution_rate_pct: (resolutionRate * 100).toFixed(1),
      csat_avg: avgCSAT ? avgCSAT.toFixed(1) : 'N/A',
      savings_fcfa: formatCurrency(savingsThisWeek),
      bot_resolved_count: botResolved
    },
    status: getHealthStatus(resolutionRate, avgCSAT)
  };
}

function getHealthStatus(resolutionRate, csat) {
  if (resolutionRate >= 0.70 && csat >= 4.0) return { label: 'Excellent', color: 'green' };
  if (resolutionRate >= 0.55 && csat >= 3.5) return { label: 'Bon', color: 'blue' };
  if (resolutionRate >= 0.40) return { label: 'À améliorer', color: 'orange' };
  return { label: 'Critique', color: 'red' };
}

Dashboard niveau 2 : métriques opérationnelles

// Métriques temps réel pour l'équipe technique
async function getOperationalMetrics() {
  const last1h = await getMetricsPeriod('1h');
  const last24h = await getMetricsPeriod('24h');
  
  return {
    // Santé instantanée
    health: {
      fallback_rate_1h: last1h.fallbackRate,
      avg_response_time_ms: last1h.avgResponseTimeMs,
      error_rate_1h: last1h.errorRate,
      active_conversations: await db.getActiveConversationCount()
    },
    
    // Files d'attente agents
    queues: await db.getAgentQueues(),
    
    // Flows qui échouent
    failing_flows: await db.getFlowsWithHighAbandon({
      period: '24h',
      min_abandon_rate: 0.30,
      min_volume: 10 // Ignorer les flows peu utilisés
    }),
    
    // Top intents du jour
    top_intents: await db.getTopIntents({ period: '24h', limit: 10 }),
    
    // Intents non reconnus (fallback clusters)
    unrecognized_patterns: await db.getTopFallbackMessages({ period: '24h', limit: 5 })
  };
}

Alertes automatiques

// Système d'alertes pour dégradations
const dashboardAlerts = {
  
  rules: [
    {
      name: 'fallback_rate_high',
      check: (metrics) => metrics.health.fallback_rate_1h > 0.30,
      severity: 'warning',
      message: (metrics) => `Taux de fallback élevé : ${(metrics.health.fallback_rate_1h * 100).toFixed(0)}% (seuil : 30%)`,
      channels: ['slack', 'email']
    },
    {
      name: 'response_time_critical',
      check: (metrics) => metrics.health.avg_response_time_ms > 5000,
      severity: 'critical',
      message: (metrics) => `Temps de réponse critique : ${metrics.health.avg_response_time_ms}ms (seuil : 5s)`,
      channels: ['slack', 'sms', 'email']
    },
    {
      name: 'queue_overload',
      check: (metrics) => metrics.queues.some(q => q.waiting > 20),
      severity: 'warning',
      message: (metrics) => `File d'attente agents : ${Math.max(...metrics.queues.map(q => q.waiting))} conversations en attente`,
      channels: ['slack']
    }
  ],
  
  evaluate: async () => {
    const metrics = await getOperationalMetrics();
    const triggeredAlerts = dashboardAlerts.rules.filter(rule => rule.check(metrics));
    
    for (const alert of triggeredAlerts) {
      // Éviter le spam : ne pas répéter une alerte dans les 30 minutes
      const recentAlert = await alertCache.get(`alert:${alert.name}`);
      if (recentAlert) continue;
      
      await sendAlert({
        name: alert.name,
        severity: alert.severity,
        message: alert.message(metrics),
        channels: alert.channels
      });
      
      await alertCache.set(`alert:${alert.name}`, true, 1800); // 30min cooldown
    }
  }
};

// Évaluer les alertes toutes les 5 minutes
setInterval(dashboardAlerts.evaluate, 5 * 60 * 1000);

Rapport hebdomadaire automatique

// Email de rapport hebdomadaire automatique
async function sendWeeklyReport() {
  const report = await generateExecutiveDashboard(
    startOfLastWeek(),
    endOfLastWeek()
  );
  
  const emailBody = `
    <h2>Rapport chatbot WhatsApp — Semaine du ${report.period}</h2>
    
    <div style="background: ${report.summary.status_color}; padding: 10px; border-radius: 5px">
      <strong>Statut : ${report.summary.status_label}</strong>
    </div>
    
    <table>
      <tr><td>Total conversations</td><td>${report.summary.total_conversations} (${report.summary.volume_trend_pct}% vs semaine précédente)</td></tr>
      <tr><td>Taux de résolution bot</td><td>${report.summary.resolution_rate_pct}%</td></tr>
      <tr><td>Score CSAT moyen</td><td>${report.summary.csat_avg}/5</td></tr>
      <tr><td>Économies estimées</td><td>${report.summary.savings_fcfa}</td></tr>
    </table>
  `;
  
  await emailService.send({
    to: process.env.REPORT_RECIPIENTS.split(','),
    subject: `Rapport chatbot WhatsApp — ${report.period}`,
    html: emailBody
  });
}

// Envoyer chaque lundi à 8h
schedule.every().monday().at('08:00').do(sendWeeklyReport);

Pour approfondir, consultez notre guide sur les KPIs chatbot WhatsApp et notre article sur le reporting WhatsApp Marketing mensuel.

FAQ

Q: Quels outils utiliser pour visualiser les analytics du chatbot WhatsApp ?

A: Plusieurs options selon votre contexte : (1) Whakup Analytics intégré (recommandé pour démarrer, zéro configuration), (2) Google Data Studio / Looker Studio connecté à votre base de données (flexible, gratuit), (3) Metabase auto-hébergé (excellent rapport qualité/coût pour les équipes techniques), (4) Tableau ou Power BI pour les grandes organisations. Pour les équipes africaines avec des ressources limitées, commencez avec Whakup Analytics et exportez les données vers Google Sheets pour les rapports personnalisés.

Q: Comment benchmarker nos métriques ? À quoi comparer nos résultats ?

A: Comparez d'abord à vous-même (évolution semaine sur semaine). Pour les benchmarks africains, référez-vous aux données de marché : taux de résolution 55-65% pour un bot mature, CSAT >75% pour une bonne expérience, taux de fallback <15% pour un NLP bien entraîné. Attention : les benchmarks varient selon le secteur (bancaire plus bas que e-commerce) et la maturité du bot (3 mois vs 2 ans).

Q: Comment présenter les analytics à une direction qui ne connaît pas les chatbots WhatsApp ?

A: Traduisez tout en impact business : pas "taux de résolution de 70%" mais "700 clients servis sans mobiliser d'agent cette semaine". Pas "CSAT 4.2/5" mais "85% de clients satisfaits de leur expérience". Pas "temps de réponse 1.2s" mais "nos clients ont une réponse instantanée 24h/24". L'économie en FCFA est souvent l'argument le plus efficace : calculez le coût équivalent en agents humains.

Q: À quelle fréquence actualiser les dashboards opérationnels ?

A: Dashboard temps réel : actualisation toutes les minutes pour les métriques critiques (taux d'erreur, files d'attente). Dashboard de performance : actualisation toutes les heures suffit. Dashboard hebdomadaire exécutif : calculé une fois par semaine. Un rafraîchissement trop fréquent consomme des ressources sans apporter de valeur ajoutée pour les métriques à faible volatilité.


Un bon tableau de bord analytics transforme votre bot WhatsApp d'une boîte noire en un système piloté par les données. C'est le fondement de toute démarche d'amélioration continue sérieuse.

Accédez aux analytics temps réel Whakup et pilotez votre chatbot WhatsApp avec des données précises dès aujourd'hui.

#whatsapp-business-api-guide#automatisation-whatsapp-flows#chatbot-whatsapp-guide
Arthur Lyonnet
Arthur LyonnetCo-fondateur & CEO

Co-fondateur de Whakup, Arthur accompagne les entreprises africaines dans leur transformation digitale via WhatsApp depuis 2022. Passionné par le growth marketing et l'entrepreneuriat en Afrique francophone.

🚀

Prêt à passer à l'action ?

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

Démarrer l'essai gratuit