Skip to content

Outbound webhooks framework (admin-configurable, HMAC-signed, event-subscribed) #324

@Salem874

Description

@Salem874

ELI5

Right now we can receive signed webhooks from Stripe and Zoom, but we can't send our own out. This would let an admin say "when a prayer request comes in, ping this URL" so other systems (a ChMS, Slack, n8n) hear about it automatically — no custom code per target.

Detailed proposal

Add tblWebhooks (id, siteId, label, targetUrl, secret, events JSON, isActive, createdAt) and tblWebhookDeliveries (id, webhookId, eventKey, payloadHash, httpStatus, responseSnippet, attemptCount, nextRetryAt, deliveredAt). Reuse the HMAC signing helper from the Stripe (#268) and Zoom (#274) inbound paths — same hash_hmac('sha256', $body, $secret) shape, just on the sending side, with X-WebMS-Signature + X-WebMS-Event + X-WebMS-Delivery-Id headers.

Add a WebhookDispatcher in _core/ with a single dispatch(string $eventKey, array $payload) entry point. Wire emit calls into the relevant apps: prayer-requests (created/answered), attendance (session-closed), expenses (submitted/approved), auth (user-created), events (created/RSVPd) — start narrow, grow with demand. Deliveries queue into tblWebhookDeliveries; an existing cron task drains the queue with exponential backoff (1m, 5m, 30m, 2h, 12h, then dead-letter).

Admin UI lives under /admin/integrations/webhooks with list/create/edit/delete, an event picker (multi-select from a registry), a "Send test event" button, and a deliveries log per webhook (last 50, status codes, response snippet, replay button). Secrets stored encrypted via the existing libsodium settings path.

Pros

  • Unlocks ChMS / Slack / n8n / Make.com / Zapier integrations with zero per-target code.
  • Reuses already-shipped HMAC signing + cron + admin scaffolding — no new framework.
  • Closes a real Church Online Platform parity gap on the primary outbound-sync path.
  • Audit-friendly: every delivery logged with payload hash and response.
  • Composable: any future app can emit by calling one dispatcher method.

Cons

  • Outbound HTTP from a shared-hosting cron needs sane timeouts/retries to avoid pile-ups.
  • Event-schema versioning is a long-tail commitment once external systems depend on it.
  • Secret rotation UX + replay-attack window need thinking through (timestamp + tolerance).
  • Risk of leaking PII to misconfigured targets — needs per-event payload allowlists.
  • Delivery log can grow fast; needs a retention/prune policy from day one.

How necessary?

Medium — high value for any admin already running a ChMS or automation stack alongside the portal.

Acceptance criteria

  • tblWebhooks + tblWebhookDeliveries migrations land with rollback notes.
  • Admin CRUD UI at /admin/integrations/webhooks with event picker + test-send.
  • WebhookDispatcher::dispatch() emits signed POSTs with HMAC headers + delivery id.
  • At least three apps (prayer-requests, attendance, expenses) emit events end-to-end.
  • Cron worker retries with exponential backoff and dead-letters after N attempts.
  • Per-webhook deliveries log shows status, payload hash, response snippet, replay button.

Estimated effort

6-8 hours focused work.


Filed during Church Online Platform competitive analysis on 2026-06-15; decision pending.

Metadata

Metadata

Assignees

No one assigned

    Labels

    for considerationIdea parked for an owner decision before active workpriority: mediumNormal priorityscope: coreCore framework (Router, Auth, Bootstrap, Logger)type: featureNew feature or module

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions