Skip to content

Webhook Events System #19

Description

@WFord26

Context

Webhook events let power users connect CalendarGenie to CRM, Slack, or billing tools. The GTM strategy targets at least 1 published integration (Zapier or Slack) by Q3. This requires a reliable event delivery system with HMAC-signed payloads.

Scope

Database

CREATE TABLE webhooks (
  id SERIAL PRIMARY KEY,
  tenant_id INTEGER NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
  url TEXT NOT NULL,
  secret_hash TEXT NOT NULL,
  events TEXT[] NOT NULL,
  is_active BOOLEAN NOT NULL DEFAULT true,
  created_by INTEGER NOT NULL REFERENCES users(id),
  created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE TABLE webhook_deliveries (
  id SERIAL PRIMARY KEY,
  webhook_id INTEGER NOT NULL REFERENCES webhooks(id) ON DELETE CASCADE,
  event_type TEXT NOT NULL,
  payload JSONB NOT NULL,
  response_status INTEGER,
  response_body TEXT,
  attempt INTEGER NOT NULL DEFAULT 1,
  delivered_at TIMESTAMPTZ,
  failed_at TIMESTAMPTZ,
  next_retry_at TIMESTAMPTZ,
  created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX idx_webhook_deliveries_pending ON webhook_deliveries(next_retry_at) WHERE delivered_at IS NULL AND failed_at IS NULL;

Events

Event Trigger Payload
booking.created New booking confirmed Booking + project + time block details
booking.cancelled Booking cancelled Booking + cancellation timestamp
booking.rescheduled Booking rescheduled Old + new booking details
session.completed Time block end_time passes with active booking Booking + session details

Delivery

  • Queue webhook delivery as background job (existing job queue)
  • Sign payload with HMAC-SHA256 using webhook secret
  • Include signature in X-CalendarGenie-Signature header
  • Retry failed deliveries: 3 attempts with exponential backoff (1min, 5min, 30min)
  • Mark as failed after max attempts
  • 10-second timeout per delivery attempt

Backend Endpoints

Method Path Auth Description
GET /api/v1/admin/webhooks Admin List all webhooks for tenant
POST /api/v1/admin/webhooks Admin Create webhook (url, events, secret auto-generated)
PUT /api/v1/admin/webhooks/:id Admin Update webhook (url, events, active status)
DELETE /api/v1/admin/webhooks/:id Admin Delete webhook
POST /api/v1/admin/webhooks/:id/test Admin Send test event to verify endpoint
GET /api/v1/admin/webhooks/:id/deliveries Admin View delivery history

Frontend

  • Webhook management page in admin area
  • Create webhook: URL input + event checkboxes + auto-generated secret (shown once)
  • Delivery log table: event type, status, timestamp, response code
  • Test button sends a test.ping event
  • Toggle active/inactive per webhook

Security

  • Webhook secrets: generated server-side, 256-bit entropy
  • Stored as bcrypt hash — raw secret shown only at creation time
  • HMAC signature prevents payload tampering
  • URL validation: HTTPS required in production

Effort

L (1-2 weeks)

Acceptance Criteria

  • All 4 event types fire reliably when corresponding actions occur
  • HMAC-SHA256 signature included in delivery headers
  • Failed deliveries retry with exponential backoff
  • Admin can create, update, delete, and test webhooks
  • Delivery history viewable per webhook
  • Webhook secrets shown only at creation, stored as hash
  • HTTPS required for webhook URLs in production mode

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1Important priority — expected at GAfeatureNew featurefull-stackRequires backend + frontend + database changes

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions