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

Intégrer OpenAI GPT-4 dans vos flows WhatsApp : tutoriel technique

Tutoriel technique step-by-step pour intégrer l'API OpenAI GPT-4 dans vos flows WhatsApp via webhooks. Code Python/Node.js, gestion du contexte et déploiement production.

Ce tutoriel vous guide étape par étape pour connecter l'API OpenAI GPT-4 à vos conversations WhatsApp via Whakup. À la fin, vous disposerez d'un chatbot WhatsApp capable de comprendre et répondre à n'importe quelle question client en français africain, avec gestion du contexte conversationnel et déploiement production robuste.

Prérequis

Avant de commencer, assurez-vous d'avoir :

  • Un compte Whakup avec numéro WhatsApp Business actif (inscrivez-vous ici)
  • Une clé API OpenAI (platform.openai.com)
  • Node.js 18+ ou Python 3.9+ sur votre serveur
  • Un domaine avec HTTPS pour votre webhook (ngrok pour le développement)

Étape 1 : Configuration de l'environnement

# Créer le projet
mkdir whatsapp-gpt4-bot
cd whatsapp-gpt4-bot
npm init -y

# Installer les dépendances
npm install openai express axios dotenv redis

Créez votre fichier .env :

OPENAI_API_KEY=sk-votre-cle-openai
WHAKUP_API_KEY=votre-cle-whakup
WHAKUP_WEBHOOK_SECRET=votre-secret-webhook
REDIS_URL=redis://localhost:6379
PORT=3000

Étape 2 : Gestion du contexte conversationnel

La gestion du contexte est cruciale : WhatsApp est une messagerie asynchrone et les conversations peuvent s'étaler sur des heures. Votre bot doit se souvenir de tout.

// context-manager.js
const redis = require('redis');
const client = redis.createClient({ url: process.env.REDIS_URL });

const CONTEXT_EXPIRY = 3600; // 1 heure d'inactivité réinitialise le contexte
const MAX_HISTORY_MESSAGES = 10; // Garder les 10 derniers échanges

async function getConversationContext(phoneNumber) {
  await client.connect().catch(() => {}); // Connexion idempotente
  
  const key = `chat_context:${phoneNumber}`;
  const data = await client.get(key);
  
  if (!data) {
    return {
      phone: phoneNumber,
      history: [],
      customer_data: null,
      session_start: new Date().toISOString()
    };
  }
  
  return JSON.parse(data);
}

async function updateConversationContext(phoneNumber, userMessage, assistantResponse) {
  const context = await getConversationContext(phoneNumber);
  
  context.history.push(
    { role: 'user', content: userMessage, timestamp: new Date().toISOString() },
    { role: 'assistant', content: assistantResponse, timestamp: new Date().toISOString() }
  );
  
  // Garder seulement les N derniers messages
  if (context.history.length > MAX_HISTORY_MESSAGES * 2) {
    context.history = context.history.slice(-MAX_HISTORY_MESSAGES * 2);
  }
  
  const key = `chat_context:${phoneNumber}`;
  await client.setEx(key, CONTEXT_EXPIRY, JSON.stringify(context));
  
  return context;
}

module.exports = { getConversationContext, updateConversationContext };

Étape 3 : Service GPT-4 avec system prompt africain

// gpt-service.js
const OpenAI = require('openai');
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });

const SYSTEM_PROMPT = `Tu es Sarah, l'assistante WhatsApp de [Nom de la boutique], une boutique en ligne populaire en Afrique de l'Ouest.

TON ET STYLE :
- Chaleureux, efficace et professionnel
- Utilise "vous" mais reste accessible
- Réponds en 2-3 phrases maximum sur WhatsApp
- Si le client écrit en nouchi ou argot, c'est ok, réponds normalement en français

CE QUE TU PEUX FAIRE :
- Répondre aux questions sur les produits, prix et disponibilités
- Aider avec le suivi de commandes (demande le numéro de commande)
- Expliquer les options de paiement (Wave, Orange Money, MTN Money, carte)
- Donner les délais de livraison (Abidjan 24h, autres villes 48-72h)
- Prendre note des problèmes et créer des tickets

CE QUE TU NE PEUX PAS FAIRE :
- Modifier des commandes directement
- Donner des remboursements (transfère à un agent)
- Promettre des prix non confirmés

ESCALADE :
Si le problème dépasse tes capacités, dis clairement : "Je vous connecte avec un collègue humain qui pourra mieux vous aider. Un instant."`;

