Home / Dental practices / Win-back text
Recall texts for patients overdue for a cleaning
Hundreds of patients haven't been in for over a year. Nobody has time to call down the list.
How it works
- Export your recall list (name, phone, last visit) to a Google Sheet. Only include patients who agreed to texts.
- Every morning at 10, the workflow texts anyone 180+ days past their last visit (you set the number) who hasn't been texted since, up to a daily cap.
- The text only says they're due and links to booking. No treatment details.
- Replies come to the front desk email. If someone replies with the word URGENT, the office cell gets a text right away, they get a quick 'got it', and the normal reply is skipped.
- The reply webhook gets the Twilio signature check (403 if not from Twilio).
Tools used
How we got this number
- Twilio local number (skip if you already have one for another recipe)$1.15
- Texting registration (A2P 10DLC) monthly fee$2
- ~240 text segments (~200 recall texts plus replies)$1.99
- carrier fees on ~240 outbound texts$1.20
- Automation platform (or self-host n8n free)β¬20
- Google Sheet recall list$0
Assumes ~200 recall texts a month. See the HIPAA note above before you start. Prices are list prices checked 2026-10-26; see every source.
Plus one-time texting registration (A2P 10DLC): about $19.50 (low-volume brand + campaign vetting). Source
The full setup, step by step
19 steps in one n8n workflow. Everything below is generated from the template itself, so it always matches.
Before you start
You need an n8n account (n8n, or self-host it free) plus your own logins for: Google Sheets Twilio Gmail / Google Workspace.
How the automation flows
Every morning at 10 (win-back texts)
Tap a step to jump to its details.
Each step and what it does
- 1Trigger (schedule)
Every morning
Runs on its own every morning at 10 (your n8n instance's time zone).
Runsevery day at 10:00
Then β 3. Config (edit me)
- 2Trigger
Incoming text
Twilio calls this webhook every time someone texts your business number.
Webhook path
YOUR_N8N_URL/webhook/win-back-smsThen β 3. Config (edit me)
- 3Settings
Config (edit me)
One place for everything specific to your business. Every later step reads from here, so this is the only node you have to edit.
Then β 4. Scheduled run or text?
- 4Decision
Scheduled run or text?
The schedule and Twilio share this workflow. Scheduled runs do the sending; texts (which carry a Twilio MessageSid) go through the signature check.
Rulethe request has no Twilio MessageSid (so it's the scheduled run)
Scheduled runs β 5. Read your list Β· Texts β 11. Check Twilio signature
- 5Google Sheets
Read your list
Reads every row of your Google Sheet list.
Sheet tab
Recallπ Connect your Google Sheets login on this node
Then β 6. Due for a nudge?
- 6Decision
Due for a nudge?
Keeps rows with a phone, not opted out, last visit at least the number of days you set, and not already texted since that visit.
Rulehas a phone, isn't opted out, last visit was at least winback_days ago, and hasn't been texted since that visit
If yes β 7. Daily cap Β· If no β stops here
- 7Limit
Daily cap
Sends to at most this many people per morning (daily_cap), so replies don't flood you.
Max
daily_capfrom Config (default 25)Then β 8. Send the win-back text
- 8Send SMS (Twilio)
Send the win-back text
Texts each person your booking link, using their first name.
Sendsthe message shown under Message copy
π Connect your Twilio login on this node
Then β 9. Mark as texted
- 9Google Sheets
Mark as texted
Writes today's date into last_texted (matched by phone) so they aren't texted again until their next visit.
Sheet tab
Recallπ Connect your Google Sheets login on this node
Then β 10. Email you a summary
- 10Send email (Gmail)
Email you a summary
One email with how many texts went out today.
Sendsthe message shown under Message copy
π Connect your Gmail login on this node
End of this path.
- 11Code (security check)
Check Twilio signature
Proves the request really came from Twilio. It rebuilds Twilio's signature (HMAC-SHA1 of your webhook URL plus every field Twilio sent, keyed with your auth token) and compares it to the X-Twilio-Signature header. Uses Node's built-in crypto module: fine on n8n Cloud; self-hosted n8n needs NODE_FUNCTION_ALLOW_BUILTIN=crypto.
DetailsHow the Twilio security check works
Then β 12. Signature valid?
- 12Decision
Signature valid?
Only real Twilio requests continue. Anything else (a bot, a fake request, a wrong URL in Config) goes to the 403 step.
Rulethe signature Twilio sent matches the one rebuilt from your auth token
If yes β 13. Acknowledge Twilio (text) Β· If no β 19. Reject: not from Twilio (403)
- 13Reply to request
Acknowledge Twilio (text)
Tells Twilio the text was received. The reply goes out separately, so this one sends nothing to the customer.
Then β 14. Says URGENT?
- 14Decision
Says URGENT?
If the customer's text contains the word URGENT (any capitalization), the urgent path runs instead of the normal reply.
Ruletheir text contains βurgentβ
If yes β 15. Text the owner (URGENT) Β· If no β 18. Forward the reply to you
- 15Send SMS (Twilio)
Text the owner (URGENT)
Texts your cell right away with their number and exactly what they wrote.
Sendsthe message shown under Message copy
π Connect your Twilio login on this node
Then β 16. Text the customer (URGENT ack)
- 16Send SMS (Twilio)
Text the customer (URGENT ack)
Lets the customer know their message reached you.
Sendsthe message shown under Message copy
π Connect your Twilio login on this node
- 17Send email (Gmail)
Email the owner (URGENT, optional)
A copy by email. If Gmail isn't connected or fails, the workflow still finishes (the text already went out).
Sendsthe message shown under Message copy
π Connect your Gmail login on this node
End of this path.
- 18Send email (Gmail)
Forward the reply to you
Emails you what they wrote, so you can answer from your phone.
Sendsthe message shown under Message copy
π Connect your Gmail login on this node
End of this path.
- 19Reply to request
Reject: not from Twilio (403)
Answers 403 Forbidden and stops. Nothing is texted, emailed or saved.
Responds
403 ForbiddenEnd of this path.
Key settings to change
All of these live in the Config (edit me) node. Change them once and every text and email updates.
| Setting | Placeholder in the template | Change it to |
|---|---|---|
Business namebusiness_name | YOUR BUSINESS NAME | Exactly how customers know you. It appears in every text. |
Booking / calendar linkbooking_link | https://YOUR-BOOKING-LINK | Your online booking page (Calendly, your CRM's scheduler, or your contact page). Use the short public link. |
Hourshours | Mon-Fri 8am-6pm | Short and text-friendly, e.g. Mon-Fri 8am-6pm. |
Your emailowner_email | you@example.com | Where the 'new lead' and 'missed call' alerts go. |
Your cellowner_cell | +15555550100 | In +1 format (+15551234567). |
Twilio numbertwilio_number | +15555550199 | The number you bought in Twilio, in +1 format. Texts are sent from it. |
Twilio auth tokentwilio_auth_token | PASTE_YOUR_TWILIO_AUTH_TOKEN | Twilio Console > Account info > Auth Token. Used only to check that requests really came from Twilio. Treat it like a password: don't share the workflow once it's filled in. |
Incoming-text webhook URLtwilio_sms_webhook_url | https://YOUR-N8N-URL/webhook/win-back-sms | The exact Production URL of the Incoming text node, the same one you paste into Twilio (Messaging > A message comes in). One character off and every text gets a 403. |
List Google Sheet IDclients_sheet_id | YOUR_GOOGLE_SHEET_ID | The long code in the sheet's URL between /d/ and /edit. |
Days until a nudgewinback_days | 180 | How many days after the last visit (or last contact) someone gets the text. |
Daily capdaily_cap | 25 | The most texts sent in one morning. |
Message copy: exactly what it sends
Highlighted parts are filled in automatically. Edit the wording right in the node.
Subject Win-back texts sent today: number sent
Subject URGENT: text from their phone number
Your cell was texted and they were told you'll get back to them right away.
Subject Reply from their phone number (replied to a win-back text)
Reply to them from your phone or the Twilio console.
How the Twilio security check works
Your webhook URL is public, so anyone who finds it could send fake "texts" and make the workflow text people on your dime. Every request Twilio sends is signed, so the first thing this workflow does is check that signature:
- Take the exact webhook URL from Config (
twilio_sms_webhook_url, ortwilio_voice_webhook_urlfor call events). - Sort every field Twilio posted by name and glue each name and value onto the end of the URL (
β¦BodyhiFrom+1555β¦). - HMAC-SHA1 that string with your Twilio auth token, base64-encode it, and compare it to the
X-Twilio-Signatureheader (a constant-time compare). - Match: continue. No match, no header, or no URL/token in Config: answer
403 Forbiddenand stop.
It's a Code node because n8n's Crypto node can't do HMAC-SHA1. It uses Node's built-in crypto module: allowed on n8n Cloud. Self-hosted n8n: set the environment variable NODE_FUNCTION_ALLOW_BUILTIN=crypto (on your task runners too, if you use them), or the node errors.
The auth token lives only in Config. Never paste it into the code, and don't share your workflow export once it's filled in.
Hook it up
- Make a Google Sheet with a tab named
Recalland columnsname | phone | last_visit | last_texted | opted_out. Phones in +1 format, dates as YYYY-MM-DD (format the columns as plain text). Most practice-management systems can export a recall list to a spreadsheet; keep only name, phone and last visit. - Fill in Config (edit me): sheet ID, how many days counts as overdue (winback_days), the daily cap, Twilio number, auth token and webhook URL.
- Connect Google Sheets, Twilio and Gmail credentials.
- In Twilio > Phone Numbers > your number > Messaging: 'A message comes in' > Webhook, HTTP POST,
https://YOUR-N8N-URL/webhook/win-back-sms. Paste the exact same URL into twilio_sms_webhook_url in Config. A number has one 'message comes in' webhook, so if you run several of these workflows on one number, point it at only one of them. - Only include people who agreed to get texts from you. Activate: every morning at 10 it texts up to the daily cap, once per visit.
Security: the Check Twilio signature node rejects (403) anything not signed with your Twilio auth token. Self-hosted n8n: set NODE_FUNCTION_ALLOW_BUILTIN=crypto. Don't share this workflow once your token is in it.
Test it before you trust it
Skip the clicking
Get the ready-to-import n8n template
Every step above, already wired up. Paste it into n8n, add your logins, fill in your business info and you're live.
β Unlocked. Here's your template.
- In n8n: click New workflow.
- Paste onto the empty canvas (Ctrl/Cmd+V).
- Set your credentials on the red nodes, then fill in Config (edit me).
Download .json instead
Done-for-you setup
Rather not build it yourself?
Set it up yourself, or I'll set it up for you in a week.
- I set up the same templates on this site in your own n8n, Twilio and Google accounts, so you own everything.
- Your business info, booking link and message wording filled in, and every test on the setup page run with you.
- Live within a week of getting your logins.
Tell me your trade and how customers reach you today. I'll reply by email with next steps.