Product
Guide pratique d’utilisation des webhooks de Mailgun
Cet article invité a été rédigé par Opeyemi Obembe, un client de Mailgun basé au Nigeria. Quand nous avons découvert le tutoriel d’Opeyemi sur la configuration des webhooks, nous avons su qu’il fallait le partager avec vous. Non seulement la méthodologie d’Opeyemi est infaillible, mais il est exactement le type de développeur que nous aimons soutenir.
Opeyemi s’est inscrit à Mailgun pour la première fois il y a quatre ans, et a depuis créé des projets vraiment intéressants. Plus récemment, il a développé Suet, un projet open source qui fournit des statistiques et des rapports détaillés pour les emails transactionnels envoyés via Mailgun. Vous pouvez l’utiliser en tandem avec nos nouvelles fonctionnalités de statistiques pour obtenir plus d’informations sur l’engagement de vos emails.
Les emails transactionnels sont essentiels pour la plupart des applications. Nous envoyons des emails de bienvenue, des emails de récupération de mot de passe, des notifications, et bien plus encore. Et dans ce cas, nous faisons appel à des fournisseurs comme Mailgun. Envoyer des emails, c’est super, mais qu’en est-il de la livraison et des performances ? Cet utilisateur a-t-il bien reçu cet email de réinitialisation de mot de passe ? Cet email de notification d’expiration de carte de crédit a-t-il été ouvert ?
Bien que ces données soient disponibles dans le tableau de bord de votre compte Mailgun, une autre façon d’obtenir des mises à jour sur ce qui arrive à vos messages transactionnels dans Mailgun est d’utiliser webhooks. Il existe également l’API, mais contrairement à l’API où vous « demandez » ces mises à jour (Poll), avec les webhooks, les mises à jour vous sont envoyées (Push). Il vous suffit de fournir l’URL d’un script capable de traiter les données d’événement via POST.
Inutile de préciser que le push présente certains avantages par rapport au poll.
- Vous n’avez pas besoin d’effectuer des requêtes API répétées. Cela signifie que vous consommez moins de ressources serveur.
- Les mises à jour se font davantage en temps réel, car elles sont poussées dès qu’elles sont disponibles sur le serveur.
Mise en place de webhooks
Il existe deux façons de configurer des webhooks dans Mailgun. Vous pouvez le faire via le tableau de bord Mailgun ou API. La méthode la plus simple consiste à utiliser le tableau de bord. Une fois sur votre tableau de bord, un lien Webhooks est disponible dans la barre de navigation.

La page des webhooks répertorie les différents types d’événements pour lesquels vous pouvez recevoir des données. En cliquant sur l’icône « + » en face de chaque événement, vous pouvez définir l’URL à laquelle les données d’événement seront envoyées.
Traitement des données
Pour traiter les données d’événement envoyées à l’URL de notre webhook, nous devons d’abord savoir à quoi ces données ressembleront. Les paramètres envoyés via POST sont disponibles dans la documentation API. Nous pouvons aller plus loin et le confirmer en utilisant une URL de webhook de test qui enregistrera les données provenant de Mailgun. Nous pouvons utiliser le Postbin de Mailgun ou requestb.in. Ces services généreront un point de terminaison unique que nous pourrons utiliser dans le tableau de bord Mailgun pour obtenir des exemples de données d’événement. Je recommande requestbin car il fournit plus de détails, comme les en-têtes de requête. Ces en-têtes sont importants car vous pourriez facilement ne pas remarquer que Mailgun envoie certaines données avec le content-type [application/x-www-form-urlencoded] et d’autres au format [multipart/form-data]. Passer à côté de ces petits détails change du tout au tout la façon dont vous obtenez les données d’événement.
Créons un point de terminaison de test pour voir à quoi ressemblent les données d’événement par rapport à ce qui se trouve dans la documentation.
- Consultez requestb.in et créez un bin.
- Copiez l’URL et accédez à la section Webhooks de votre tableau de bord Mailgun.
- Collez l’URL dans le champ de saisie et cliquez sur le lien « Test Webhook ». Cela enverra des exemples de données d’événement à l’URL.

- Répétez cette opération pour tous les événements qui vous intéressent.
- Actualisez la page de requestbin pour voir les données d’événement envoyées.

