Manual mode is useful locally but blocks customer beta.
Make marketplace notifications automatic before beta.
One operator surface for login codes, order updates, disputes, saved-search alerts, message notifications, provider verification, and retry scheduling.
Delivery Gate
Checking notification provider handoff mode.
Configure webhook, Resend Email, Cloudflare Email, or WhatsApp Cloud with real credentials.
Set a long cron token and schedule `/api/notifications/due`.
Choose Provider
Pick the fastest real path. Webhook is usually the shortest bridge; Resend avoids the Cloudflare Email beta blocker; WhatsApp Cloud is cleaner once Meta templates are approved.
Webhook relay
Use a Make, Zapier, Worker, or custom HTTPS endpoint that receives ClearLah events and sends WhatsApp, SMS, or email.
WhatsApp Cloud
Use the Meta phone number ID, production access token, login template, and business notification template/default map.
Resend Email
Use a verified Resend domain and API key for Google and email-first beta users while Cloudflare Email remains unavailable.
Cloudflare Email
Use Email Service sending with the Pages Functions EMAIL binding for Google and email-first beta users.
Due retry schedule
Queued and failed notifications are not automatic until a scheduler calls the token-protected due endpoint every few minutes.
Copy Commands
Run one provider setup path, verify it, then rerun strict notification and customer beta gates.
Webhook setup
Writes production-style local env and a masked Cloudflare handoff.
npm run configure:notifications -- --mode=webhook --webhook-url=https://notify.your-domain.sg/clearlah --webhook-token=<long-random-provider-token-at-least-24-chars> --cron-token=<long-random-cron-token-at-least-24-chars> --write
Verify webhook
Sends a synthetic ClearLah notification payload to the configured endpoint.
npm run ops:verify-notification-webhook -- --from-env
WhatsApp setup
Use only approved production templates. Keep token values out of git.
npm run configure:notifications -- --mode=whatsapp_cloud --graph-version=v24.0 --phone-number-id=<numeric-meta-phone-number-id> --access-token=<meta-whatsapp-cloud-access-token> --auth-template=clearlah_login_code --template-language=en_US --template-default=clearlah_notification --template-map='{}' --cron-token=<long-random-cron-token-at-least-24-chars> --write
Resend setup
Verify the domain in Resend first. Keep the API key out of git.
npm run configure:notifications -- --mode=resend_email --resend-api-key=<resend-api-key-starting-with-re_> --email-from=notifications@sgsecondhand.com --email-from-name=ClearLah --email-reply-to=support@sgsecondhand.com --cron-token=<long-random-cron-token-at-least-24-chars> --write
Email setup
Enable Cloudflare Email Service sending first. This also writes the EMAIL binding to Wrangler.
npm run configure:notifications -- --mode=cloudflare_email --email-from=notifications@sgsecondhand.com --email-from-name=ClearLah --email-reply-to=support@sgsecondhand.com --cron-token=<long-random-cron-token-at-least-24-chars> --write
Cloudflare secrets
Use the masked handoff output, then add real values through Wrangler or the dashboard.
npx wrangler pages secret put CLEARLAH_NOTIFICATION_MODE --project-name clearlah npx wrangler pages secret put CLEARLAH_NOTIFICATION_CRON_TOKEN --project-name clearlah npx wrangler pages secret put CLEARLAH_NOTIFICATION_WEBHOOK_URL --project-name clearlah npx wrangler pages secret put CLEARLAH_NOTIFICATION_WEBHOOK_TOKEN --project-name clearlah npx wrangler pages secret put CLEARLAH_RESEND_API_KEY --project-name clearlah npx wrangler pages secret put CLEARLAH_EMAIL_FROM --project-name clearlah npx wrangler pages secret put CLEARLAH_EMAIL_FROM_NAME --project-name clearlah npx wrangler pages secret put CLEARLAH_EMAIL_REPLY_TO --project-name clearlah
Due retry schedule
Configure this with your scheduler after the cron token is set in production.
curl -X POST https://clearlah.pages.dev/api/notifications/due \
-H "content-type: application/json" \
-H "x-clearlah-notification-cron-token: $CLEARLAH_NOTIFICATION_CRON_TOKEN" \
--data '{"limit":25}'
Strict notification gate
Fails in manual mode. Passes only with real provider values and retry token.
npm run ops:notifications -- --strict
Provider smoke
Local checks for provider setup, due endpoint, templates, and webhook verifier.
npm run test:configure-notifications npm run test:notification-readiness npm run test:notification-due npm run test:notification-webhook npm run test:notification-templates
Strict package
Only package strict after inventory and notifications are ready.
npm run package:pages:strict
Customer beta gate
Rechecks inventory, notifications, package, deployment evidence, and transactions.
npm run check:customer-beta
Operator Links
Use these with the provider setup so queued messages can be reviewed, chased, and proven.
Delivery Guardrails
These keep customer beta from depending on a founder manually chasing every message.
`CLEARLAH_NOTIFICATION_MODE=manual` must not clear customer beta or production traffic.
Tokens, access tokens, webhook secrets, and cron tokens belong in `.env.local` and Cloudflare secrets only.
Cloudflare Email mode must include `[[send_email]] name = "EMAIL"` in Wrangler before strict readiness passes.
Resend Email mode requires a verified sending domain, real API key, and sender address before customer traffic.
WhatsApp Cloud messages need approved login and business notification templates before customer traffic.
Automatic delivery includes the due retry scheduler, not only provider configuration.