← Back to feature backlog

πŸ“¨ 7-day Adoption Flow + Newsletter Engine

Two features sharing one engine. Adoption: the automated 7-day flow that walks new clients to their first project, brand profile, and content delivery β€” replacing manual phone chasing. Newsletter: the same drip engine repurposed for monthly newsletters and one-shot blasts. Both run on SendGrid + Twilio under the hood.

Wave 2 · 🟑 Next · STAFF Replaces ActiveCampaign + manual chase F-044 · F-045 · F-241
The goal

Stop calling new clients to chase adoption. Stop emailing 1,000 people manually.

Adoption is the highest-leverage moment in a client's life with us. Today we manually call them to push: submit your first project, complete your brand profile, watch the wizard, react to the first content. The new flow runs all of that automatically through email + SMS, stops nudging on each milestone hit, and frees up the team. Same engine repurposed: super admins fire one-shot blasts; product managers schedule drip newsletters. ActiveCampaign-style flow editor without ActiveCampaign's price tag.

+ adoption rate
Realtors who hit all 4 milestones in week 1 churn 3Γ— less. Automation gets more across the line.
βˆ’manual chase hours
Free the success team from "did you finish your brand profile?" calls.
βˆ’$200/mo SaaS
Cut ActiveCampaign / Mailchimp subscriptions. SendGrid covers it.
+ super-admin blasts
One-shot announcements (downtime, new feature) blast in 30 seconds, no engineering ticket.
Adoption flow editor Β· F-044

The 7-day flow as visible nodes β€” staff can see + tune it

Each node is an action: send email, send SMS, or wait. Branches based on milestone state ("if brand profile complete, skip step 3"). Visible to the success team so they know exactly what's been sent. Editable so we can tune messaging without an engineer.

staff.socialrealtr.com/flows/adoption-7-day
7-Day Adoption Flow
Triggers on new client signup Β· Currently active for 87 clients
⚑

Trigger Β· New client signup

Fires when Stripe checkout completes + password is set
↓
↓
⏱

Wait 1 hour

Give them time to read the welcome before nudging
↓
πŸ“±

SMS Β· Brand Profile prompt (if not complete)

"Hey Sarah β€” quick 3-min step that makes everything else work β†’" Β· 51% click rate
↓
⏱

Wait 24 hours

Branch Β· check milestone state
↓
↓
πŸ“±

SMS Β· "Submit your first project" prompt

If no project submitted by day 3 Β· 38% reply rate
↓
↓
βœ…

End Β· Move to "Active" segment

Adoption flow stops Β· regular notification preferences take over
1
2
3
4
5
1Trigger node = Stripe + password. Flow doesn't fire on Stripe alone β€” only when the password is set (the realtor has actually entered the platform). Reduces sending welcomes to people who never log in.
2Open rates inline. Every node shows performance metric (open rate, click rate, reply rate). Staff sees what's working; nodes get tuned without engineering.
3Email + SMS in the same flow (F-044). Staff visualizes both surfaces. SMS for the can't-miss moments (brand profile prompt), email for the longer ones. Realtor opt-out per channel.
4State-aware branches. "If brand profile complete by hour 25, skip the day-2 brand profile email." Smarter than dumb drip; doesn't pester clients who already finished.
5Graduate to "Active" segment. Once they finish the 7-day flow, regular notification preferences (F-120) take over. The adoption flow has a beginning AND an end β€” not a perpetual nag.
Per-client adoption progress Β· staff view

How adoption looks per individual client

When a CC opens a client's profile, this widget shows where the client is in adoption. Replaces the "manually call them to ask" workflow. CC sees what's been sent, what's pending, and what milestone is stuck.

πŸ“Š Sarah Konja Β· Day 4 of 7

βœ“
Account created + password set
Day 0 Β· Mar 14
βœ“
Welcome email opened
Day 0 Β· 14 min after signup
βœ“
Brand Profile completed
Day 1 Β· 6 of 6 sections
βœ“
First content delivered
Day 2 Β· "Welcome to Surrey" post
5
Submit first project (in progress)
SMS sent yesterday Β· awaiting
6
Watch guided wizard
Pending
7
Day 7 check-in
Scheduled May 14

πŸ“’ Send a blast

Super admin? Push a one-shot announcement to all clients (or a segment) β€” downtime notice, new feature, holiday schedule. Plugs into the same SendGrid + Twilio rails as the adoption flow.