Si vous examinez attentivement les données sur requestbin, vous remarquerez ce que j’ai dit concernant certaines données envoyées au format multipart/form-data.
Maintenant que nous connaissons les paramètres pour chaque type d’événement et le type de contenu sous lequel ils peuvent se présenter, il est facile d’écrire le code pour traiter les données envoyées. Voici un code simple qui affichera les détails des plaintes et des emails rejetés. (J’utilise multer pour gérer le multipart/form-data.)
const express = require('express') rn , bodyParser = require('body-parser')rn , multer = require('multer')rn ;rnrnconst app = express(); rnapp.use(bodyParser.urlencoded({extended: false})); rnapp.listen(process.env.PORT || 3000);rnrnapp.post('/webhook', multer().none(), function(req, res) { rn const email = req.body.recipient;rn const event = req.body.event;rnrn if (event == 'complained') {rn console.log(<code data-enlighter-language="generic" class="EnlighterJSRAW">${email} complained about your mail</code>);rn }rn else if (event == 'dropped') {rn console.log(<code data-enlighter-language="generic" class="EnlighterJSRAW">Mail to ${email} dropped. ${event.description}</code>);rn }rn else if (event == 'bounced') {rn console.log(<code data-enlighter-language="generic" class="EnlighterJSRAW">Error ${event.code}: Mail to ${email} bounced. ${event.error}</code>);rn }rnrn res.end();rn});
Sécurisation
Rien n’empêche une personne qui connaît l’URL de notre webhook de créer de fausses données d’événement et de les envoyer à cette URL. Heureusement, Mailgun signe chaque requête envoyée et publie également les paramètres suivants :
- timestamp (nombre de secondes écoulées depuis le 1er janvier 1970)
- jeton (chaîne de 50 caractères générée aléatoirement)
- signature (chaîne hexadécimale générée par l’algorithme HMAC)
Pour vérifier le jeton, vous devez :
- Concaténer les valeurs du timestamp et du jeton.
- Encoder la chaîne résultante avec HMAC, en utilisant votre clé de signature de webhook HTTP comme clé et Sha256 comme algorithme.
Le résultat doit être identique à la signature.
Voici ce que cela donne dans Node.js :
const value = event_data_timestamp+event_data_token; rnconst hash = crypto.createHmac('sha256', apikey) rn .update(value)rn .digest('hex');rnif (hash !== event_data_signature) { rn console.log('Invalid signature');rn return;rn}
Si nous ajoutons cela à notre exemple de code initial, nous obtiendrons quelque chose comme ceci :
const express = require('express') rn , crypto = require('crypto')rn , multer = require('multer')rn , bodyParser = require('body-parser')rn ;rnrnconst app = express(); rnapp.use(bodyParser.urlencoded({extended: false})); rnapp.listen(process.env.PORT || 3000);rnrnapp.get('/webhook', multer().none(), function(req, res) { rn // Validate signaturern const value = req.body.timestamp+req.body.token;rn const hash = crypto.createHmac('sha256',rn process.env.API_KEY)rn .update(value)rn .digest('hex');rn if (hash !== req.body.signature) {rn console.log('Invalid signature');rn return res.end();rn }rnrn // Log status of eventrn const email = req.body.recipient;rn const event = req.body.event;rnrn if (event == 'complained') {rn console.log(<code data-enlighter-language="generic" class="EnlighterJSRAW">${email} complained about your mail</code>);rn }rn else if (event == 'dropped') {rn console.log(<code data-enlighter-language="generic" class="EnlighterJSRAW">Mail to ${email} dropped. ${event.description}</code>);rn }rn else if (event == 'bounced') {rn console.log(<code data-enlighter-language="generic" class="EnlighterJSRAW">Error ${event.code}: Mail to ${email} bounced. ${event.error}</code>);rn }rnrn res.end();rn});
Nous pouvons même aller plus loin, et :
- Pour chaque requête, vérifier dans un cache de jetons afin d’éviter l’utilisation du même jeton. Chaque jeton y sera stocké. Cela permettra d’éviter les attaques par rejeu.
- Vérifier que le timestamp n’est pas trop éloigné de l’heure actuelle.
Mise à l’échelle
Si vous envoyez beaucoup d’emails et que vous attendez un grand nombre d’événements, placer votre script de webhook sur un serveur qui ne peut pas évoluer automatiquement est une mauvaise idée. Même si vous ne vous attendez pas à beaucoup d’événements, des imprévus peuvent entraîner une forte augmentation des événements. Avoir un serveur capable d’évoluer automatiquement est très utile dans ce genre de situation.
Découvrez le serverless computing. En clair, l’idée est que vous pouvez déléguer l’exécution de votre code et tout ce qui s’y rapporte à un fournisseur. Plusieurs instances de votre code peuvent être exécutées en parallèle, et vous pouvez ajuster les ressources informatiques, comme la RAM et le temps d’exécution, à la volée. Cela le rend hautement évolutif. Vous êtes également facturé en fonction des ressources consommées et du temps d’exécution. Cela peut donc s’avérer très économique si vous n’envoyez pas souvent de gros volumes d’emails.
Il existe plusieurs fournisseurs de serverless computing. L’un de ceux que j’utilise et recommande est Google Cloud Functions en raison de la facilité de configuration des fonctions HTTP. Une fonction HTTP est un bloc de code encapsulé sous forme de fonction qui peut être déclenché en visitant une URL. C’est exactement ce dont nous avons besoin pour notre webhook.
Pour créer cette fonction, nous devons écrire une fonction JavaScript qui sera exportée en tant que module Node.js. La fonction prend des arguments spécifiques au protocole HTTP : request et response.
exports.webhook = function(request, response) { rn // Handle event data herern response.send({status:"ok"});rn}
En fonction du content-type de la requête, le corps de la requête est automatiquement transmis et disponible dans le paramètre body de l’objet de requête.
exports.webhook = function(request, response) { rn let event = request.body.event; // deliveredrn // Handle event data herern // ...rn response.send({status:"ok"});rn}
Cependant, cela ne fonctionne pas pour le type de contenu multipart/form-data. Et comme nous le savons déjà, Mailgun envoie certaines données au format multipart/form-data. Nous pouvons intégrer une bibliothèque comme Multer en utilisant require(). Cependant, nous devons nous assurer que la dépendance est répertoriée dans le fichier package.json.
const multer = require('multer');rnrnexports.webhook = function(request, response) { rn parser(request, response, function(){rn console.log(request.body); // Our event datarn // Handle event data herern // ...rn response.send({status:"ok"});rn });rn}
{rn "dependencies": {rn "multer": "^1.3.0"rn }rn}
Ensuite, nous pouvons publier la fonction sur Cloud Functions. Un moyen simple de le faire est de passer par le tableau de bord de Cloud Functions.
- Accédez à votre console Google Cloud (si vous n’avez pas encore de compte, créez-en un).
- Activez Cloud Functions dans le tableau de bord.
- Cliquez sur « Créer une fonction ».
- Entrez un nom pour votre fonction (par exemple, « mailgun-webhook »).
- Dans la section de déclenchement, sélectionnez « Déclencheur HTTP ». Notez l’URL, il s’agira de l’URL de votre webhook.
- Copiez le code de traitement des données d’événement dans la section index.js de la fonction Cloud.
- Copiez le contenu de votre package.json et collez-le dans la section package.json .
- Sélectionnez ou créez un Stage bucket. Le stage bucket est simplement l’endroit où le code est préparé. Vous pouvez utiliser ce que vous voulez ici.
- Dans Fonction à exécuter, saisissez le nom de votre fonction (par exemple, « webhook »).
- Enregistrer.
Vous pouvez désormais utiliser l’URL de la fonction dans Mailgun comme URL de webhook.
Conclusion
Travailler avec les webhooks de Mailgun est facile. Il existe de nombreuses façons d’utiliser les données d’événement pour enrichir vos applications en dehors de Mailgun. Si, par exemple, vous permettez à vos utilisateurs d’envoyer des emails depuis votre site Web pour quelque raison que ce soit et que vous utilisez Mailgun, vous pouvez utiliser les webhooks pour leur fournir des statistiques. Vous souhaitez peut-être envoyer vos statistiques d’emails vers une autre plateforme. Vous souhaitez peut-être être notifié en cas d’échec dans votre Slack compte. Ou peut-être pas du tout, peut-être souhaitez-vous simplement des statistiques plus détaillées. Quel que soit le cas d’utilisation, les données d’événement sont à votre disposition.
Pour un exemple concret, consultez la source du fichier webhook de Suet.
Vous souhaitez essayer les webhooks de Mailgun ? Inscrivez-vous !
Et si vous avez besoin d’aide pour faire vos premiers pas avec Mailgun, découvrez cette formation Mailgun gratuite! Notre responsable du support client, Chris Hammer, vous guide tout au long du processus de configuration et vous aide à démarrer l’envoi, la réception et le suivi de vos emails avec Mailgun.