Webhooks

10 minutes Intermédiaire

Introduction

Les webhooks vous permettent de recevoir des notifications HTTP en temps réel lorsque des événements se produisent sur votre infrastructure M2S. Plus besoin de poller l’API : M2S vous notifie automatiquement.

Événements disponibles

ÉvénementDescriptionPayload
instance.createdUne instance a été crééeinstance, user
instance.deletedUne instance a été suppriméeinstance, user
instance.startedUne instance a démarréinstance
instance.stoppedUne instance s’est arrêtéeinstance
backup.completedUn backup s’est terminébackup, instance
backup.failedUn backup a échouébackup, instance, error
alert.triggeredUne alerte s’est déclenchéealert, instance, metric
invoice.createdUne facture a été généréeinvoice, amount

Créer un webhook

Via l’API

curl -X POST "https://api.m2s.cloud/v1/webhooks" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://votre-app.com/webhooks/m2s",
    "events": ["instance.created", "instance.deleted", "backup.failed"],
    "secret": "votre-secret-key",
    "active": true
  }'

# Réponse
{
  "data": {
    "id": "wh_abc123",
    "url": "https://votre-app.com/webhooks/m2s",
    "events": ["instance.created", "instance.deleted", "backup.failed"],
    "secret": "whsec_xxxxxxxxxxxxx",
    "active": true,
    "created_at": "2024-01-20T10:00:00Z"
  }
}

Via l’espace client

  1. Accédez aux webhooks : Compte → Webhooks → Nouveau webhook
  2. URL de destination : Endpoint HTTPS qui recevra les notifications
  3. Sélectionnez les événements : Choisissez les événements à écouter
  4. Secret de signature : Clé pour vérifier l’authenticité des requêtes

Payload d’un webhook

{
  "id": "evt_xyz789",
  "type": "instance.created",
  "created_at": "2024-01-20T10:30:00Z",
  "data": {
    "instance": {
      "id": "i-abc123",
      "name": "web-prod-01",
      "status": "running",
      "plan": "business",
      "region": "fr-par-1",
      "ip_address": "51.15.0.100"
    },
    "user": {
      "id": "usr_456",
      "email": "admin@example.com"
    }
  }
}

Vérifier la signature

Chaque webhook est signé avec un secret pour garantir son authenticité. Vérifiez toujours la signature avant de traiter le payload.

Python - Vérification

from flask import Flask, request, abort
import hmac
import hashlib
import json

app = Flask(__name__)
WEBHOOK_SECRET = "whsec_xxxxxxxxxxxxx"

def verify_signature(payload, signature, secret):
    expected = hmac.new(
        secret.encode(),
        payload.encode(),
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, signature)

@app.route('/webhooks/m2s', methods=['POST'])
def handle_webhook():
    payload = request.get_data(as_text=True)
    signature = request.headers.get('X-M2S-Signature')

    if not verify_signature(payload, signature, WEBHOOK_SECRET):
        abort(401)

    event = json.loads(payload)
    print(f"Événement reçu: {event['type']}")

    # Traiter l'événement
    if event['type'] == 'instance.created':
        instance = event['data']['instance']
        print(f"Nouvelle instance: {instance['name']}")

    return {'status': 'ok'}, 200

Node.js - Vérification

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

const app = express();
const WEBHOOK_SECRET = 'whsec_xxxxxxxxxxxxx';

function verifySignature(payload, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(payload, 'utf8')
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

app.post('/webhooks/m2s', (req, res) => {
  const payload = JSON.stringify(req.body);
  const signature = req.headers['x-m2s-signature'];

  if (!verifySignature(payload, signature, WEBHOOK_SECRET)) {
    return res.status(401).send('Invalid signature');
  }

  const event = req.body;
  console.log(`Événement reçu: ${event.type}`);

  res.json({ status: 'ok' });
});

Headers HTTP

Chaque requête webhook inclut les headers suivants :

HeaderDescription
X-M2S-SignatureSignature HMAC-SHA256 du payload
X-M2S-Event-IDID unique de l’événement
X-M2S-Event-TypeType d’événement (ex: instance.created)
X-M2S-TimestampTimestamp UNIX de l’événement
Content-Typeapplication/json

Gestion des échecs

Politique de retry

En cas d’échec de livraison, M2S réessaie automatiquement selon une politique exponentielle :

  • 1er retry : 1 minute
  • 2ème retry : 5 minutes
  • 3ème retry : 30 minutes
  • 4ème retry : 2 heures
  • 5ème retry : 6 heures

Après 5 échecs, le webhook est désactivé et une notification email est envoyée.

Bonnes pratiques

RecommandéÀ éviter
Vérifiez toujours la signatureTraiter sync dans le handler
Répondez rapidement (200 OK)Ignorer la signature
Traitez async (queue/background)Timeout trop long (> 30s)
Loguez les événements reçusEndpoint HTTP non sécurisé
Gérez l’idempotence (X-M2S-Event-ID)Pas de logs de débogage