SolidHooksSolidHooks
Commencer
Cas d’usageIngérer des webhooks par e-mail

Transformez les e-mails entrants en webhook

Bien des systèmes ne vous enverront jamais de webhook. Un fournisseur envoie un avis par e-mail, une banque une alerte, un outil interne un rapport nocturne. Donnez à chacun une adresse SolidHooks et ce qui y arrive devient un événement stocké avec une enveloppe analysée, acheminé par les mêmes connexions et relancé selon le même calendrier que le trafic HTTP.
Une adresse par sourceDéduplication sur Message-IDMêmes relances et accusés de réception
Contenu de ce guide
  1. 01Créer une source e-mail et trouver son adresse
  2. 02L’enveloppe que reçoit votre destination
  3. 03Acheminer selon l’expéditeur ou l’objet
  4. 04Déduplication, budget de taille et pièces jointes
  5. 05La règle unique : une source traite l’e-mail ou HTTP, jamais les deux

Sa place dans le pipeline

L’e-mail est un fournisseur de source, choisi comme GitHub ou Stripe, et non un produit à part. Une fois analysé, le message est un événement comme un autre : les parties de SolidHooks que vous connaissez déjà continuent de fonctionner. Les connexions le font correspondre, les livraisons le relancent, la rétention le fait expirer, et votre consommateur reçoit du JSON en HTTP comme d’habitude.

Sender
any mail client
Source address
<maskId>@sdhk.events
Stored event
parsed envelope, typed
Destination
HTTP POST
Votre consommateur ne parle jamais SMTP. Il reçoit le même POST JSON que celui d’un fournisseur de webhooks.

Mise en place

  1. 1

    Créez une source avec le fournisseur e-mail

    Passez provider: "email" à la création, ou basculez une source existante avec un PATCH. La réponse contient emailAddress, qui vaut null pour tous les autres fournisseurs.

    curl
    curl -s "$API/v1/sources" \  -H "authorization: Bearer $SDHK_KEY" \  -H 'content-type: application/json' \  -d '{ "name": "Supplier notices", "provider": "email",       "verifierConfig": {} }' → { "id": "src_...", "maskId": "Kb3xk29ZtQm7Rv1A",    "emailAddress": "Kb3xk29ZtQm7Rv1A@sdhk.events", ... }

    Convertir une source qui a déjà un vérificateur exige verifierType: "noop" dans le même PATCH. Rien ne signe un e-mail entrant : l’API refuse donc de conserver l’identifiant stocké plutôt que de garder un secret qu’elle ne lirait jamais. Le même PATCH efface aussi le eventTypeField de la source et toutes ses idempotencyKeys, qui décrivaient tous deux une forme de payload qui n’arrive plus.

  2. 2

    Donnez l’adresse à l’expéditeur

    Collez-la là où l’autre système attend un destinataire. Il n’y a aucune étape de vérification ni aucun DNS à configurer de votre côté.

  3. 3

    Connectez la source à une destination

    Comme pour n’importe quelle autre source. Vous filtrez sur l’expéditeur ou l’objet, selon ce que nomme le eventTypeField de la source, ou sur email.received si vous ne l’avez pas défini. L’acheminement selon l’expéditeur ou l’objet est décrit plus bas.

Ce que reçoit votre destination

Le payload stocké est une enveloppe normalisée plutôt qu’un bloc MIME brut : votre gestionnaire n’a pas besoin d’analyseur de courrier. Les adresses sont extraites, les deux corps séparés, et les pièces jointes arrivent en base64 avec leurs métadonnées.

payload
{  "from": "billing@supplier.example",  "to": ["Kb3xk29ZtQm7Rv1A@sdhk.events"],  "cc": [],  "subject": "Invoice #42",  "messageId": "<abc123@mail.supplier.example>",  "date": "Tue, 14 Jul 2026 09:00:00 +0000",  "text": "plain-text body",  "html": "<p>html body</p>",  "spamStatus": "NotSpam",  "bounce": false,  "attachments": [    { "name": "invoice.pdf", "contentType": "application/pdf", "size": 12345, "data": "<base64>" }  ]}

from est l’en-tête From: du message réduit à une adresse nue : Acme Billing <billing@supplier.example> arrive sous la forme billing@supplier.example. C’est ce qui le rend utilisable comme clé de filtre. Le nom affiché varie, et le Return-Path sous-jacent est une adresse de rebond propre à chaque message dès qu’il passe par un service d’envoi. Cet expéditeur d’enveloppe n’est utilisé qu’en dernier recours, quand un message n’a aucun en-tête From:.

Le corps brut de l’événement conserve tout le payload d’origine du fournisseur de courrier, y compris les champs non listés ci-dessus, avec attachments[].data remplacé par null. Les octets des pièces jointes ne vivent que dans l’enveloppe, ce qui évite de stocker deux fois un gros PDF.

