Aller au contenu principal

Webhooks

Les webhooks SendAs.me vous permettent de recevoir des notifications en temps réel sur les événements liés à vos applications : emails envoyés, échecs, connexions OAuth, révoctions de compte.

Comment fonctionnent les webhooks

  1. Vous configurez une URL webhook sur votre application dans le portail
  2. Lorsqu'un événement se produit, SendAs.me envoie une requête POST HTTP vers votre URL
  3. Votre serveur reçoit le payload JSON signé et peut agir en conséquence (mettre à jour votre base de données, afficher une notification, déclencher une relance, etc.)

Vous pouvez configurer plusieurs endpoints webhook par application, chacun avec ses propres événements.


Types d'événements

ÉvénementDéclenché quand
email_sentUn email a été envoyé avec succès via Gmail ou Office 365
email_failed_tempL'envoi a échoué temporairement (erreur réseau, API indisponible) — sera retenté
email_failed_permL'envoi a échoué définitivement (adresse invalide, quota dépassé)
oauth_connectedUn de vos utilisateurs vient de connecter son compte Gmail ou Office 365
oauth_expiredLe compte d'un utilisateur a été révoqué — les envois pour ce compte échoueront

Format des payloads

Tous les événements partagent la même structure de base :

{
"event": "email_sent",
"app_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"timestamp": "2025-06-15T10:35:22.543Z",
"data": { }
}

email_sent

{
"event": "email_sent",
"app_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"timestamp": "2025-06-15T10:35:22.543Z",
"data": {
"log_id": "log_abc123def456",
"from_address": "alice@gmail.com",
"to_address": "bob@example.com",
"subject": "Votre commande #12345 est confirmée",
"provider": "gmail",
"message_id": "18d4a2b3c1e4f567"
}
}

email_failed_temp

{
"event": "email_failed_temp",
"app_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"timestamp": "2025-06-15T10:35:22.543Z",
"data": {
"log_id": "log_abc123def456",
"from_address": "alice@gmail.com",
"to_address": "bob@example.com",
"subject": "Votre commande #12345 est confirmée",
"provider": "gmail",
"error": "Connection timeout to Gmail API",
"retry_count": 1,
"next_retry_at": "2025-06-15T10:40:22.543Z"
}
}

email_failed_perm

{
"event": "email_failed_perm",
"app_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"timestamp": "2025-06-15T10:35:22.543Z",
"data": {
"log_id": "log_abc123def456",
"from_address": "alice@gmail.com",
"to_address": "adresse-invalide",
"subject": "Test",
"provider": "gmail",
"error": "Invalid recipient address",
"final": true
}
}

oauth_connected

{
"event": "oauth_connected",
"app_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"timestamp": "2025-06-15T09:00:00.000Z",
"data": {
"credential_id": "cred_xyz789abc",
"email": "alice@gmail.com",
"provider": "gmail"
}
}

oauth_expired

{
"event": "oauth_expired",
"app_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"timestamp": "2025-06-15T10:00:00.000Z",
"data": {
"credential_id": "cred_xyz789abc",
"email": "alice@gmail.com",
"provider": "gmail",
"reason": "refresh_token_revoked"
}
}

Signature HMAC

Chaque webhook est signé avec HMAC-SHA256 pour vous permettre de vérifier son authenticité et de vous assurer qu'il provient bien de SendAs.me.

Header de signature

X-Gateway-Signature: sha256=a1b2c3d4e5f6789...

Calcul de la signature

signature = HMAC-SHA256(webhook_secret, json_body_bytes)
header_value = "sha256=" + hex(signature)

json_body_bytes est le body HTTP brut (en bytes), et webhook_secret est le secret configuré sur votre webhook dans le portail.

Vérification côté serveur

Toujours vérifier la signature

Ne traitez jamais un webhook sans avoir vérifié sa signature. Un attaquant pourrait envoyer de faux événements vers votre endpoint.

Python :

import hmac
import hashlib

def verify_signature(body: bytes, signature_header: str, secret: str) -> bool:
expected = hmac.new(
secret.encode(),
body,
hashlib.sha256
).hexdigest()
received = signature_header.replace("sha256=", "")
return hmac.compare_digest(expected, received)

Node.js :

const crypto = require('crypto');

function verifySignature(body, signatureHeader, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(body)
.digest('hex');
const received = signatureHeader.replace('sha256=', '');
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(received)
);
}

PHP :

function verifySignature(string $body, string $signatureHeader, string $secret): bool {
$expected = hash_hmac('sha256', $body, $secret);
$received = str_replace('sha256=', '', $signatureHeader);
return hash_equals($expected, $received);
}

Retry et backoff exponentiel

Si votre endpoint retourne un code HTTP autre que 2xx, ou si la connexion échoue, SendAs.me retente la livraison automatiquement :

TentativeDélai avant retry
1ère (initiale)Immédiate
2ème5 minutes
3ème20 minutes
4ème60 minutes
Abandon

Après 4 tentatives échouées, le webhook est marqué failed. Vous pouvez consulter l'historique complet des tentatives dans le portail et, si nécessaire, relancer manuellement une livraison.

Répondre rapidement

Votre endpoint webhook doit répondre en moins de 30 secondes. Si votre traitement prend plus de temps, répondez 200 OK immédiatement et traitez le payload de façon asynchrone dans votre système.


Historique des livraisons

Le portail affiche l'historique de chaque tentative de livraison pour chaque webhook :

  • Numéro de tentative
  • Code HTTP retourné
  • Durée de la requête
  • Corps de la réponse (tronqué)
  • Statut (réussi ou échoué)
  • Horodatage

Utile pour déboguer un endpoint qui ne reçoit pas les notifications attendues.