async function generateResponse(conversationHistory, newMessage, customerContext) {
  const messages = [
    { role: 'system', content: SYSTEM_PROMPT }
  ];
  
  // Ajouter le contexte client si disponible
  if (customerContext) {
    messages.push({
      role: 'system',
      content: `Informations client : Nom: ${customerContext.name || 'Inconnu'}, Commandes: ${customerContext.order_count || 0}, Dernière commande: ${customerContext.last_order_date || 'aucune'}`
    });
  }
  
  // Ajouter l'historique
  messages.push(...conversationHistory.slice(-10));
  messages.push({ role: 'user', content: newMessage });
  
  try {
    const completion = await openai.chat.completions.create({
      model: 'gpt-4o',
      messages: messages,
      max_tokens: 250,
      temperature: 0.7,
      presence_penalty: 0.1, // Évite les répétitions
    });
    
    const response = completion.choices[0].message.content;
    const shouldEscalate = detectEscalation(response);
    
    return {
      text: response,
      escalate: shouldEscalate,
      tokens: completion.usage.total_tokens,
      model: completion.model
    };
    
  } catch (error) {
    console.error('OpenAI API Error:', error);
    // Fallback gracieux en cas d'erreur OpenAI
    return {
      text: "Je rencontre une difficulté technique. Un agent va vous répondre dans quelques minutes.",
      escalate: true,
      error: true
    };
  }
}

function detectEscalation(response) {
  const triggers = [
    'connecte avec un collègue',
    'agent humain',
    'ne suis pas en mesure',
    'dépasse mes capacités',
    'supervisor',
    'responsable'
  ];
  return triggers.some(t => response.toLowerCase().includes(t));
}

module.exports = { generateResponse };

Étape 4 : Webhook principal et intégration Whakup

// server.js
const express = require('express');
const { getConversationContext, updateConversationContext } = require('./context-manager');
const { generateResponse } = require('./gpt-service');
const axios = require('axios');

const app = express();
app.use(express.json());

// Vérification signature webhook Whakup
function verifyWebhookSignature(req) {
  const signature = req.headers['x-whakup-signature'];
  const crypto = require('crypto');
  const expected = crypto
    .createHmac('sha256', process.env.WHAKUP_WEBHOOK_SECRET)
    .update(JSON.stringify(req.body))
    .digest('hex');
  return signature === `sha256=${expected}`;
}

// Webhook principal - réception messages WhatsApp
app.post('/webhook/message', async (req, res) => {
  // Validation sécurité
  if (!verifyWebhookSignature(req)) {
    return res.status(401).json({ error: 'Unauthorized' });
  }
  
  // Accuser réception immédiatement (WhatsApp requiert réponse <5s)
  res.json({ status: 'received' });
  
  // Traitement asynchrone
  processMessage(req.body).catch(console.error);
});

async function processMessage(payload) {
  const { phone, message, message_id } = payload;
  
  try {
    // Récupérer contexte conversationnel
    const context = await getConversationContext(phone);
    
    // Générer réponse GPT-4
    const gptResponse = await generateResponse(
      context.history,
      message,
      context.customer_data
    );
    
    // Envoyer réponse via Whakup API
    await sendWhatsAppMessage(phone, gptResponse.text);
    
    // Sauvegarder contexte mis à jour
    await updateConversationContext(phone, message, gptResponse.text);
    
    // Escalade si nécessaire
    if (gptResponse.escalate) {
      await escalateToHuman(phone, message, context);
    }
    
    // Log pour monitoring
    console.log({
      event: 'message_processed',
      phone: phone.slice(-4), // Anonymisé
      tokens: gptResponse.tokens,
      escalated: gptResponse.escalate,
      timestamp: new Date().toISOString()
    });
    
  } catch (error) {
    console.error('Processing error:', error);
    // Message d'erreur gracieux au client
    await sendWhatsAppMessage(phone, "Désolé, je rencontre une difficulté. Un agent vous contacte dans 5 minutes.");
    await escalateToHuman(phone, message, null, 'technical_error');
  }
}