πŸ“œ Recent blasts

"Local Leader is live"
Sent April 28 Β· by Mary
1,247
SENT
68%
OPEN
14%
CLICK
"Scheduled maintenance Sunday 2am"
Sent April 20 Β· by Trent
1,238
SENT
71%
OPEN
2%
CLICK
Blast composer Β· F-241

Compose a one-shot blast β€” segment + write + preview + send

When a manager or super admin clicks "Compose new blast," this is the page. Subject + audience selector with live count + body editor + email preview pane. Send-now or schedule for later. Track who fired it for audit. Everything plugs into the same SendGrid + Twilio rails as the adoption flow β€” no new infrastructure.

staff.socialrealtr.com/newsletter/compose
πŸ“’ NEW BLAST
Compose a blast
🎯 AUDIENCE
All clients Top Producer only Rising Star only Rookie only + My book (CC view) + Custom segment
1,247
active clients will receive this
β†’ ~870 email opens Β· ~175 SMS reads (estimated)
πŸ“¨ SUBJECT LINE
52 chars Β· βœ“ good for inbox preview πŸ“ˆ Predicted open rate: 68%
✍ BODY
Variables available: {{ first_name }} Β· {{ plan }} Β· {{ city }} Β· {{ assigned_cc }}
⏰ SEND TIMING
β€” or β€” in client's local timezone
⚑ LIVE EMAIL PREVIEW
From: Trent Β· Social Realtr 9:00 AM
To: sarah@konjarealty.com
Reels are now live β€” record + post in 60 seconds
Hey Sarah β€”

You can now record reels straight from the platform. Open Script Generator β†’ Teleprompter β†’ Record. 60 seconds, you've got a finished video, scheduled across IG / TikTok / YouTube.

Trent walks through it in this 90-second tour:
Watch the tour β†’

Try it on your next listing this week. Reply to this email if you hit any snags β€” I'll help.

β€” Trent + the team
You're receiving this because you're an active Social Realtr client. Notification preferences Β· Unsubscribe from product updates
βœ“ Compliance check passed. Unsubscribe link present. Sender identified. Body under 5K chars. No spammy phrases detected. Safe to send.
πŸ“Š Predicted performance (based on past blasts of similar audience + length):
πŸ“§ Open rate: ~68% Β· πŸ“± Click rate: ~14% Β· ⏱ Estimated send time: ~3 min for all 1,247
1
2
3
4
5
14 send actions in the top bar. Save draft (preserve work) Β· Preview (open in new tab) Β· Schedule (gradient β€” premium action) Β· Send now (black β€” primary). Hierarchy via background, not size.
2Audience picker with live count. Pill segments (All / Top Producer / Rising Star / Rookie / My book / Custom). Big number 1,247 updates as they pick. Channel toggles below β€” SMS shows "175 eligible" because TCPA opt-in is respected.
3Subject + open-rate prediction. Inline character count + inbox-preview check + AI-predicted open rate based on past blasts. Encourages tight subject lines without nagging.
4Body editor with variables + AI assist. Standard rich-text toolbar + variables ({{ first_name }} etc) + ✨ Write with AI for first-draft generation. Same Anthropic Claude API as the rest of the platform.
5Live email preview pane. Renders exactly what the recipient sees β€” name substituted in, formatted body, footer with unsubscribe. Updates as they type. Compliance check + predicted performance below close the loop.
πŸ›  BUILD PATH FOR OTTO

Wiring this up with SendGrid + Claude Code

The whole engine β€” adoption flow + blast composer + drip newsletter β€” rides on three pillars: SendGrid for delivery (already wired in your stack via sr_close_api_key pattern), a WP REST layer for state + audience filtering, and a 5-minute cron running the drip state machine. Otto builds it with Claude Code in 5 phases. Total estimated: 12–18 hours for a clean v1.

PHASE 1 Β· ~2 hr

Data model (Plan mode)

Use Claude Code's Plan mode (Shift+Tab) BEFORE writing PHP. Get the schemas right or you re-migrate three times.

sr_blast (CPT) β€” drafts + sent
sr_blast_event β€” SG webhook events
sr_drip_flow β€” flow definitions
sr_drip_step β€” individual nodes
sr_drip_run β€” per-client state
sr_audience_segment β€” saved filters
Prompt for Claude: "Plan the WP CPT schema for an email blast + drip system. Each blast needs: subject, body_html, audience filter, channels, status, scheduled_at, sent_at, stats. Each drip flow has steps with delays + branching. Show me the schema before writing code."
PHASE 2 Β· ~1 hr

