DocsRecettesBrancher un pipeline sur les webhooks

Brancher un pipeline sur les webhooks

Créez un webhook sur transfer.downloaded, vérifiez la signature à la réception, puis déclenchez votre traitement (notifier, archiver) en toute fiabilité.

Recettes4 min de lectureMis à jour le 10 juin 2026
Télécharger en PDF

Les webhooks transforment Coffrify en source d'évènements pour vos systèmes : dès qu'un fichier est téléchargé, Coffrify envoie une requête POST signée à votre endpoint, et vous lancez la suite (notifier une équipe, archiver le transfert, écrire dans votre base). Cette recette monte un pipeline de bout en bout autour de l'évènement transfer.downloaded : créer l'abonnement, vérifier la signature à la réception, puis exécuter votre logique métier. Le principe vaut pour n'importe quel évènement du catalogue ; il suffit de changer la liste events.

Ce que vous allez construire

  • Un webhook abonné à transfer.downloaded, créé via POST /v1/webhooks.
  • Un endpoint HTTP qui reçoit l'évènement, vérifie la signature, puis répond 200 rapidement.
  • Un traitement déclenché après vérification : ici une notification et un archivage, à remplacer par votre logique.

Étape 1 : créer le webhook

Enregistrez votre endpoint et la liste d'évènements. La réponse contient un secret au format whsec_… qui n'est affiché qu'une seule fois : stockez-le immédiatement dans votre coffre à secrets ou vos variables d'environnement. C'est lui qui sert à signer chaque livraison et donc à la vérifier chez vous. L'opération exige le scope webhooks:manage.

POST/v1/webhooksCrée un abonnement webhook et renvoie le secret de signature (affiché une seule fois).
import { Coffrify } from '@coffrify/sdk'
 
const coffrify = new Coffrify({ apiKey: process.env.COFFRIFY_API_KEY })
 
const { webhook, secret } = await coffrify.webhooks.create({
name: 'Pipeline téléchargements',
url: 'https://pipeline.example.com/hooks/coffrify',
events: ['transfer.downloaded'],
})
 
console.log('Webhook créé :', webhook.id)
// À conserver : ce secret ne sera plus jamais affiché.
console.log('COFFRIFY_WEBHOOK_SECRET =', secret)

Réglez COFFRIFY_WEBHOOK_SECRET côté serveur avant de passer à la suite. Si vous l'avez perdu, ne recréez pas le webhook : faites tourner le secret avec POST /v1/webhooks/{id}/rotate-secret, qui renvoie une nouvelle valeur tout en gardant l'ancienne valide pendant une fenêtre de grâce (24 h par défaut).

Étape 2 : comprendre ce que vous recevez

Chaque livraison est un POST JSON avec une enveloppe stable. Le bloc data porte les détails propres à l'évènement, et id identifie la livraison de façon unique (utile pour la déduplication, voir plus bas).

{
"id": "a1b2c3d4-e5f6-4789-a012-3456789abcde",
"type": "transfer.downloaded",
"created_at": "2026-06-10T14:32:05.117Z",
"workspace_id": "ws_8f2c…",
"data": {
"transfer_id": "tr_9k3m…",
"country": "FR",
"bytes": 4827193
}
}

La requête arrive avec ces en-têtes. Les trois en-têtes webhook-* suivent la spécification Standard Webhooks (compatible avec les vérificateurs courants) ; les en-têtes X-Coffrify-* sont fournis en complément.

En-têteRôle
webhook-idIdentifiant unique de la livraison. Identique sur les nouvelles tentatives : sert à dédupliquer.
webhook-timestampHorodatage Unix (secondes) de la signature. Sert à rejeter les requêtes trop anciennes.
webhook-signatureSignature v1,<base64> calculée à partir du secret. C'est la valeur à vérifier.
X-Coffrify-Event-TypeType d'évènement, ici transfer.downloaded. Pratique pour router sans parser le corps.

Étape 3 : vérifier la signature, puis traiter

