Receivers
An endpoint that verifies the Webhook-Signature header before it reads the body, in your framework. The secret is the sk_zelf_wh_... value from your subscription.
pip install zelf-sdkEvery Python example below verifies the signature with the Zelf client, so the HMAC, the timestamp window and the replay check are handled for you.
Framework
import os
from fastapi import FastAPI, Request, Response
from starlette.concurrency import run_in_threadpool
from zelf import webhooks
# Your webhook signing secret. Set it as an environment variable. A list is
# also accepted, so both secrets can be held during a rotation.
WEBHOOK_SECRET = os.environ["ZELF_WEBHOOK_SECRET"]
app = FastAPI()
def handle(event: webhooks.WebhookEvent) -> None:
if event.delivery_mode == "inline":
# The rows arrive in the body.
for row in event.items:
print("row", row.get("id"))
return
# Manifest mode. rows() downloads each file and checks the published
# sha256 over the body before it yields anything.
for row in event.rows():
print("row", row.get("id"))
@app.post("/webhooks/zelf")
async def receiver(request: Request):
# parse() checks the signature and the timestamp, then returns the typed
# event. Pass the raw bytes, not request.json().
try:
event = webhooks.parse(await request.body(), request.headers, WEBHOOK_SECRET)
except webhooks.WebhookVerificationError as exc:
# Return 4xx so a bad message is not retried.
return Response(f"rejected: {exc}", status_code=400)
# Reply fast. rows() blocks, so keep it off the event loop.
await run_in_threadpool(handle, event)
return Response(status_code=204)