Webhooks
Chronicle.WebHooks provides an idiomatic Elixir API for registering and inspecting Chronicle webhooks.
Webhooks let Chronicle push observed events to external HTTP endpoints.
Discoverable webhooks
Section titled “Discoverable webhooks”Discoverable webhooks follow the same pattern as projections and constraints: define them as modules and Chronicle exposes metadata through __chronicle_webhook__/1.
defmodule MyApp.WebHooks.AccountEvents do use Chronicle.WebHooks.Webhook, id: "account-events", target_url: "https://example.com/chronicle/webhooks", event_sequence_id: "event-log"
alias Chronicle.WebHooks.DefinitionBuilder
@impl true def define(builder) do builder |> DefinitionBuilder.with_event_type(MyApp.Events.AccountOpened) |> DefinitionBuilder.with_event_type(MyApp.Events.FundsDeposited) |> DefinitionBuilder.with_header("x-source", "my-app") |> DefinitionBuilder.with_bearer_token(System.fetch_env!("WEBHOOK_TOKEN")) endendWhen Chronicle.Client starts with otp_app: :my_app, discoverable webhooks are found automatically and registered on startup.
{Chronicle.Client, connection_string: "chronicle://chronicle-dev-client:chronicle-dev-secret@localhost:35000", event_store: "banking", otp_app: :my_app}You can also register explicit modules:
{Chronicle.Client, connection_string: "chronicle://chronicle-dev-client:chronicle-dev-secret@localhost:35000", event_store: "banking", webhooks: [MyApp.WebHooks.AccountEvents]}Imperative registration
Section titled “Imperative registration”Register a webhook without defining a module:
:ok = Chronicle.WebHooks.register( "account-events", "https://example.com/chronicle/webhooks", fn builder -> builder |> Chronicle.WebHooks.DefinitionBuilder.with_event_type(MyApp.Events.AccountOpened) |> Chronicle.WebHooks.DefinitionBuilder.with_basic_auth("chronicle", System.fetch_env!("WEBHOOK_PASSWORD")) |> Chronicle.WebHooks.DefinitionBuilder.with_header("x-source", "my-app") end )Builder API
Section titled “Builder API”Chronicle.WebHooks.DefinitionBuilder is immutable and pipeline-friendly.
builder|> DefinitionBuilder.on_event_sequence("audit-sequence")|> DefinitionBuilder.with_event_type(MyApp.Events.AccountOpened)|> DefinitionBuilder.with_basic_auth("user", "password")|> DefinitionBuilder.with_bearer_token("token")|> DefinitionBuilder.with_oauth("https://login.example.com", "client-id", "client-secret")|> DefinitionBuilder.with_header("x-source", "my-app")|> DefinitionBuilder.not_replayable()|> DefinitionBuilder.not_active()If you don’t select any event types, the webhook uses the event types the client was given in :event_types or discovered in your application. When that list is empty, for example with discover: false and no :event_types, it falls back to every event type module loaded in the VM. Select event types explicitly to control exactly what the webhook receives.
not_replayable() and not_active() need Chronicle kernel 19.33.0 or later. An older kernel ignores
these flags and treats the webhook as replayable and active regardless.
Query and remove webhooks
Section titled “Query and remove webhooks”{:ok, webhooks} = Chronicle.WebHooks.all():ok = Chronicle.WebHooks.remove("account-events")Registered webhooks are returned as %Chronicle.WebHooks.Definition{} with:
:id:event_sequence_id:event_types:target:replayable?:active?
The nested %Chronicle.WebHooks.Target{} contains:
:url:headers:authorization
When you build a definition locally, authorization is one of:
{:basic, %{username: ..., password: ...}}{:bearer, %{token: ...}}{:oauth, %{authority: ..., client_id: ..., client_secret: ...}}nil
Chronicle doesn’t return credentials when you read webhooks back, so :authorization is always nil on definitions from Chronicle.WebHooks.all/1.
Manual discovery
Section titled “Manual discovery”webhooks = Chronicle.WebHooks.discover():ok = Chronicle.WebHooks.register_discovered()Top-level convenience helpers
Section titled “Top-level convenience helpers”Chronicle also delegates to the webhook API:
{:ok, webhooks} = Chronicle.get_webhooks():ok = Chronicle.register_discovered_webhooks():ok = Chronicle.remove_webhook("account-events")