Le SDK fournit verifyWebhookFromHeaders : passez-lui le corps brut (non parsé), les en-têtes de la requête et votre secret. Il valide la signature et l'horodatage (tolérance de 5 minutes par défaut), puis renvoie { valid, event }. Point crucial : votre framework ne doit pas avoir déjà transformé le corps en objet. Donnez la chaîne exacte reçue, sinon la signature ne correspondra pas.

import express from 'express'
import { verifyWebhookFromHeaders } from '@coffrify/sdk/webhooks'
 
const app = express()
const SECRET = process.env.COFFRIFY_WEBHOOK_SECRET
 
app.post(
'/hooks/coffrify',
express.raw({ type: 'application/json' }),
async (req, res) => {
const rawBody = req.body.toString('utf8')
const result = await verifyWebhookFromHeaders(rawBody, req.headers, SECRET)
 
if (!result.valid) {
return res.status(400).send(result.reason)
}
 
const event = result.event
// Répondez vite : accusez réception, traitez en arrière-plan.
res.sendStatus(200)
 
if (event.type === 'transfer.downloaded') {
await runPipeline(event) // notifier, archiver, etc.
}
},
)
 
app.listen(3000)

Remplacez runPipeline par votre logique. Un exemple typique : router selon le type, notifier un canal interne, puis archiver le transfert. La déduplication via webhook-id évite de traiter deux fois la même livraison en cas de nouvelle tentative.

import { Coffrify } from '@coffrify/sdk'
 
const coffrify = new Coffrify({ apiKey: process.env.COFFRIFY_API_KEY })
const seen = new Set() // en production : Redis, base de données, etc.
 
async function runPipeline(event) {
if (seen.has(event.id)) return // déjà traité (nouvelle tentative)
seen.add(event.id)
 
const transferId = event.data.transfer_id
 
// 1. Notifier
await notifyTeam(`Transfert ${transferId} téléchargé depuis ${event.data.country}`)
 
// 2. Archiver le transfert côté Coffrify
await coffrify.transfers.delete(transferId)
}

Étape 4 : tester sans attendre un vrai téléchargement

Inutile de provoquer un téléchargement réel pour valider votre endpoint. Déclenchez une livraison de test signée vers votre URL : Coffrify renvoie le code HTTP, la durée et un extrait de la réponse de votre serveur. La requête de test porte l'en-tête X-Coffrify-Test-Delivery: true, ce qui vous permet d'isoler ces appels de vos flux réels.

const result = await coffrify.webhooks.test(webhook.id, {
event_type: 'transfer.downloaded',
})
 
console.log(result.status, result.duration_ms, result.body_preview)

Fiabilité : nouvelles tentatives et observabilité

Si votre endpoint ne répond pas 2xx, Coffrify retente la livraison avec un délai croissant, sur une fenêtre d'environ 72 heures (jusqu'à 10 tentatives). Après une série d'échecs consécutifs, l'endpoint peut être désactivé automatiquement et vous recevez l'évènement webhook.endpoint_disabled. Concevez donc votre handler pour être idempotent (grâce à webhook-id) et pour répondre rapidement, en déportant le travail lourd en arrière-plan.

  • Consultez les tentatives récentes d'un webhook avec GET /v1/webhooks/{id}/deliveries.
  • Relancez une livraison passée (même event_id, même destinataire) avec POST /v1/webhooks/deliveries/{id}/replay.
  • Remettez en file une livraison bloquée après une panne en aval avec POST /v1/webhooks/deliveries/{id}/retry.
  • Listez tous les types d'évènements disponibles via GET /v1/webhooks/events (endpoint public, sans authentification).

Aller plus loin

Le même mécanisme couvre tout le cycle de vie : abonnez-vous à transfer.created pour journaliser les envois, à transfer.expired et transfer.deleted pour nettoyer votre côté, ou aux évènements d'analyse antivirus transfer.scan_clean et transfer.scan_infected pour conditionner un traitement à un verdict sain. Ajoutez simplement ces types à events lors de la création ou via PATCH /v1/webhooks. La vérification de signature reste rigoureusement identique pour tous.

Cette page vous a-t-elle aidé ?
Anonyme, dédupliqué 24h par signature locale.