Une source fait l’un ou l’autre

Sur une source e-mail, un POST HTTP vers son URL d’ingestion renvoie 400 BAD_REQUEST avec un message indiquant que la source ingère des e-mails. C’est voulu. Le courrier et les webhooks arrivent par des chemins différents et un seul produit une enveloppe : une source qui accepterait les deux remettrait à votre consommateur deux formes de payload sous un même type d’événement.

Conséquence pour l’idempotence
idempotencyKeys est refusé avec un 400 sur une source e-mail. La déduplication y repose sur le Message-ID, un chemin que vous ne choisissez pas.

Acheminer selon l’expéditeur ou l’objet

Le type d’événement d’un e-mail vient du eventTypeField de la source, le même réglage que pour une source HTTP. Faites-le pointer vers body.from et chaque message est typé avec l’adresse de l’expéditeur, qu’un filtre de connexion fait ensuite correspondre comme n’importe quel type d’événement. La correspondance ignore la casse, car les systèmes de messagerie ne préservent pas la casse d’un en-tête From: : une liste d’autorisation écrite une fois continue de correspondre à un expéditeur qui arrive plus tard sous la forme Billing@Supplier.example. Le rejeu s’appuie sur le type enregistré à l’ingestion, donc les filtres se comportent à l’identique la deuxième fois.

Deux chemins sont disponibles, et aucun autre : body.from et body.subject. Ce sont les champs qui distinguent réellement un message d’un autre. Le tableau de bord propose les deux mêmes, si bien qu’une source configurée via l’API reste modifiable dans le tableau de bord SolidHooks.

curl
# Type each email with its sender instead of email.receivedcurl -s -X PATCH "$API/v1/sources/src_..." \  -H "authorization: Bearer $SDHK_KEY" \  -H 'content-type: application/json' \  -d '{ "data": { "eventTypeField": "body.from" } }' # Then a connection takes only that supplier:#   "filterRules": { "eventTypes": ["billing@supplier.example"] }
Sans réglage, un seul type
Sans eventTypeField, chaque e-mail accepté est typé email.received. Il reste filtrable, mais pas séparable par expéditeur. Le même repli s’applique message par message : un e-mail sans objet sur une source body.subject reçoit email.received au lieu d’échapper à tous les filtres.

Déduplication et budget de taille

Le courrier est plus volumineux et plus désordonné que le JSON d’un webhook : mieux vaut connaître les règles sur ce qui est conservé avant qu’une pièce jointe de 20 Mo n’arrive à 3 h du matin. Rien n’est refusé pour cause de taille. Tout est réduit pour tenir, et le budget dans lequel il faut tenir plafonne à 4 096 Ko.

déduplicationSur le Message-ID. Une répétition renvoie duplicate: true et ne stocke rien.
budgetLe maxPayloadSizeKb de la source, partagé entre corps et pièces jointes. Entre 1 et 4 096 Ko, 256 par défaut.
texte d’abordLe texte brut est décompté en premier et tronqué s’il dépasse à lui seul le budget.
html ensuiteEntièrement remplacé par null si texte et html dépassent encore le budget, jamais coupé partiellement. Dans les deux cas, bodyTruncated: true est défini.
pièces jointesLes métadonnées sont conservées, data devient null et truncated: true est défini. Les octets ne sont jamais coupés partiellement. C’est le base64 qui est décompté : prévoyez environ un tiers de plus que la taille du fichier.
rotationrotate-mask change l’adresse, car elle est dérivée du maskId.

Bonnes pratiques à adopter

  • Définissez eventTypeField sur body.from avant d’en avoir besoin. Les filtres écrits sur email.received devront être réécrits dès qu’un deuxième expéditeur utilisera la même adresse.
  • Augmentez maxPayloadSizeKb avant d’en avoir besoin si l’expéditeur joint des PDF. Le plafond est de 4 096 Ko, et le base64 coûte environ un tiers de plus que le fichier lui-même. Découvrir le budget par un indicateur truncated est une moins bonne façon de l’apprendre.
  • Lisez spamStatus et bounce dans votre gestionnaire. Ils figurent dans l’enveloppe parce que le courrier arrive d’expéditeurs que vous ne contrôlez pas.
  • Traitez l’adresse comme un identifiant secret. Quiconque la connaît peut créer des événements sur cette source : renouvelez-la si elle se retrouve dans un endroit public.

Questions

Offrez un webhook aux systèmes qui ne vous envoient que des e-mails

Choisissez l’e-mail comme fournisseur, distribuez l’adresse et traitez le résultat comme n’importe quel autre événement.