Briefing reply setup (Resend Inbound)

Admin switch-on for reply-to-the-briefing: Resend Inbound domain, MX record, webhook URL, and the BRIEFING_REPLY_DOMAIN / RESEND_INBOUND_SECRET variables.

Open in Jordyn:/admin

Briefing reply setup (Resend Inbound)

Users can reply to the morning briefing email — "done 1 and 3, push the rest to tomorrow, and have Jordyn draft the reply for the Banner email" — and Jordyn acts on it. All the code ships enabled-but-dormant: nothing changes until the two environment variables below are set. This page is the exact switch-on procedure.

How it works (30 seconds)

  • When BRIEFING_REPLY_DOMAIN is set, each briefing's Reply-To becomes a per-user address like briefing+<userId>.<hmac>@reply.jordyn.app. The HMAC token identifies the user; the From header is never trusted on its own.
  • Resend Inbound receives mail for that domain and POSTs the parsed email (svix-signed) to the webhook.
  • The webhook verifies the signature, strips the quoted original, interprets the reply against that user's current briefing items, executes only done/snooze (through the same code path as the email's one-tap links), and emails back a confirmation. Free-text asks ("draft the reply") are never executed from email — they become a to-do plus a one-tap "have Jordyn do it now" link in the confirmation.
  • Inbound is rate-limited to 20 replies per user per day.

Setup steps

  1. Resend dashboard: add the inbound domain. Resend dashboard, then Inbound (under Receiving), then Add domain. Use a dedicated subdomain: reply.jordyn.app. Do not use the sending domain itself — its MX records are already spoken for.

  2. Add the MX record at the DNS provider. The Resend dashboard shows the exact record after you add the domain. It is an MX record on reply.jordyn.app pointing at Resend's inbound host (currently shown in the dashboard as an inbound.resend.com-style host, priority 10). Copy the host and priority from the dashboard rather than from this page, and wait for the domain to show Verified.

  3. Add the webhook. Resend dashboard, then Webhooks, then Add webhook.

    • URL: https://jordyn.app/api/inbound/briefing
    • Event: the inbound "email received" event. Copy the webhook signing secret (starts with whsec_) — it is shown when the webhook is created.
  4. Set the environment variables in Vercel (Project, then Settings, then Environment Variables, Production):

    • BRIEFING_REPLY_DOMAIN = reply.jordyn.app
    • RESEND_INBOUND_SECRET = the whsec_... signing secret from step 3. Redeploy so the new variables take effect.
  5. Verify.

    • Trigger a briefing (or wait for the morning cron) and confirm the email's Reply-To is briefing+...@reply.jordyn.app and the footer shows the "just reply to this email" hint.
    • Reply "done 1" from the account's own inbox. Within a minute a confirmation email ("Got it — your briefing reply, handled") should arrive and the item should be done on the Today page.
    • A request to https://jordyn.app/api/inbound/briefing without the env vars set answers 503; with them set but without a valid svix signature it answers 401. Both are correct.

Rollback

Remove BRIEFING_REPLY_DOMAIN (or both variables) and redeploy. Briefings immediately revert to the old Reply-To (support@jordyn.app), the hint line disappears, and the webhook answers 503. No data changes are needed.

Notes and limits

  • The reply interpreter only ever marks items done or moves to-dos to tomorrow — the same two operations as the email's one-tap links, executed through the same function. It cannot delete, send, or edit anything.
  • If the From address doesn't match the account's profile email, the reply is still processed (people reply from aliases) but a warning is logged. The security boundary is the HMAC token in the To address plus the svix webhook signature, not the From header.
  • Replies that can't be matched to a current briefing item are answered honestly ("Couldn't match") and change nothing.

Related

Can’t find it? Ask the Guide — it answers from these same articles.