@molecule/api-notifications-webhook
Provider bond · notifications · API (Node) · v1.0.2 · Apache-2.0
HTTP webhook notification provider
npm install @molecule/api-notifications-webhooknpm · Source on GitHub · Implements @molecule/api-notifications
How it works
@molecule/api-notifications-webhook is a provider bond on the API (Node) side: it implements the notifications core interface (@molecule/api-notifications) with a concrete vendor or library behind it.
Your code calls the core; you wire this provider once at startup. Swapping vendors later is one line in that wiring, not a rewrite.
import { setProvider } from '@molecule/api-notifications'
import { provider } from '@molecule/api-notifications-webhook'
setProvider('webhook', provider)Works with: @molecule/api-notifications, @molecule/api-secrets
Secrets: NOTIFICATIONS_WEBHOOK_URL, NOTIFICATIONS_WEBHOOK_SECRET (optional)
Live demos
Running apps built with Molecule that install this package — open the app or study the template.
Reference
Webhook notifications provider for molecule.dev.
Sends notifications as HTTP POST requests with optional HMAC signing.
Auto-generated, AI-first package reference for the molecule.dev ecosystem. It is written to be read by coding agents as much as by people, and is generated from this package's source — edit
src/index.tsJSDoc, not this file.
Quick Start
import { setProvider } from '@molecule/api-notifications'
import { provider } from '@molecule/api-notifications-webhook'
setProvider('webhook', provider)
Type
provider
Installation
npm install @molecule/api-notifications-webhook @molecule/api-notifications @molecule/api-secrets
API
Interfaces
WebhookConfig
Configuration for the webhook notifications provider.
interface WebhookConfig {
/** The webhook URL to POST to. Defaults to NOTIFICATIONS_WEBHOOK_URL env var. */
url?: string
/** Optional HMAC secret for request signing. Defaults to NOTIFICATIONS_WEBHOOK_SECRET env var. */
secret?: string
/** Request timeout in milliseconds. Defaults to 10000. */
timeoutMs?: number
}
ProcessEnv
Environment variables consumed by the webhook notifications provider.
interface ProcessEnv {
NOTIFICATIONS_WEBHOOK_URL: string
NOTIFICATIONS_WEBHOOK_SECRET?: string
}
Functions
createProvider(config)
Creates a webhook notifications provider.
function createProvider(config?: WebhookConfig): NotificationsProvider
config— Optional configuration.
Returns: A NotificationsProvider that sends via HTTP webhook.
Constants
provider
The provider implementation.
const provider: NotificationsProvider
notificationsWebhookSecretDefinitions
Secret definitions required by the webhook notifications bond.
const notificationsWebhookSecretDefinitions: SecretDefinition[]
Core Interface
Implements @molecule/api-notifications interface.
Injection Notes
Requirements
Peer dependencies:
@molecule/api-notifications^1.0.1@molecule/api-secrets^1.0.1
Environment Variables
NOTIFICATIONS_WEBHOOK_URL(required) — Notification webhook URL- Setup: HTTPS endpoint that receives notification POSTs from your app.
- Example:
https://example.com/hooks/notify
NOTIFICATIONS_WEBHOOK_SECRET(optional) — Notification webhook signing secret- Auto-generated at scaffold — no manual setup.
Runtime Dependencies
@molecule/api-notifications@molecule/api-secrets
Wire format: the POST body is
{ subject, body, timestamp, metadata } — metadata is nested under its
own key (never spread at the top level), so a Notification.metadata
object can safely use keys like subject/body/timestamp without
colliding with the canonical envelope fields the receiver (and the HMAC
signature, when a secret is configured) depends on.
- Signature (when a secret is configured): the POST carries
X-Signature-256: sha256=<hex>where<hex>is the HMAC-SHA256 of the EXACT raw JSON body, keyed byNOTIFICATIONS_WEBHOOK_SECRET(orconfig.secret). Receivers must compute the HMAC over the raw request bytes BEFORE parsing (a re-serialized body will not match) and compare timing-safely. No secret → no header. send()never throws — it fails open. Missing URL, non-2xx, or timeout (default 10 s) resolve to{ success: false, error }; checkresult.successwhen delivery matters.- URL/secret/timeout are captured on first use (lazy) and frozen — env
changes after the first send require a restart or a fresh
createProvider()instance.
E2E Tests
Integration checklist — drive the real flow (no mocks), adapt each item to this app's actual events/triggers, and check every box off one by one. A box you can't check is an integration bug to fix — not a skip:
- Each ops/event trigger the app defines (service down, new signup,
a threshold crossed) actually calls
notifyAll()and the message reaches every bonded channel. The sandbox CAPTURES outbound notifications instead of sending — read them with theread_activitytool and confirm the subject+body match the event that fired. Never mock the flow or modify production code to expose it. - MULTI-CHANNEL: with >1 channel bonded,
notifyAll()returns oneNotificationResultper channel and a single channel failing (success: false) does not swallow the others — every other channel still captured, its own result stillsuccess: true. - The body carries the real event data (no
undefinedplaceholders) and nothing that must not leave the system — no secrets, tokens, or PII that an external channel (Slack/webhook) should never receive. - Triggers are not end-user SPAMMABLE — no public endpoint lets a caller fire unbounded notifications; the trigger is internal (an ops/system event) or rate-limited.