SendGrid wrapper class

Single PHP class that wraps the v3 API. Every other piece of the system calls this β€” never SendGrid directly.

SR_SendGrid::sendTransactional()
SR_SendGrid::sendBlast()
SR_SendGrid::scheduleSingleSend()
SR_SendGrid::addContact()
SR_SendGrid::handleWebhook()
Critical: use SendGrid Dynamic Templates for variable substitution, NOT PHP string replacement. Each template has handlebars vars ({{ first_name }}). Better deliverability + no XSS risk.
PHASE 3 Β· ~3 hr

WP REST endpoints

5 endpoints. All gated by capability check (super-admin or manager-of-segment).

POST /wp-json/sr/v1/blast/send
POST /wp-json/sr/v1/blast/schedule
GET  /wp-json/sr/v1/blast/{id}/stats
POST /wp-json/sr/v1/audience/count
POST /wp-json/sr/v1/sendgrid/webhook
Prompt for Claude: "Generate a WordPress REST endpoint that accepts {subject, body_html, template_id, audience_filter, channels, scheduled_at} and forwards to my SR_SendGrid wrapper. Validate caller has 'edit_others_posts' capability. Return job_id + estimated send count."
PHASE 4 Β· ~4 hr

Drip engine (the state machine)

WP cron runs every 5 min. Reads sr_drip_run records ready to advance.

1. SELECT runs WHERE next_at <= NOW()
2. For each: load current step
3. Check skip conditions (state-aware)
4. Execute action (send email/SMS/wait)
5. Advance to next step
6. Update next_at + log event
Prompt for Claude: "Build a WP cron callback that runs every 5 min. Reads sr_drip_run records ready to advance. Loads the current sr_drip_step. Skips if state-aware condition is met (e.g. 'brand_profile_complete = true'). Otherwise calls the step's action. Idempotent β€” safe to run twice."
PHASE 5 Β· ~3 hr

Composer UI + flow editor

WP page templates rendering this mockup's HTML. JS posts to the REST endpoints from Phase 3. Audience picker fires POST /audience/count on every segment change for the live count.

Composer (this mockup's surface 3):
β€’ Audience picker + live count via REST
β€’ Subject + char counter + open-rate predictor
β€’ Body editor (use TinyMCE or wp_editor)
β€’ Live email preview iframe
β€’ Send-now / schedule actions
Flow editor (surface 1):
β€’ Vertical node list (linear v1)
β€’ Drag-drop ordering (later)
β€’ Each node = email/SMS/wait + skip-condition
β€’ Performance metrics inline (open rate, etc.)
β€’ Edit / preview / pause buttons per node
⚑ CRITICAL SENDGRID DECISIONS
Use 2 SendGrid subusers β€” one for transactional (project ready, password reset), one for marketing (blasts, drip). Bad marketing bounces never harm transactional deliverability. Industry standard.
Dynamic Templates not inline HTML β€” store templates in SendGrid; reference by ID. Edit copy without redeploying. Variables via handlebars.
Webhook for events β€” open / click / bounce / unsubscribe / spam-report all post to /wp-json/sr/v1/sendgrid/webhook. Stats tracked per blast.
Suppression list = source of truth β€” don't try to maintain unsubscribe state in WP. SendGrid's suppression list filters automatically. Check it via API for the audience-count predictor.
Send rate limits β€” SendGrid Pro tier: ~100K/day. Batch sends in chunks of 1,000. Don't loop one-by-one β€” use the v3 batch endpoint or Marketing Campaigns Single Sends.
Plain-text fallback required β€” every email needs a text/plain alternative for spam-filter compliance. SendGrid Dynamic Templates handle this if you provide both versions.
πŸ’‘ CLAUDE CODE WORKFLOW TIP FOR OTTO

Open Claude Code in the plugin/theme directory. Paste this entire mockup's URL + the F-241 backlog card description. Then walk through phases 1–5 sequentially with Plan mode. Don't skip Plan mode for the data model β€” it's where rework happens. Have Claude generate one phase end-to-end (CPTs + REST + UI) before moving to the next. Test with a 5-person internal audience first; flip to all clients once confident.

Open questions for Trent