2.5 KiB
deliverPresenceWebhook
Purpose
Best-effort, signed delivery of a single presence event to a configured webhook receiver. The gateway calls this function on every presence transition (join / leave / update) when a presenceWebhook is configured on the daemon. Retry, exponential backoff, and circuit-breaking are owned by @suaveplan/webhook-client.deliver, which internally threads @suaveplan/retry — the gateway never has to reinvent that policy.
Features
- Per-event opt-in filter:
config.eventsconstrains which kinds fan out. Default (undefined) fans out every kind. - HMAC-SHA-256 signed payloads when
config.secretis set, matching the proposal's "signed delivery payload" requirement. - Errors are swallowed and routed to an optional
onError(err)hook so presence — which is inherently lossy — never crashes the daemon. - Deterministic delivery id:
presence-<clientId>-<at>makes the receiver's idempotency story easy.
Usage: Basic Example
import { deliverPresenceWebhook } from "@suaveplan/websocket-gateway";
await deliverPresenceWebhook(
{ url: "https://example.com/webhooks/presence", secret: "shared-secret" },
{ kind: "presence:join", clientId: "alice", roomId: "ops", status: "online", at: Date.now() }
);
Usage: Advanced Example
import { deliverPresenceWebhook } from "@suaveplan/websocket-gateway";
import { logger } from "@suaveplan/logger";
await deliverPresenceWebhook(
{
url: "https://hooks.example.com/presence",
secret: process.env.PRESENCE_HMAC,
events: ["presence:join", "presence:leave"], // skip 'update' chatter
},
{
kind: "presence:update",
clientId: "alice",
roomId: undefined,
status: "away",
at: Date.now(),
},
(err) => logger.warn("presence webhook delivery failed", { err })
);
API Reference
deliverPresenceWebhook(config, event, onError?): Promise<void>PresenceWebhookEvent—{ kind, clientId, roomId, status, at }value object.
Implementation Notes
The function never throws — webhook-client.deliver already classifies retryable vs terminal status codes and consumes the retry budget internally. Surfacing failures upstream would force the gateway to invent a recovery policy, but presence is best-effort by design (receivers reconcile via the next heartbeat / connection event). Delivery is signed with the same algorithm webhook-client defaults to (sha256); future stronger algorithms (e.g. ed25519) become a config.algorithm switch the moment webhook-client exposes one.