Webhooks
A webhook forwards events Chronicle observes to an external HTTP endpoint — use it to notify another system without that system needing to connect to Chronicle itself. Webhooks are configured server-side (the Kernel makes the HTTP calls), so registering one is a one-time setup step, not something you do per request.
Register a webhook
Section titled “Register a webhook”using Cratis.Chronicle;using Cratis.Chronicle.Events;using Cratis.Chronicle.Webhooks;
[EventType]public record WebhooksIndexAccountOpened(string OwnerName);
public class WebhooksIndexRegister(IEventStore eventStore){ public async Task RegisterWebhook() => await eventStore.Webhooks.Register( "account-events", "https://example.com/chronicle/webhooks", builder => builder .WithEventType<WebhooksIndexAccountOpened>() .WithHeader("x-source", "my-app") .WithBearerToken(Environment.GetEnvironmentVariable("WEBHOOK_TOKEN")!));}import io.cratis.chronicle.EventStoreimport io.cratis.chronicle.events.EventType
@EventType(id = "webhooks-index-order-placed")data class WebhooksIndexOrderPlaced(val orderId: String)
suspend fun registerOrderWebhook(store: EventStore) { store.webhooks.register("order-placed-webhook", "https://hooks.example.com/orders") { builder -> builder .withEventType(WebhooksIndexOrderPlaced::class) .withBearerToken("webhook-token") }}import io.cratis.chronicle.EventStore;import io.cratis.chronicle.events.EventType;
import io.cratis.chronicle.java.WebhookDefinitionBuilderJavaBridge;import io.cratis.chronicle.java.WebhooksServiceJavaBridge;
@EventType(id = "webhooks-index-order-placed")record WebhooksIndexOrderPlaced(String orderId) {}
class WebhooksIndexRegistration { void registerOrderWebhook(EventStore store) { WebhooksServiceJavaBridge.register(store.getWebhooks(), "order-placed-webhook", "https://hooks.example.com/orders", builder -> { WebhookDefinitionBuilderJavaBridge.withEventType(builder, WebhooksIndexOrderPlaced.class) .withBearerToken("webhook-token"); return null; // Java lambda returning Unit }); }}defmodule MyApp.Events.WebhooksIndexAccountOpened do use Chronicle.Events.EventType, id: "webhooks-index-account-opened"
defstruct [:owner_name]end
defmodule MyApp.WebhooksIndexRegister do alias MyApp.Events.WebhooksIndexAccountOpened
def register_webhook do Chronicle.WebHooks.register( "account-events", "https://example.com/chronicle/webhooks", fn builder -> builder |> Chronicle.WebHooks.DefinitionBuilder.with_event_type(WebhooksIndexAccountOpened) |> Chronicle.WebHooks.DefinitionBuilder.with_header("x-source", "my-app") |> Chronicle.WebHooks.DefinitionBuilder.with_bearer_token(System.fetch_env!("WEBHOOK_TOKEN")) end ) endendimport { eventType, IEventStore } from '@cratis/chronicle';
@eventType()class WebhooksIndexAccountOpened { constructor(readonly ownerName: string) {}}
class WebhooksIndexRegister { constructor( private readonly store: IEventStore, private readonly webhookToken: string ) {}
async registerWebhook(): Promise<void> { await this.store.webhooks.register( 'account-events', 'https://example.com/chronicle/webhooks', builder => { builder .withEventType(WebhooksIndexAccountOpened) .withHeader('x-source', 'my-app') .withBearerToken(this.webhookToken); } ); }}If no event types are configured, the webhook forwards every event type registered for the client.
Query registered webhooks
Section titled “Query registered webhooks”using Cratis.Chronicle;using Cratis.Chronicle.Webhooks;
public class WebhooksIndexQuery(IEventStore eventStore){ public async Task<IEnumerable<WebhookDefinition>> GetAllWebhooks() => await eventStore.Webhooks.GetAll();}import io.cratis.chronicle.EventStore
suspend fun listRegisteredWebhooks(store: EventStore) { val webhooks = store.webhooks.getAll() webhooks.forEach { webhook -> println("${webhook.identifier} -> ${webhook.target.url}") }}import Cratis.Chronicle.Contracts.Observation.Webhooks.ObservationWebhooks;
import io.cratis.chronicle.EventStore;
import io.cratis.chronicle.java.WebhooksServiceJavaBridge;
import java.util.List;
class WebhooksIndexListing { void listRegisteredWebhooks(EventStore store) { List<ObservationWebhooks.WebhookDefinition> webhooks = WebhooksServiceJavaBridge.getAll(store.getWebhooks()); for (ObservationWebhooks.WebhookDefinition webhook : webhooks) { System.out.println(webhook.getIdentifier() + " -> " + webhook.getTarget().getUrl()); } }}defmodule MyApp.WebhooksIndexQuery do def get_all_webhooks do Chronicle.WebHooks.all() endendimport { IEventStore } from '@cratis/chronicle';import { WebhookDefinition } from '@cratis/chronicle.contracts';
class WebhooksIndexQuery { constructor(private readonly store: IEventStore) {}
async getAllWebhooks(): Promise<WebhookDefinition[]> { return this.store.webhooks.getWebhooks(); }}Related topics
Section titled “Related topics”- Jobs — inspecting and controlling long-running Kernel operations, the other kernel-managed background concern.
- Subscriptions — forwarding events between event stores rather than to an external HTTP endpoint.