Product Block 07 · Sellable today
SMS Reactivation Agent
Customers who haven't booked in N days get a personal text. The agent handles the reply thread.
Best fit: Salons, gyms, restaurants, dental, primary care, MedSpa — any business with a customer database and a recurring-visit cadence.
SMS Reactivation Agent — build it without writing code
Drop the prompt below into Claude Code or Codex. The agent picks a salon/MedSpa/dental prospect with a stale customer DB, builds the segmentation + personalized message generator + Twilio reply handler with TCPA opt-out, generates 3 sample messages for THEIR actual stale customers as the cold-pitch artifact.
You provide
You provide: (1) a salon/MedSpa/dental prospect with public reviews showing stale-customer pattern, (2) decision-maker email, (3) sample customer data (CSV export OR fake but realistic synthetic data the human creates).
You get back
You get: a working segmentation + message gen + reply handler deployed on a Twilio number, 3 sample personalized messages addressed to anonymized stale customers from THEIR DB, a 60-second Loom of receive→reply→book, and a draft cold pitch.
Runtime & cost
Roughly 75 minutes wall-clock. ~$1-2 in Claude tokens + Twilio test number cost.
You are building an SMS Reactivation Agent (Block 07 in the Cafecito AI new-hire playbook). Full reference at https://cafecito-ai.com/new-hire/blocks/07-sms-reactivation-agent. Read it. Use plan mode. Stop at every [GATE].
INPUTS YOU NEED FROM THE HUMAN (ask before doing anything else):
1. Prospect (salon / MedSpa / dental / fitness / restaurant — must have customer LTV >= $300)
2. Decision-maker email
3. Customer data — either (a) CSV export with name + phone + last_visit_at + last_service + technician, OR (b) human creates 20 rows of realistic synthetic data matching the prospect's services
ENVIRONMENT (verify):
- Working dir: /home/eratner/cafecito-ai
- Cloudflare account: f7a9b24f679e1d3952921ee5e72e677e
- Twilio cafecito-ai sub-account access (the human gives you SID + Token)
SECRETS TO CONFIRM:
- ANTHROPIC_API_KEY
- TWILIO_SID, TWILIO_TOKEN
- (Cal.com: optional — defer to manual booking link in week 1)
THE PLAN:
STEP 1 — RESEARCH + DATA (15 min)
- Pull prospect website. Identify primary services (3-5), staff names if listed, brand color, owner first name.
- Wait for human to provide customer CSV or 20 rows of synthetic data.
- Pre-qualify the data: must have >= 10 customers with last_visit_at older than 60 days.
[GATE 1 — show data shape + segmentation preview, ask "proceed?"]
STEP 2 — SCAFFOLD WORKER (15 min)
- Create /home/eratner/cafecito-ai/sms-reactivation-<prospect-slug>/.
- Use Prompt #1 from the block page ("Customer-segmentation query") for the D1 schema + segmentation SQL.
- Use Prompt #2 ("Personalized message generator") for the per-customer message logic.
- Use Prompt #3 ("Reply handler with Cal.com booking") for inbound webhook handling.
- Bindings: D1 SMS_DB, KV opt_out_list, secrets above.
- TCPA opt-out logic MUST be implemented before any test send (STOP / UNSUBSCRIBE / QUIT / CANCEL → immediate confirmation reply within 2 min).
[GATE 2 — show worker.js + opt-out flow tested with a fake STOP, ask "deploy?"]
STEP 3 — DEPLOY + TWILIO PROVISION (10 min)
- Apply D1 migration. Deploy via OAuth wrangler.
- Provision a Twilio number (Miami area code 305/786/954). Set SMS webhook to the worker /sms-webhook.
- Test send to YOUR phone with a fake customer row. Reply STOP → confirm within 2 min.
[GATE 3 — confirm Twilio + opt-out work, ask "ready to generate sample messages?"]
STEP 4 — GENERATE 3 SAMPLE MESSAGES (10 min)
- Pick 3 customers from the data with the highest LTV among the 60+ day inactive segment.
- Run each through the message generator. Capture: customer initials, last service, last technician, generated SMS, tone chosen, confidence.
- Anonymize: first name initial only, no full last name. Phone numbers redacted.
- Build a small one-page report (HTML or markdown) showing the 3 samples side by side.
[GATE 4 — show the 3 sample messages, ask the human "would these be in their voice?"]
STEP 5 — RECORD THE LOOM (5 min, human action)
- Tell human: "Open the message gen UI. Generate one message for one customer. Send to YOUR phone. Reply YES. Show the AI booking the slot. Save the URL."
STEP 6 — DRAFT THE COLD PITCH (5 min)
- Email subject: "I generated outreach for 3 of your stale customers. Tell me if these would work."
- Email body: 4 sentences, lead with the % of stale customers in their DB (estimated), attach the 3-sample report, name $1.5k setup / $300/mo + SMS pass-through, one yes/no close.
[GATE 5 — show the draft, ask the human to send manually]
STEP 7 — SHIP THE SUMMARY
- Single-line: "[BUSINESS] reactivation agent live · 3 sample messages: [URL] · pitch sent to [EMAIL]."
DONE.
GUARDRAILS: NEVER send a real outbound to a real customer during testing — only to YOUR phone. TCPA opt-out compliance is MANDATORY before any test send. Cost ceiling: $5 in Twilio + Claude.
01Stack▾
- CF Worker
- D1
- Twilio (SMS)
- Claude
- CF Cron Triggers
03Day-1 plan▾
A real prospect. A real demo. A real outbound message — all before 5pm.
-
09:00–09:30
Pick a high-LTV business with a stale customer DB.
Hair salon, MedSpa, dental practice, fitness studio. Pick one where average customer LTV is $500+ and you can credibly say "you have hundreds of customers who haven't booked in 90 days."
-
09:30–10:30
Get sample data (or scrape Mindbody/Boulevard if accessible).
Best case: they share an export. Realistic: build the demo with synthetic data that matches the shape they'd have.
-
10:30–11:30
Build the segmentation query.
D1 query: customers where last_visit_at < (today - 60 days) AND has_phone = true AND opted_out = false AND total_visits >= 2. The 2-visit minimum filters one-time customers.
-
11:30–12:30
Build the message generator.
For each customer: pull last service + last technician + last visit date. Generate a one-line SMS in the owner's tone: "Hey [name], it's been a while since we did your [service] — we've got Tuesday + Friday open this week. — [Owner first name]".
-
12:30–13:30
Wire Twilio + the cron.
Cron: Mon-Wed-Fri at 11am ET. Per-cron: pull next 20 customers from queue, generate personalized message, send via Twilio. Throttle. Log every send.
-
13:30–14:30
Build the reply handler.
Twilio webhook → CF Worker. Claude reads inbound + customer history + original outbound. Three outcomes: (1) clear booking → reply with Cal.com link, (2) question → reply naturally, (3) ambiguous/angry/unsubscribe → escalate to human inbox.
-
14:30–15:30
Build the opt-out + compliance flow.
STOP/UNSUBSCRIBE/QUIT/CANCEL detected → immediate confirmation reply ("Got it, you're unsubscribed. Reply START to opt back in.") + flag in D1 + remove from all future queues. Required by TCPA.
-
15:30–16:30
Send 5 test messages to yourself + 2 friends.
Test the full flow: receive → see personalization → reply YES → get Cal.com link → reply something off-topic → see natural response → reply STOP → confirm opt-out.
-
16:30–17:00
Send the cold pitch with sample messages.
Email the owner. Attach 3 sample messages your system would send to 3 of THEIR actual customers (anonymized initials). Subject: "I generated outreach for 3 of your stale customers."
04Best practices & gotchas▾
-
Always sign with the owner's actual first name. Never "the team."
Why: Customers respond to a name, not an org. "From the Bella Salon team" has 3-5x lower reply rate than "From Maria at Bella." Customers know it's automated; they engage anyway when it feels personally addressed.
-
Reference the last service or visit explicitly.
Why: "Hey, we miss you" is a coupon mailer. "Hey, it's been 9 weeks since your highlights with Carla" is a friend texting. The specificity is the entire reactivation lever.
-
Tuesday or Wednesday at 11am ET. No exceptions.
Why: SMS engagement peaks mid-morning, mid-week. Friday afternoon = ignored. Saturday = reads as desperate. Monday = needy. Tuesday/Wednesday 11am = intentional.
-
TCPA opt-out compliance is non-negotiable. Build it first, not last.
Why: STOP/UNSUBSCRIBE/QUIT/CANCEL must trigger immediate opt-out + confirmation reply within 2 minutes. Carrier penalties for non-compliance are $500-$1500 per message. No exceptions.
-
Max 1 outbound + 3 reply turns then human handoff.
Why: AI texting feels great for 4 turns and uncanny by turn 6. Cap the conversation. Handoff to a human-staffed inbox at turn 4 or any sign of complexity.
-
A/B test message tone (warm / casual / urgent) per customer segment.
Why: 60-day-stale responds best to warm. 180-day-stale responds best to direct ("we're running a slot Friday — last chance"). Loyal-but-busy responds best to casual. Track reply rate by tone × segment.
-
The booking link is a single tap, not a form.
Why: A reply of "yes" should land them in a Cal.com page already pre-filled with their name + last service. Two taps to book. Friction at booking kills the reactivation.
05Prompts (copy-paste)▾
Drop these into Claude Code. Replace the [BRACKETED] fields with the prospect's details.
Generates the SQL/D1 query that picks the right customers to message in a given week.
Generate a D1 SQL query for the SMS reactivation agent at [BUSINESS NAME].
Schema:
- customers: id, first_name, last_name, phone, opted_out, total_visits, last_visit_at, lifetime_value
- visits: id, customer_id, service, technician, visit_date, total
- outreach_log: id, customer_id, sent_at, message, response_at, response, outcome
Query requirements:
- Last visit between [N1] and [N2] days ago (warm 30-60d, mid 60-120d, cold 120-180d).
- total_visits >= 2.
- opted_out = false.
- No outreach sent in last [M] days (cooldown, default 30).
- Has non-null phone.
- Order by lifetime_value DESC.
- LIMIT 20.
Also output the cron-driver function: takes the query, sends each customer to message generator, sends via Twilio, logs to outreach_log. Throttle 1/sec.
Output: SQL + cron function in ESM JS.
The Claude prompt that crafts each SMS based on customer history + owner voice.
Generate a personalized reactivation SMS for [BUSINESS NAME].
Customer:
- First name: [name]
- Last service: [service]
- Last technician/provider: [name]
- Days since last visit: [N]
- Total visits: [N]
- Lifetime value: $[N]
Business:
- Owner first name: [name]
- Tone: [warm / casual / direct]
- Available slots: [pull from Cal.com or static]
- Booking link: [Cal.com URL pre-filled]
Constraints:
- Single SMS, MAX 160 characters.
- Sign with owner first name + business first letter (e.g. "— Maria, B.")
- Reference specific last service AND last technician.
- Suggest a specific window ("Tuesday or Friday").
- No emojis. No "miss you." No "valued customer." No exclamation points.
- Include the Cal.com link only if 160 chars allow.
Output: full message text + tone (warm/casual/direct) + confidence (high/medium/low) on personalization data.
The Claude prompt that handles inbound replies — book, converse, or escalate.
Handle this inbound SMS reply for [BUSINESS NAME].
History:
- Outbound message: [original SMS]
- Reply #[N] in thread (max 4 before human handoff).
- Customer name: [first name]
- Last service: [service]
- Booking link: [Cal.com URL]
Inbound: [reply text]
Classify and respond:
1. **Clear booking** ("yes," "Tuesday works") → "Great, [first name] — here's the link to grab Tuesday at [time]: [URL]. Take 30 seconds."
2. **Easy question** ("how much," "weekend slots") → answer in one SMS, propose a slot, include link.
3. **Complex question** (medical/dental/billing) → "Got it — [Owner first] will follow up directly today. What's the best window?"
4. **Negative** ("no thanks") → respect immediately. "All good, [first name] — we'll stop. Reply YES anytime."
5. **STOP / UNSUBSCRIBE / QUIT / CANCEL** → immediately fire opt-out workflow. Reply: "Got it, you're unsubscribed. Reply START to opt back in."
6. **Ambiguous** → ask one clarifying question. If reply count at 3, escalate.
7. **At reply #4** (regardless) → "Let me get [Owner first] in here directly — sec." + escalation flag.
Output JSON:
{
"category": "...",
"reply_text": "...",
"escalate_to_human": true|false,
"escalation_reason": "...",
"include_booking_link": true|false,
"log_outcome": "booked|conversation_continuing|negative|opted_out|escalated"
}
The Friday recap email showing the owner what the agent did all week.
Generate the weekly performance digest email sent to [OWNER NAME] at [BUSINESS NAME] every Friday at 4pm.
Inputs:
- N customers messaged this week
- N replies received (split by category)
- N bookings closed
- $ revenue from re-bookings
- N escalations awaiting owner response
- Comparison vs last week + 4-week average
Structure:
- Subject: "[BUSINESS] · Reactivation week of [date]: $[revenue] from [N] re-bookings"
- Top: headline number (revenue) + cost ($300 + SMS this week).
- Stats grid: 4 KPIs side by side.
- Highlight box: BEST reactivation of the week ("Sarah J., last visit Aug 2025, booked highlights for Friday — $145").
- Action items: list of escalations awaiting owner reply.
- Mini-recommendation: one tone or timing change to test next week.
- Footer: "Reply with questions or schedule a 15-min review: [Cal.com]."
Tone: factual, mildly conversational. Owner should look forward to this email.
Output: complete HTML email template.
06Selling script▾
Discovery question (ask this first)
"What percentage of your customers from a year ago are still booking with you? When was the last time you reached out to one of them personally?"
The frame
Acquisition costs in Miami SMB services run $150-$300 per new customer. Reactivation costs $0.01 per SMS. The economics aren't close — yet most owners spend on Instagram ads and let their customer database go stale. The one-text-per-week pattern recovers more revenue than any acquisition channel.
The demo play
On the discovery call: hand them three sample messages your system generated for three of THEIR actual stale customers. Watch them read. Their first words tell you whether the personalization landed. The pitch is over the moment they say "this sounds like me."
Objections
-
"Customers will find it annoying."
"One personalized text from 'Maria at Bella' on a Tuesday morning isn't annoying. Six generic blasts from 'The Bella Salon Team' on Friday afternoons are. Volume + cadence + tone is the entire difference. We send one outbound, max 3 reply turns, then handoff. Opt-out is one word."
-
"What about TCPA / compliance?"
"Built in from day one. STOP/UNSUBSCRIBE triggers immediate opt-out within 2 minutes, confirmation reply, full audit log. Conservative cadence — never re-messages an opted-out customer."
-
"My staff already does this manually."
"How often, to how many customers, with what reply rate? Most salons text 5-10 customers a week and stop after a month. The system does 60 a week, every week, with personalization the front desk can't match."
-
"$300/mo + SMS feels too much."
"Average reactivation generates $80-$200 per re-booked customer. At 3% reply-to-booking on 60 messages/week, that's 7 re-bookings a month at $140 average = $980/mo recovered. ROI is over 3x typically."
The close
"$1.5k now to wire it to your customer DB + train the voice + send next Tuesday's 20 messages. $300/mo + ~$0.008 per SMS from then on. If your reactivation revenue isn't at least 2x the monthly fee in 60 days, kill it — no contract."
07Pricing notes▾
Anchor on customer LTV recovery. A $1k LTV customer reactivated covers 3+ years of monthly fees. Per-SMS cost: $0.0079 in the US (Twilio). At 60 outbounds/week = ~$2/mo pass-through. Setup includes: customer DB integration, voice training, message templates per segment, reply handler, opt-out compliance, weekly digest. Does NOT include: Mindbody/Boulevard/Vagaro live integration ($1k each), multi-location ($500 each), custom personality per technician ($500). Upsell: combine with Block 01 (voice receptionist) for customers who reply by calling, Block 04 (review responses) for post-visit review request → "Customer Loop" at $700/mo.