Webhooks

Les webhooks vous permettent de recevoir des notifications en temps réel lorsque des événements se produisent dans votre système Diamy, comme des appels entrants, des messages vocaux ou des changements de statut.

Présentation

Au lieu de sonder régulièrement l'API pour détecter les changements, les webhooks envoient des notifications HTTP POST à une URL que vous spécifiez lorsqu'un événement se produit. Cela vous permet de créer des intégrations en temps réel avec votre système Diamy.

Système Diamy

Votre application

1. Un événement se produit dans Diamy (ex: appel entrant)

2. Diamy envoie une requête HTTP POST à votre URL de webhook

3. Votre application traite l'événement et répond avec un code 200

Configuration des webhooks

Pour configurer un webhook, vous devez spécifier une URL de destination et les types d'événements que vous souhaitez recevoir.

Via la console d'administration

  1. Connectez-vous à votre console d'administration Diamy et accédez à Paramètres > API > Webhooks
  2. Cliquez sur Ajouter un webhook
  3. Saisissez l'URL de destination qui recevra les notifications
  4. Sélectionnez les événements que vous souhaitez recevoir
  5. Configurez éventuellement un secret pour sécuriser vos webhooks
  6. Cliquez sur Enregistrer

Via l'API

POST/v2/webhooks

Vous pouvez également créer des webhooks programmatiquement via l'API :

curl -X POST "https://api.diamy.fr/v2/webhooks" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://votre-serveur.com/webhooks/diamy",
    "events": ["call.incoming", "call.ended", "voicemail.new"],
    "secret": "votre_secret_webhook",
    "description": "Webhook pour les événements d'appels"
  }'

Types d'événements

Voici les principaux types d'événements que vous pouvez recevoir via les webhooks :

ÉvénementDescription
call.incomingDéclenché lorsqu'un nouvel appel entrant est reçu
call.answeredDéclenché lorsqu'un appel est répondu
call.missedDéclenché lorsqu'un appel entrant n'est pas répondu
call.endedDéclenché lorsqu'un appel se termine
call.transferredDéclenché lorsqu'un appel est transféré
voicemail.newDéclenché lorsqu'un nouveau message vocal est reçu
voicemail.readDéclenché lorsqu'un message vocal est marqué comme lu
message.newDéclenché lorsqu'un nouveau message instantané est reçu
user.presence_changedDéclenché lorsque le statut de présence d'un utilisateur change
contact.createdDéclenché lorsqu'un nouveau contact est créé
contact.updatedDéclenché lorsqu'un contact est mis à jour

Format des notifications

Les notifications de webhook sont envoyées sous forme de requêtes HTTP POST avec un corps JSON contenant les détails de l'événement.

Structure générale

{
  "id": "evt_123456789",
  "type": "call.incoming",
  "created_at": "2023-06-15T14:32:21Z",
  "data": {
    // Les données spécifiques à l'événement
  }
}

Chaque notification contient :

  • id : Un identifiant unique pour l'événement
  • type : Le type d'événement (ex: call.incoming)
  • created_at : La date et l'heure à laquelle l'événement s'est produit (format ISO 8601)
  • data : Un objet contenant les détails spécifiques à l'événement

Exemples par type d'événement

{
  "id": "evt_123456789",
  "type": "call.incoming",
  "created_at": "2023-06-15T14:32:21Z",
  "data": {
    "call": {
      "id": "call_123456",
      "direction": "inbound",
      "from": {
        "number": "+33123456789",
        "name": "Jean Dupont",
        "contact_id": "contact_789012"
      },
      "to": {
        "number": "+33987654321",
        "name": "Service Client",
        "user_id": "user_345678"
      },
      "status": "ringing",
      "timestamp": "2023-06-15T14:32:21Z",
      "queue": {
        "id": "queue_123",
        "name": "Support Technique"
      },
      "custom_data": {
        "crm_contact_id": "CRM-12345"
      }
    }
  }
}

Vérification des signatures

Pour garantir que les webhooks proviennent bien de Diamy et n'ont pas été altérés, nous signons chaque requête avec un secret que vous configurez.

