Skip to content

Add webhook notifications for pipeline events #14

Description

@ipasechnikov

Summary

Let a pipeline notify an external HTTP endpoint when something happens — an error at any stage, a message delivered successfully, or a custom event raised from mapping logic. Enables alerting, dashboards, downstream triggers, and audit without polling Interbox.

Motivation

Today a pipeline's outcome (delivered / errored) is only visible by inspecting Interbox itself. Integrators want to be pushed these events into their own systems (Slack, PagerDuty, an internal service) instead of watching for them.

Proposed authoring

Subscribe a pipeline's events to one or more endpoints:

pipeline("adt")
  .source(mllpSource({ /* ... */ }))
  .mapper(v2ToFhir({ /* ... */ }))
  .sender(aidboxSender({ /* ... */ }))
  // any error in this pipeline → ops endpoint
  .webhook({ url: env("OPS_WEBHOOK_URL"), secret: env("WEBHOOK_SECRET"),
             on: ["parse_error", "map_error", "send_error"] })
  // every successful delivery → analytics endpoint
  .webhook({ url: env("ANALYTICS_WEBHOOK_URL"), on: ["sent"] });

Event types

  • parse_error — inbound message could not be parsed
  • map_error — mapping failed
  • send_error — delivery to the destination failed (permanent)
  • deferred — delivery failed after retries were exhausted
  • sent — message delivered successfully
  • custom:* — application-defined (below)

Custom events from mapping

Raise domain events from mapping code:

map(cfg, msg, ctx) {
  const patient = toPatient(msg);
  if (msg.MRG) ctx.webhook("custom:patient_merged", { into: patient.id });
  return patient;
}

Route them like any other event: .webhook({ url: env("EVENTS_URL"), on: ["custom:patient_merged"] }).

Delivery expectations

  • Reliable — an event is not lost if the endpoint is briefly unreachable; deliveries are retried with backoff.
  • Signed — each request carries an HMAC signature header; the receiver verifies authenticity. Signing secret supplied via env.
  • Idempotent — each delivery carries a stable unique id; retries reuse it, so receivers can dedupe.
  • Payload — JSON: event type, pipeline name, minimal context (ids, error info). Opt-in to include the raw message or mapped resource.

Security

  • Signing secret provided via env var — never committed to config.
  • Outbound URLs restricted by an allowlist; internal / link-local addresses blocked.

Out of scope (initial)

  • UI for managing endpoints (config-as-code only).
  • Delivery fan-out beyond the endpoints you declare.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Fields

    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