"""FlowDeck — Webhook outbound dispatcher (v2.1.0).""" from __future__ import annotations import json import logging import httpx from app.db import get_conn logger = logging.getLogger(__name__) EVENTS = [ "page.created", "page.updated", "page.deleted", "collection.created", "collection.updated", "collection.deleted", "comment.added", "page.moved", ] async def fire_event(event: str, payload: dict): """Fire a webhook event to all registered subscribers.""" if event not in EVENTS: return with get_conn() as conn: subs = conn.execute("SELECT url, secret FROM webhook_subscriptions WHERE event=?", (event,)).fetchall() async with httpx.AsyncClient(timeout=10) as client: for sub in subs: url, secret = sub["url"], sub["secret"] headers = {"Content-Type": "application/json", "X-FlowDeck-Event": event} if secret: headers["X-FlowDeck-Secret"] = secret try: await client.post(url, json=payload, headers=headers) except Exception: logger.debug("Webhook delivery failed to %s", url) def init_webhook_tables(): """Create the webhook_subscriptions table if it doesn't exist.""" with get_conn() as conn: conn.execute(""" CREATE TABLE IF NOT EXISTS webhook_subscriptions ( id INTEGER PRIMARY KEY AUTOINCREMENT, url TEXT NOT NULL, event TEXT NOT NULL, secret TEXT DEFAULT '', active BOOLEAN NOT NULL DEFAULT 1, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) """) conn.commit()