En-tête de signature

Chaque requête webhook inclut un en-tête Diamy-Signature qui contient une signature HMAC-SHA256 du corps de la requête, générée avec votre secret webhook.

Diamy-Signature: t=1623766341,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd

L'en-tête contient :

  • t : Timestamp de la requête (en secondes depuis l'époque Unix)
  • v1 : Signature HMAC-SHA256 du corps de la requête

Vérification de la signature

Pour vérifier la signature, vous devez :

  1. Extraire le timestamp et la signature de l'en-tête
  2. Vérifier que la requête n'est pas trop ancienne (pour éviter les attaques par rejeu)
  3. Calculer le HMAC-SHA256 du corps de la requête avec votre secret webhook
  4. Comparer la signature calculée avec celle reçue dans l'en-tête

Exemple en Node.js

const crypto = require('crypto');
const express = require('express');
const app = express();

app.use(express.json({
  verify: (req, res, buf) => {
    req.rawBody = buf;
  }
}));

app.post('/webhooks/diamy', (req, res) => {
  const signature = req.headers['diamy-signature'];
  const webhookSecret = 'votre_secret_webhook';
  
  if (!signature) {
    return res.status(400).send('Signature manquante');
  }
  
  // Extraire le timestamp et la signature
  const [timestamp, receivedSignature] = signature.split(',').map(part => {
    const [key, value] = part.split('=');
    return value;
  });
  
  // Vérifier que la requête n'est pas trop ancienne (5 minutes max)
  const now = Math.floor(Date.now() / 1000);
  if (now - parseInt(timestamp) > 300) {
    return res.status(400).send('Requête expirée');
  }
  
  // Calculer la signature
  const hmac = crypto.createHmac('sha256', webhookSecret);
  hmac.update(req.rawBody);
  const expectedSignature = hmac.digest('hex');
  
  // Comparer les signatures
  if (receivedSignature !== expectedSignature) {
    return res.status(401).send('Signature invalide');
  }
  
  // Traiter l'événement
  const event = req.body;
  console.log('Événement reçu:', event.type);
  
  // Répondre avec un code 200 pour confirmer la réception
  res.status(200).send('OK');
});

app.listen(3000, () => {
  console.log('Serveur webhook démarré sur le port 3000');
});

Bonnes pratiques

  • Répondez rapidement : Votre endpoint doit répondre avec un code 200 dès que possible pour confirmer la réception. Traitez l'événement de manière asynchrone si nécessaire.
  • Gérez les tentatives : Si votre endpoint ne répond pas avec un code 200, Diamy réessaiera d'envoyer l'événement plusieurs fois avec une stratégie de backoff exponentiel.
  • Vérifiez les signatures : Utilisez toujours la vérification des signatures pour vous assurer que les requêtes proviennent bien de Diamy.
  • Traitez les événements de manière idempotente : Un même événement peut être envoyé plusieurs fois en cas d'erreur. Assurez-vous que votre traitement est idempotent.
  • Surveillez vos webhooks : Utilisez la console d'administration pour surveiller les livraisons de webhooks et les éventuelles erreurs.

Dépannage

Problèmes courants

ProblèmeSolution
Webhook non reçu
  • Vérifiez que l'URL est accessible depuis Internet
  • Vérifiez les pare-feu et les règles de sécurité
  • Consultez les logs de livraison dans la console d'administration
Erreur de signature
  • Vérifiez que vous utilisez le bon secret
  • Assurez-vous de calculer la signature sur le corps brut de la requête
  • Vérifiez que vous utilisez l'algorithme HMAC-SHA256
Événements manquants
  • Vérifiez que vous avez souscrit aux bons types d'événements
  • Consultez les logs d'événements dans la console d'administration
Événements en double
  • Implémentez un traitement idempotent en utilisant l'ID de l'événement
  • Stockez les IDs d'événements traités pour éviter les doublons

Pour plus d'informations ou en cas de problème, n'hésitez pas à contacter notre support technique à l'adresse support@diamy.fr.