Webhook Signature Verification
Every webhook request includes an X-DialogBrain-Signature header with an HMAC-SHA256 signature. Always verify it to prevent spoofed requests.
Signature Format
X-DialogBrain-Signature: sha256=<hex-digest>
Python
import hashlib
import hmac
def verify_webhook(payload: bytes, signature: str, secret: str) -> bool:
"""
payload: raw request body bytes
signature: X-DialogBrain-Signature header value ("sha256=...")
secret: whsec_... from webhook creation
"""
key = bytes.fromhex(secret.removeprefix("whsec_"))
expected = "sha256=" + hmac.new(key, payload, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, signature)
# FastAPI example
from fastapi import FastAPI, Request, HTTPException
app = FastAPI()
@app.post("/webhook")
async def handle_webhook(request: Request):
body = await request.body()
sig = request.headers.get("x-dialogbrain-signature", "")
secret = "whsec_YOUR_SECRET_HERE"
if not verify_webhook(body, sig, secret):
raise HTTPException(401, "Invalid signature")
import json
event = json.loads(body)
print(f"Received: {event['event']}")
return {"ok": True}
Or use the SDK:
from dialogbrain import verify_webhook
is_valid = verify_webhook(
payload=request.body,
signature=request.headers["x-dialogbrain-signature"],
secret="whsec_YOUR_SECRET_HERE",
)
Node.js
const crypto = require('crypto');
function verifyWebhook(payload, signature, secret) {
const key = Buffer.from(secret.replace('whsec_', ''), 'hex');
const expected = 'sha256=' + crypto.createHmac('sha256', key).update(payload).digest('hex');
return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature));
}
// Express example
app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
const sig = req.headers['x-dialogbrain-signature'];
if (!verifyWebhook(req.body, sig, process.env.WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature');
}
const event = JSON.parse(req.body);
console.log('Event:', event.event);
res.json({ ok: true });
});
Go
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"strings"
)
func verifyWebhook(payload []byte, signature, secret string) bool {
hexKey := strings.TrimPrefix(secret, "whsec_")
key, err := hex.DecodeString(hexKey)
if err != nil {
return false
}
mac := hmac.New(sha256.New, key)
mac.Write(payload)
expected := "sha256=" + hex.EncodeToString(mac.Sum(nil))
return hmac.Equal([]byte(expected), []byte(signature))
}