Webhook
Ogni evento outbound è firmato con HMAC-SHA256 nell'header X-Lvbl-Signature. Verifica sempre la firma prima di processare il payload.
Mai fidarsi del payload senza verifica
Senza verifica della firma chiunque conosca l'URL può inviare eventi fake. Usa
timingSafeEqual / hmac.compare_digest.Verifica firma — Node.js
ts
import { createHmac, timingSafeEqual } from "crypto";
import express from "express";
const app = express();
app.use(express.raw({ type: "application/json" }));
app.post("/webhook/lvbl", (req, res) => {
const signature = req.header("X-Lvbl-Signature") || "";
const body = req.body.toString("utf8");
const expected = createHmac("sha256", process.env.LVBL_WEBHOOK_SECRET!)
.update(body)
.digest("hex");
if (
signature.length !== expected.length ||
!timingSafeEqual(Buffer.from(signature), Buffer.from(expected))
) {
return res.status(401).send("Invalid signature");
}
const event = JSON.parse(body);
console.log(event.type, event.data);
res.send("ok");
});Verifica firma — Python
python
import hmac, hashlib, os
from flask import Flask, request, abort
app = Flask(__name__)
SECRET = os.environ["LVBL_WEBHOOK_SECRET"].encode()
@app.post("/webhook/lvbl")
def hook():
sig = request.headers.get("X-Lvbl-Signature", "")
body = request.get_data()
expected = hmac.new(SECRET, body, hashlib.sha256).hexdigest()
if not hmac.compare_digest(sig, expected):
abort(401)
event = request.get_json()
print(event["type"], event["data"])
return "ok"Esempio payload
json
{
"type": "assignment",
"experiment_id": "...",
"data": {
"user_id": "user-123",
"variant_id": "...",
"variant_name": "B"
},
"timestamp": "2026-05-31T12:00:00Z"
}Eventi disponibili
A/B Testing
assignment— utente assegnato a una varianteconversion— goal raggiuntowinner— esperimento concluso con vincitore statisticoguardrail_violation— metrica guardrail oltre sogliastatus_change— esperimento avviato / messo in pausa / terminato
Deadline Engine
subscribe— nuovo iscritto al countdownexpired— deadline scaduta per un iscrittoreminder_24h— promemoria 24h prima della scadenzareminder_1h— promemoria 1h prima