Missing Feature: Backlink Outreach Reply Tracking
Priority: 🟡 Nice-to-have (post-launch) Area: SEO / Backlinks / Outreach
What Exists
- Outreach emails are drafted by the
backlink-writeragent, edited in the DM portal (/seo/link-building/[id]), and sent via Resend through the notification infrastructure. - The
CampaignEmailmodel recordsstatus(draft/approved/sent) andsentAt. - The
Backlinkmodel tracksoutreachStatus(prospecting → outreach_sent → responded → agreed → published) and timestamps per stage. - DMs manually advance the status via the backlink detail page when they receive a reply.
What’s Missing
1. Automated Reply Detection
When a prospect replies to an outreach email, there is currently no mechanism to automatically detect it. The DM has to:
- Check their inbox manually.
- Come back to the backlink detail page.
- Manually change
outreachStatustorespondedand paste the reply content into Notes.
2. Reply Content Storage
There is no BacklinkReply model. Reply subject, body, sender, and timestamp have nowhere to live. The timeline on the detail page shows “Responded” as a status but no reply text.
3. No-Response Follow-up Tracking
There is no way to flag a prospect as no_response automatically after N days without a reply.
Implementation Options
Option A — Resend Webhook (Recommended, Lowest Effort)
Resend fires webhook events for email.replied (when a reply comes in to a Resend-tracked thread).
What to build:
POST /webhook/resendroute in the Fastify API (verify Resend signature).- On
email.repliedevent: look up theCampaignEmailbymessageId(store Resend’s message ID on send), advanceBacklink.outreachStatustoresponded, setrespondedAt, create aBacklinkReplyrecord. - New
BacklinkReplymodel:{ id, backlinkId, campaignEmailId, from, subject, body, receivedAt }. - Reply thread card on the backlink detail page (both DM and dashboard portals).
Limitation: Only works for replies that come back to the Resend-tracked thread (i.e., if the prospect replies to the exact sent address). Does not work if the DM uses a personal inbox.
Effort: ~1 day.
Option B — Gmail / Outlook Polling
A scheduled BullMQ job polls a connected Gmail/Outlook account for replies matching sent subjects.
What to build:
- OAuth flow per DM user (Google/Microsoft).
ConnectedMailboxmodel storing refresh tokens.email-reply-pollerBullMQ worker (runs every 15 min per connected mailbox).- Thread-matching logic: match by
In-Reply-Toor subject prefix. - Same
BacklinkReplymodel + detail page display.
Effort: ~3–4 days. Requires OAuth setup per email provider.
Option C — Forward-to-Inbox (Cheapest Hack)
DM forwards replies to a dedicated replies@leadmetrics.ai address. A webhook parser (e.g., Cloudmailin, Postmark inbound) parses them and routes to the right backlink by matching a unique tag in the reply subject/footer.
Effort: ~2 days. Requires a dedicated inbound email address.
Auto No-Response Flagging
Regardless of which option above is chosen, a separate backlink-followup-checker BullMQ cron job (daily) should:
- Find all backlinks with
outreachStatus = "outreach_sent"andoutreachSentAt < now - 14 days. - Mark them
no_response. - Optionally notify the DM.
Effort: ~2 hours once the status model is in place.
Related Files
packages/db/prisma/schema.prisma— AddBacklinkReplymodel; addmessageIdfield onCampaignEmail.apps/api/src/routers/— New webhook route + reply router.apps/dm/src/app/(dm)/seo/backlinks/[id]/BacklinkDetailDMClient.tsx— Reply thread card.apps/dashboard/src/app/(dashboard)/seo/backlinks/[id]/BacklinkDetailClient.tsx— Read-only reply view for clients.packages/agents/src/workers/—backlink-followup-checker.worker.ts.