Cada llamada enviada por Mailpro incluye cabeceras que permiten autenticarla:
X-Mailpro-Signature : t=1758000000,v1=5a72…c8b1
X-Mailpro-Event-Id : evt_5f2c…
X-Mailpro-Event-Type: email.delivered
X-Mailpro-Attempt : 1
Cálculo de la firma
v1 es el HMAC-SHA256, en hexadecimal minúsculas, de la cadena t + "." + cuerpo bruto de la petición, calculado con el secreto entregado al crear el webhook. El cuerpo debe tomarse tal como se recibió, antes de cualquier decodificación JSON.
// Node.js
const crypto = require("crypto");
function verify(rawBody, header, secret) {
const t = header.match(/t=([0-9]+)/)[1];
const v1 = header.match(/v1=([0-9a-f]+)/)[1];
const expected = crypto.createHmac("sha256", secret).update(t + "." + rawBody).digest("hex");
const fresh = Math.abs(Date.now() / 1000 - Number(t)) < 300; // 5 minutos
return fresh && crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(v1));
}
Buenas prácticas
- Rechace toda petición cuya firma no coincida o cuya marca de tiempo
ttenga más de unos minutos (protección contra repetición). - Use
X-Mailpro-Event-Idpara ignorar un evento ya procesado: una misma entrega puede presentarse varias veces en caso de reintento. - Responda 2xx en menos de 10 segundos y procese después el mensaje de forma asíncrona.
- Tras Renovar el secreto, el antiguo queda invalidado de inmediato: actualice antes su servidor o tolere un minuto de firmas rechazadas.
Los webhooks de destino de la automatización (sentido B) siguen el mismo principio, con la cabecera X-Mailpro-Automation-Signature y la clave de firma opcional que defina en el destino.