Automate WhatsApp Appointment Reminders with n8n (Clinics, Salons, Coaching Centres)
A missed appointment is an empty chair you already paid for. Clinics, salons, physios, tutors and coaching centres in India mostly fix this the same way: someone at the front desk sends WhatsApp reminders by hand every evening. It works until that person is busy, on leave, or forgets.
This post shows the n8n workflow I build for that job. It reads tomorrow's bookings, sends each customer a WhatsApp reminder, and routes "reschedule" replies back to your staff. It runs every evening without anyone touching it.
What the workflow does
Every day at 6 PM
→ read tomorrow's appointments (Google Sheets or Google Calendar)
→ skip rows without a valid phone number or already reminded
→ send WhatsApp reminder with date, time and address
→ mark the row "reminded"
When a customer replies
→ "1" / "yes" → mark confirmed
→ "2" / "reschedule" → alert the front desk on WhatsApp
→ anything else → forward to the front desk
Two n8n workflows, about 12 nodes in total. No app for the customer to install, no new software for your staff to learn. They keep using the sheet or calendar they already use.
Step 0: pick how WhatsApp messages get sent
This choice decides your cost and your risk, so make it first.
| Meta WhatsApp Cloud API | OpenWA / unofficial gateway | |
|---|---|---|
| Setup | Business verification + approved template | Scan a QR code with a phone |
| Cost per reminder | ₹0.115 + GST (utility template) | ₹0 |
| Ban risk | None if you follow Meta's rules | Real, especially at volume |
| Good for | Any business sending reminders daily | Testing, or under ~30 messages/day to existing customers |
Appointment reminders count as utility messages in Meta's pricing, the cheap category. A clinic sending 1,000 reminders a month pays about ₹136 including GST. Full rate table and worked bills: WhatsApp Business API pricing in India.
My advice: start on OpenWA to prove the workflow with your real bookings for a week, then move to the Cloud API. Only the "send" node changes. The comparison of both routes is in Evolution API vs OpenWA vs Meta Cloud API.
Step 1: the booking source
Option A: Google Sheets
Most small businesses already have a sheet. It needs these columns:
| date | time | name | phone | service | status |
|---|---|---|---|---|---|
| 2026-10-31 | 10:30 | Priya | 9876543210 | Root canal follow-up |
Keep date in YYYY-MM-DD format. If staff type "31 Oct", the filter in Step 2 has to parse it, and that's where reminders silently go missing.
Option B: Google Calendar
If bookings live in Google Calendar, use the Google Calendar → Get Many Events node with "After" set to tomorrow 00:00 and "Before" set to tomorrow 23:59. Ask staff to put the phone number in the event description. A single convention like Phone: 9876543210 is enough to extract it reliably.
Step 2: the daily reminder workflow
1. Schedule Trigger: every day at 18:00. Set the workflow timezone to Asia/Kolkata in workflow settings, or it fires at 18:00 UTC (11:30 PM IST).
2. Google Sheets → Get Row(s): read the booking sheet.
3. Code node: keep tomorrow's rows, clean the numbers, skip anything already reminded.
4. HTTP Request: send the WhatsApp message.
5. Google Sheets → Update Row: set status to reminded.
The Code node does the work that usually breaks these setups:
const tomorrow = new Date(Date.now() + 24 * 60 * 60 * 1000)
.toLocaleDateString('en-CA', { timeZone: 'Asia/Kolkata' }); // YYYY-MM-DD
return $input.all()
.filter(i => i.json.date === tomorrow && !i.json.status)
.map(i => {
// Accept "98765 43210", "+91 98765-43210", "09876543210"
const digits = String(i.json.phone).replace(/\D/g, '').replace(/^0+/, '');
const phone = digits.length === 10 ? '91' + digits : digits;
return { json: { ...i.json, phone, valid: /^91[6-9]\d{9}$/.test(phone) } };
})
.filter(i => i.json.valid);
The phone cleanup matters more than it looks. Staff type numbers in every format, and an invalid number gives an error at the send step rather than a missing reminder you'd never notice.
Sending through the Meta Cloud API
POST https://graph.facebook.com/{API_VERSION}/{PHONE_NUMBER_ID}/messages
Authorization: Bearer {ACCESS_TOKEN}
// {API_VERSION}: the current Graph API version from Meta's changelog, e.g. v23.0
{
"messaging_product": "whatsapp",
"to": "{{ $json.phone }}",
"type": "template",
"template": {
"name": "appointment_reminder",
"language": { "code": "en" },
"components": [{
"type": "body",
"parameters": [
{ "type": "text", "text": "{{ $json.name }}" },
{ "type": "text", "text": "{{ $json.service }}" },
{ "type": "text", "text": "{{ $json.time }}" }
]
}]
}
}
The template you submit to Meta for approval looks like:
Hi {{1}}, this is a reminder of your {{2}} appointment tomorrow at {{3}}. Reply 1 to confirm or 2 to reschedule.
Submit it under the Utility category. Keep it free of offers and discounts, or Meta reclassifies it as Marketing and you pay about 7.5× more per message.
Sending through OpenWA
Same workflow, different HTTP Request:
POST http://openwa-api:2785/api/sessions/{sessionId}/messages/send-text
{
"chatId": "{{ $json.phone }}@c.us",
"text": "Hi {{ $json.name }}, reminder of your {{ $json.service }} appointment tomorrow at {{ $json.time }}. Reply 1 to confirm or 2 to reschedule."
}
Add a Wait node of 20–40 seconds between messages. Twenty messages sent within one second from a personal number is exactly the pattern WhatsApp flags. The full OpenWA endpoint list is in the OpenWA API reference for n8n.
Step 3: handle the replies
The second workflow starts with a Webhook node that receives incoming messages from the Cloud API or OpenWA. Then:
1. Code node: normalise the text (trim().toLowerCase()) and pull out the sender's number.
2. Google Sheets → Get Row(s): find tomorrow's booking for that number.
3. Switch node:
- 1, yes, confirm, haan → update status to confirmed, send "Thanks, see you tomorrow."
- 2, reschedule, cancel → update status to reschedule, send the front desk a WhatsApp message with the customer's name and number.
- anything else → forward the message to the front desk unchanged.
Add Hindi or your local language to the confirm list. Customers reply the way they talk, and "haan ji" should count as a yes.
A customer replying opens a 24-hour service window with Meta. Your "see you tomorrow" reply inside that window is free.
What it costs per month
For a clinic with about 40 appointments a day (roughly 1,000 reminders a month):
n8n self-hosted on a small VPS ≈ ₹500–700
Meta utility templates (1,000) ≈ ₹136 incl. GST
Google Sheets / Calendar ₹0
------------------------------------------------
Total ≈ ₹650–850/month
If you already run n8n for something else, the reminders add only the message cost. Server sizing and the hidden costs are in n8n self-hosted cost in India.
Compare that with reminder add-ons in clinic or salon software, which usually charge per message or need a higher plan, and with the 20–30 minutes a day someone spends sending reminders by hand.
Mistakes I see in these setups
cancelled before sending.Beyond reminders
Once bookings flow through n8n, the same setup can send:
Each is one more small workflow on the same server.
Want this running for your clinic, salon or institute without building it yourself? See WhatsApp automation for clinics or get in touch.
Related Posts
Rather have this built for you?
I set up WhatsApp and n8n automation for small businesses: reply bots, order updates and lead capture, handed over with backups and a known monthly cost. Fixed packages from ₹15,000.
See packages and pricingBuilt something similar or want to talk through the architecture? Get in touch.