async function sendWhatsAppMessage(phone, text) {
  return axios.post('https://api.whakup.com/v1/messages', {
    to: phone,
    type: 'text',
    text: { body: text }
  }, {
    headers: { 'Authorization': `Bearer ${process.env.WHAKUP_API_KEY}` }
  });
}

async function escalateToHuman(phone, originalMessage, context, reason = 'bot_decision') {
  return axios.post('https://api.whakup.com/v1/conversations/escalate', {
    phone,
    reason,
    context: {
      original_message: originalMessage,
      history_summary: context?.history?.slice(-4) || []
    }
  }, {
    headers: { 'Authorization': `Bearer ${process.env.WHAKUP_API_KEY}` }
  });
}

app.listen(process.env.PORT, () => {
  console.log(`WhatsApp GPT-4 Bot running on port ${process.env.PORT}`);
});

Étape 5 : Déploiement production

Pour un déploiement production robuste, voici les recommandations :

# docker-compose.yml pour déploiement production
version: '3.8'
services:
  bot:
    build: .
    environment:
      - NODE_ENV=production
    restart: unless-stopped
    depends_on:
      - redis
    ports:
      - "3000:3000"
    
  redis:
    image: redis:7-alpine
    restart: unless-stopped
    volumes:
      - redis_data:/data
    command: redis-server --appendonly yes

volumes:
  redis_data:

Déployez sur un VPS en Afrique ou proche (AWS Cape Town, Google Cloud Johannesburg) pour minimiser la latence.

FAQ

Q: GPT-4 peut-il vraiment comprendre le nouchi et les expressions ivoiriennes ?

A: Partiellement. GPT-4 comprend le contexte général même avec des mots nouchi, mais n'a pas une maîtrise parfaite. Il est conseillé d'ajouter une couche de normalisation en amont pour les expressions les plus fréquentes. Dans 80% des cas, GPT-4 comprend suffisamment bien l'intention du message pour générer une réponse utile.

Q: Comment éviter les coûts excessifs de l'API OpenAI ?

A: Trois techniques : (1) utiliser GPT-4o-mini pour 80% des messages simples et GPT-4o uniquement pour les complexes, (2) implémenter un cache Redis pour les questions fréquentes, (3) limiter l'historique à 10 échanges maximum. Ces optimisations réduisent les coûts de 60-70%.

Q: Que faire si l'API OpenAI est indisponible ?

A: Implémentez toujours un fallback. Dans notre exemple, en cas d'erreur API, le bot envoie un message d'excuse et escalade vers un humain. Vous pouvez aussi configurer un fallback sur Claude (Anthropic) ou Mistral pour la haute disponibilité.

Q: Comment tester le bot avant de le mettre en production ?

A: Utilisez ngrok pour exposer votre webhook local, configurez un numéro WhatsApp de test dans Whakup, et testez manuellement les 50 questions les plus fréquentes de vos clients. Mesurez le taux de réponses satisfaisantes avant de basculer en production.


Vous avez maintenant un chatbot WhatsApp GPT-4 production-ready. La prochaine étape est de l'enrichir avec vos données produits via RAG et d'affiner votre system prompt avec les retours des premières semaines.

Créez votre compte Whakup pour accéder à l'API et aux webhooks nécessaires pour ce tutoriel. Consultez également notre guide sur les réponses IA pour WhatsApp et l'automatisation des flows WhatsApp.

#whatsapp-business-api-guide#automatisation-whatsapp-flows#chatbot-whatsapp-guide
Pablo Lenormand
Pablo LenormandCo-fondateur & CPO

Co-fondateur et Chief Product Officer de Whakup, Pablo conçoit les fonctionnalités qui permettent aux marques africaines de maximiser leur impact sur WhatsApp.

🚀

Prêt à passer à l'action ?

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

Démarrer l'essai gratuit