Skip to content

Quick Start

sarmakska edited this page May 31, 2026 · 2 revisions

Quick Start

git clone https://github.com/sarmakska/webhook-to-email.git
cd webhook-to-email
npm install
cp .env.example .env

Edit .env:

RESEND_API_KEY=re_...
NOTIFY_EMAIL=you@yourdomain.com

Run:

npm start

In another terminal, fire a test webhook:

curl -X POST http://localhost:3000/hooks/test \
  -H "Content-Type: application/json" \
  -d '{"hello": "world"}'

You get 202 {"ok":true,"queued":true,"subject":"Webhook: test"} immediately. The background worker delivers the email, and one titled "Webhook: test" arrives within a couple of seconds.

What you should see

  • Server logs on start: webhook-to-email listening on :3000, plus a line per enabled feature (HMAC, Slack, Telegram, retry queue, dead-letter inbox).
  • On a hit: [test] queued: Webhook: test.
  • 202 returned to the source immediately.
  • The email arrives once the worker delivers it.

Inspect queue and failures

curl http://localhost:3000/            # { ok, service, uptime, queueDepth, deadLetters }
curl http://localhost:3000/dead-letter # recent delivery failures

Add a real webhook source

For Stripe:

  1. Stripe dashboard, Developers, Webhooks, Add endpoint.
  2. URL https://your-domain.com/hooks/stripe.
  3. Copy the signing secret, set it as WEBHOOK_SECRET in .env.
  4. The bundled src/templates/stripe.js formats invoice.paid and customer.subscription.created.

For GitHub:

  1. Repo, Settings, Webhooks, Add.
  2. URL https://your-domain.com/hooks/github, content type application/json, secret set to your WEBHOOK_SECRET.
  3. Choose the events you want.

See HMAC-Verification for every provider and Per-Source-Templates for formatting.

Add fan-out

SLACK_WEBHOOK_URL=https://hooks.slack.com/services/T.../B.../...
TELEGRAM_BOT_TOKEN=123456:ABC-DEF...
TELEGRAM_CHAT_ID=123456789

Restart, and every delivered event is also posted to Slack and Telegram. See Fan-Out.

Send a signed test

WEBHOOK_SECRET=your-secret ./examples/curl-test.sh

The script computes a valid X-Signature header so the request passes verification.

If something breaks

Problem Fix
RESEND_API_KEY and NOTIFY_EMAIL must be set Edit .env
401 on webhook calls Wrong WEBHOOK_SECRET, missing signature, or wrong source path
202 but no email Check GET /dead-letter; the failure and its error are listed there
Slack or Telegram missing Fan-out is best effort; check the stdout warning and the credentials
Jobs piling in dead-letter Read the error field; usually an invalid key or unverified sender

Clone this wiki locally