WhatsApp + Google Calendar: confirmations handled
Appointment confirmations sound simple until your front desk is buried in WhatsApp threads, reminders get forgotten, and “See you tomorrow” turns into a no-show.
This WhatsApp calendar automation hits clinic managers first, but reception teams and busy practice owners feel it too. You get confirmations sent on time, replies routed to the right place, and your schedule stays accurate without someone babysitting it.
Below is the exact workflow, what it fixes, and how it keeps WhatsApp messages and Google Calendar appointments in sync day after day.
How This Automation Works
The full n8n workflow, from trigger to final output:
n8n Workflow Template: WhatsApp + Google Calendar: confirmations handled
flowchart LR
subgraph sg0["Assistente Clínica Flow"]
direction LR
n6@{ icon: "mdi:brain", form: "rounded", label: "OpenAI Chat Model", pos: "b", h: 48 }
n7@{ icon: "mdi:robot", form: "rounded", label: "Assistente Clínica", pos: "b", h: 48 }
n8@{ icon: "mdi:message-outline", form: "rounded", label: "Enviar alerta de cancelamento", pos: "b", h: 48 }
n11@{ icon: "mdi:robot", form: "rounded", label: "AI Agent", pos: "b", h: 48 }
n12@{ icon: "mdi:memory", form: "rounded", label: "Postgres Chat Memory1", pos: "b", h: 48 }
n13@{ icon: "mdi:wrench", form: "rounded", label: "MCP Google Calendar2", pos: "b", h: 48 }
n17@{ icon: "mdi:brain", form: "rounded", label: "OpenRouter Chat Model1", pos: "b", h: 48 }
n18["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/webhook.dark.svg' width='40' height='40' /></div><br/>Webhook1"]
n19@{ icon: "mdi:swap-vertical", form: "rounded", label: "Edit Fields1", pos: "b", h: 48 }
n20@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Switch", pos: "b", h: 48 }
n21@{ icon: "mdi:robot", form: "rounded", label: "OpenAI", pos: "b", h: 48 }
n22@{ icon: "mdi:web", form: "rounded", label: "Evolution API", pos: "b", h: 48 }
n23@{ icon: "mdi:cog", form: "rounded", label: "Convert to File", pos: "b", h: 48 }
n24@{ icon: "mdi:robot", form: "rounded", label: "OpenAI1", pos: "b", h: 48 }
n25@{ icon: "mdi:robot", form: "rounded", label: "AI Agent2", pos: "b", h: 48 }
n26@{ icon: "mdi:brain", form: "rounded", label: "OpenRouter Chat Model2", pos: "b", h: 48 }
n27@{ icon: "mdi:web", form: "rounded", label: "Evolution API2", pos: "b", h: 48 }
n28@{ icon: "mdi:wrench", form: "rounded", label: "CallToHuman", pos: "b", h: 48 }
n21 --> n7
n20 --> n7
n20 --> n24
n20 --> n22
n24 --> n25
n11 --> n27
n18 --> n19
n25 --> n7
n28 -.-> n7
n19 --> n20
n22 --> n23
n23 --> n21
n6 -.-> n7
n7 --> n11
n13 -.-> n7
n12 -.-> n7
n17 -.-> n11
n26 -.-> n25
n8 -.-> n7
end
subgraph sg1["Receber Mensagem Telegram Flow"]
direction LR
n0@{ icon: "mdi:brain", form: "rounded", label: "OpenAI Chat Model1", pos: "b", h: 48 }
n1@{ icon: "mdi:robot", form: "rounded", label: "Assistente clinica interno", pos: "b", h: 48 }
n2@{ icon: "mdi:cog", form: "rounded", label: "Google Tasks", pos: "b", h: 48 }
n3@{ icon: "mdi:wrench", form: "rounded", label: "MCP Google Calendar", pos: "b", h: 48 }
n4["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/telegram.svg' width='40' height='40' /></div><br/>Receber Mensagem Telegram"]
n5@{ icon: "mdi:memory", form: "rounded", label: "Postgres Chat Memory", pos: "b", h: 48 }
n16["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/telegram.svg' width='40' height='40' /></div><br/>Telegram"]
n2 -.-> n1
n0 -.-> n1
n3 -.-> n1
n5 -.-> n1
n4 --> n1
n1 --> n16
end
subgraph sg2["Gatilho diário Flow"]
direction LR
n9@{ icon: "mdi:play-circle", form: "rounded", label: "Gatilho diário", pos: "b", h: 48 }
n10@{ icon: "mdi:robot", form: "rounded", label: "Assistente de confirmação", pos: "b", h: 48 }
n14@{ icon: "mdi:wrench", form: "rounded", label: "MCP GMAIL", pos: "b", h: 48 }
n15@{ icon: "mdi:wrench", form: "rounded", label: "MCP CALENDAR", pos: "b", h: 48 }
n29@{ icon: "mdi:brain", form: "rounded", label: "OpenAI Chat Model2", pos: "b", h: 48 }
n30@{ icon: "mdi:web", form: "rounded", label: "REMINDER", pos: "b", h: 48 }
n14 -.-> n10
n15 -.-> n10
n9 --> n10
n29 -.-> n10
n10 --> n30
end
%% Styling
classDef trigger fill:#e8f5e9,stroke:#388e3c,stroke-width:2px
classDef ai fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
classDef aiModel fill:#e8eaf6,stroke:#3f51b5,stroke-width:2px
classDef decision fill:#fff8e1,stroke:#f9a825,stroke-width:2px
classDef database fill:#fce4ec,stroke:#c2185b,stroke-width:2px
classDef api fill:#fff3e0,stroke:#e65100,stroke-width:2px
classDef code fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px
classDef disabled stroke-dasharray: 5 5,opacity: 0.5
class n4,n9 trigger
class n7,n11,n21,n24,n25,n1,n10 ai
class n6,n17,n26,n0,n29 aiModel
class n13,n28,n3,n14,n15 ai
class n12,n5 ai
class n20 decision
class n18,n22,n27,n30 api
classDef customIcon fill:none,stroke:none
class n18,n4,n16 customIcon
The Problem: Confirmations fall through the cracks
Most clinics don’t lose patients because the care is bad. They lose time (and revenue) because communication is messy. A receptionist confirms five appointments, gets pulled into an urgent call, then comes back to 30 unread WhatsApp messages. Somewhere in that pile is a patient trying to reschedule, another asking “what time was it again?”, and someone who never replies at all. Now your Google Calendar is technically “correct”, but reality isn’t. Staff prep the wrong room, the wrong clinician, or nobody shows up. Honestly, it’s exhausting.
The friction compounds. Here’s where it breaks down in real clinics.
- Confirmations are sent inconsistently, so patients who would have replied “yes” simply don’t see a prompt.
- Reschedule requests arrive, but they’re buried in chat history and handled too late to reuse the slot.
- WhatsApp voice notes and photos slow everything down because someone has to listen, interpret, and type it back out.
- Calendar changes and chat updates drift apart, which creates double-bookings or awkward “we don’t see you scheduled” moments.
The Solution: WhatsApp confirmations that update your calendar
This n8n workflow acts like a clinic communication layer between WhatsApp, Telegram (for staff), and Google Calendar. Incoming WhatsApp messages hit a webhook first, then get classified by type (text, image, audio, document). If it’s media, the workflow fetches the file and uses AI to turn it into usable text (audio transcription or image understanding). From there, a specialized WhatsApp assistant agent handles common patient intents like confirming, rescheduling, and basic questions, then a formatting agent ensures the outgoing message matches WhatsApp-friendly structure before sending it through the Evolution API. Separately, every weekday morning the workflow checks tomorrow’s Google Calendar appointments and proactively sends confirmation messages, so the “please confirm” step happens reliably even on busy days.
The workflow starts with two entry points: patient messages in WhatsApp and staff requests in Telegram. It then routes the conversation through the right AI agent, pulls or updates appointment details via Google Calendar tools, and finally sends a clean confirmation back to the patient (and a clear response back to staff when they initiate changes).
What You Get: Automation vs. Results
| What This Workflow Automates | Results You’ll Get |
|---|---|
|
|
Example: What This Looks Like
Say your clinic has 25 appointments tomorrow. Manually, sending a WhatsApp reminder, waiting, then logging the outcome often takes about 4 minutes per patient once you include context switching, which is roughly 100 minutes. And that’s on a “smooth” day. With this workflow, confirmations go out automatically at 08:00, and replies route themselves to the right agent. You might spend 10 minutes reviewing edge cases, not nearly two hours chasing people.
What You’ll Need
- n8n instance (try n8n Cloud free)
- Self-hosting option if you prefer (Hostinger works well)
- Evolution API (WhatsApp) for sending and receiving WhatsApp messages.
- Google Calendar to read and update appointment details.
- Telegram Bot for staff commands and internal notifications.
- OpenAI API key (get it from your OpenAI API dashboard).
- PostgreSQL database for persistent chat memory sessions.
Skill level: Intermediate. You’ll connect a few credentials, paste API keys, and test message flows end-to-end.
Don’t want to set this up yourself? Talk to an automation expert (free 15-minute consultation).
How It Works
Patient messages trigger the workflow. An incoming WhatsApp webhook receives each message, then fields are mapped so the workflow has a consistent format to work with.
Content gets understood, even when it’s messy. A switch routes text straight to the WhatsApp assistant, while audio and images are fetched and converted so AI can transcribe or interpret what the patient actually sent.
AI agents handle intent and next actions. The Clinic WhatsApp Assistant and Appointment Confirmation Agent decide if the patient is confirming, asking to reschedule, or needs escalation. When staff initiate changes from Telegram, the Internal Clinic Assistant handles those requests and replies back in Telegram.
Confirmed messaging goes out cleanly. A Message Formatting Agent prepares the final WhatsApp reply, then the Evolution API dispatch nodes send it. On weekdays at 08:00, the scheduled trigger runs a next-day reminder batch so confirmations happen consistently.
You can easily modify the confirmation timing to match your clinic hours based on your needs. See the full implementation guide below for customization options.
Step-by-Step Implementation Guide
Step 1: Configure the Triggers
Set up the inbound WhatsApp, Telegram, and scheduled triggers that initiate the workflow’s three core flows.
- Open Incoming WhatsApp Webhook and set HTTP Method to
POSTand Path toevolutionAPIKORE. - Open Telegram Message Intake and confirm it listens for updates of
message. Credential Required: Connect yourtelegramApicredentials. - Open Weekday Schedule Trigger and set the cron expression to
0 8 * * 1-5(weekday 08:00).
evolutionAPIKORE.Step 2: Map and Route Incoming WhatsApp Data
Normalize the incoming WhatsApp payload and route it by content type (text, image, audio, or document).
- In Map Incoming Fields, add assignments for key fields like number with
{{$json.body.data.key.remoteJid}}and text with{{$json.body.data.message.conversation}}. - In Map Incoming Fields, include media fields such as image.url with
{{$json.body.data.message.imageMessage.url}}and audio.url with{{$json.body.data.message.audioMessage.url}}. - In Route by Content Type, verify the rules check
{{$json.text}},{{$json.image.url}},{{$json.audio.url}}, and{{$json.document.url}}fornotEmpty.
Step 3: Configure Media Processing for Audio and Images
Set up the audio transcription and image analysis paths before responses are generated.
- In Evolution Media Fetch, set Operation to
get-media-base64, Message ID to{{$json.key_id}}, and Instance Name to{{$('Incoming WhatsApp Webhook').item.json.body.instance}}. Credential Required: Connect yourevolutionApicredentials. - In Binary File Converter, set Operation to
toBinaryand Source Property todata.base64. - In OpenAI Audio Transcriber, set Resource to
audio, Operation totranscribe, and Binary Property Name to=data. Credential Required: Connect youropenAiApicredentials. - In OpenAI Vision Analyzer, set Resource to
image, Operation toanalyze, Text toTRANSCRIBE OS TEXTOS e describe a imagem, and Image URLs to{{$json.image}}. Credential Required: Connect youropenAiApicredentials. - In Image Insight Agent, set Text to
{{$json.output}}and ensure it uses OpenRouter Chat Engine B as the language model. Credential Required: Connect youropenRouterApicredentials to OpenRouter Chat Engine B.
Step 4: Configure the WhatsApp AI Response Chain
Build the assistant that interprets messages, applies memory, formats the reply, and sends it to WhatsApp.
- In Clinic WhatsApp Assistant, set Text to
{{$json.text}}{{$json.output}}and review the system message for clinic policy. - Attach Postgres Memory Session as memory with Session Key set to
{{ $('Incoming WhatsApp Webhook').item.json.body.data.key.id }}and Context Window Length to50. Credential Required: Connect yourpostgrescredentials on Clinic WhatsApp Assistant (the memory node is a sub-node). - Set the language model for Clinic WhatsApp Assistant to OpenAI Chat Engine. Credential Required: Connect your
openAiApicredentials to OpenAI Chat Engine. - For tools used by Clinic WhatsApp Assistant, ensure Send Cancellation Alert is available with Text
{{$fromAI('Text', ``, 'string')}}and Chat ID{{$fromAI('Chat_ID', ``, 'string')}}. Credential Required: Connect yourtelegramApicredentials on Clinic WhatsApp Assistant (tool credentials belong to the parent agent). - Open Run Sub-Workflow (Configure Required) and set Workflow ID to your escalation workflow. Keep inputs mapped to
{{$fromAI('nome', ``, 'string')}},{{$fromAI('telefone', ``, 'string')}}, and{{$fromAI('ultima_mensagem', ``, 'string')}}. - In Message Formatting Agent, set Text to
{{$json.output}}and use OpenRouter Chat Engine A as the language model. Credential Required: Connect youropenRouterApicredentials to OpenRouter Chat Engine A. - In WhatsApp Message Dispatch, set Remote JID to
{{$('Incoming WhatsApp Webhook').item.json.body.data.key.remoteJid}}, Message Text to{{$json.output}}, and Instance Name to{{$('Incoming WhatsApp Webhook').item.json.body.instance}}. Credential Required: Connect yourevolutionApicredentials.
Step 5: Configure the Telegram Internal Assistant Flow
Set up the internal Telegram-driven assistant for staff-driven rescheduling and task reminders.
- In Internal Clinic Assistant, set Text to
{{$json.message.text}}and verify the system instructions for internal rescheduling and shopping list tasks. - Assign OpenAI Chat Engine A as the language model. Credential Required: Connect your
openAiApicredentials to OpenAI Chat Engine A. - Connect Postgres Conversation Memory with Session Key set to
100and Context Window Length to10. Credential Required: Connect yourpostgrescredentials on Internal Clinic Assistant (memory credentials belong to the parent agent). - Ensure tool nodes for this agent are attached: MCP Calendar Access and Add Task Reminder. Credential Required: Connect your
googleTasksOAuth2Apicredentials on Internal Clinic Assistant (the Add Task Reminder tool is a sub-node). - In Telegram Reply Sender, set Text to
{{$json.output}}and Chat ID to{{$('Telegram Message Intake').item.json.message.chat.id}}. Credential Required: Connect yourtelegramApicredentials.
Step 6: Configure Appointment Confirmation Automation
Automate daily appointment confirmation messages based on the calendar.
- Open Appointment Confirmation Agent and confirm the prompt instructs it to list next-day events and send reminders.
- Assign OpenAI Chat Engine B as the language model. Credential Required: Connect your
openAiApicredentials to OpenAI Chat Engine B. - Attach the MCP tools MCP Calendar Tool and MCP Gmail Connector to Appointment Confirmation Agent so it can read the schedule and related communications.
- In Appointment Reminder Sender, set Remote JID to
[YOUR_EMAIL], Message Text to{{$fromAI("reminder")}}, and Instance Name toinstance name. Credential Required: Connect yourevolutionApicredentials.
[YOUR_EMAIL] and instance name in Appointment Reminder Sender or reminders will not reach real recipients.Step 7: Review Execution Flow Connections
Verify the node order matches the intended execution paths for WhatsApp, Telegram, and scheduled reminders.
- Confirm the WhatsApp chain: Incoming WhatsApp Webhook → Map Incoming Fields → Route by Content Type → Clinic WhatsApp Assistant → Message Formatting Agent → WhatsApp Message Dispatch.
- Confirm the audio branch: Route by Content Type → Evolution Media Fetch → Binary File Converter → OpenAI Audio Transcriber → Clinic WhatsApp Assistant.
- Confirm the image branch: Route by Content Type → OpenAI Vision Analyzer → Image Insight Agent → Clinic WhatsApp Assistant.
- Confirm the Telegram chain: Telegram Message Intake → Internal Clinic Assistant → Telegram Reply Sender.
- Confirm the scheduled reminders: Weekday Schedule Trigger → Appointment Confirmation Agent → Appointment Reminder Sender.
Step 8: Test & Activate Your Workflow
Validate each trigger and confirm the responses before turning on the workflow in production.
- Use Execute Workflow to send a test message into Incoming WhatsApp Webhook and confirm the response is sent by WhatsApp Message Dispatch.
- Send a Telegram message to verify Telegram Message Intake triggers Internal Clinic Assistant and returns a reply via Telegram Reply Sender.
- Run Weekday Schedule Trigger manually to confirm Appointment Reminder Sender sends a reminder with
{{$fromAI("reminder")}}. - When tests succeed, toggle the workflow to Active to enable production execution.
Common Gotchas
- Google Calendar OAuth credentials can expire or need specific permissions. If things break, check your Google Cloud OAuth consent screen and token status first.
- If you’re using Wait nodes or external rendering, processing times vary. Bump up the wait duration if downstream nodes fail on empty responses.
- Evolution API (WhatsApp) instances often fail due to an incorrect instance name or revoked API key. Verify the instance and key in your Evolution dashboard, then re-test a single outbound message.
- Default prompts in AI nodes are generic. Add your brand voice early or you’ll be editing outputs forever.
Frequently Asked Questions
Plan for about 60 minutes if your credentials are ready.
No. You’ll mostly connect accounts and paste API keys. The logic is already built into the workflow.
Yes. n8n has a free self-hosted option and a free trial on n8n Cloud. Cloud plans start at $20/month for higher volume. You’ll also need to factor in OpenAI API usage costs, which are usually a few cents per conversation depending on message length and media.
Two options: n8n Cloud (managed, easiest setup) or self-hosting on a VPS. For self-hosting, Hostinger VPS is affordable and handles n8n well. Self-hosting gives you unlimited executions but requires basic server management.
Yes, and you should. You can change the weekday timing in the “Weekday Schedule Trigger” node, then adjust the wording inside the “Appointment Confirmation Agent” and “Message Formatting Agent” so it matches your clinic’s tone. Common tweaks include adding a cancellation policy line, supporting multiple languages, and sending staff a Telegram alert when a patient asks to reschedule.
Usually it’s an Evolution API credential issue: wrong instance name, expired key, or the WhatsApp session disconnected. Update the Evolution credentials in n8n, then send one simple outbound test message to confirm delivery. If inbound messages aren’t arriving, double-check the webhook URL configured in Evolution. Also watch for rate limits if you blast many reminders at once.
For a typical small clinic schedule, dozens to a few hundred confirmations a day is realistic.
Often, yes, if you care about reliability and flexibility. This workflow isn’t just “send a reminder”; it routes messages by content type, processes audio and images, and uses memory so patient conversations don’t reset every time. n8n also gives you branching logic without paying per-path, and self-hosting avoids execution caps if volume grows. Zapier or Make can be quicker for very simple two-step reminders, but they get awkward once you add media processing and escalation rules. If you want help choosing, Talk to an automation expert and map it to your actual patient volume.
Once confirmations run on autopilot, the schedule stops being a daily guessing game. The workflow handles the repetitive follow-ups so your staff can focus on patients.
Need Help Setting This Up?
Our automation experts can build and customize this workflow for your specific needs. Free 15-minute consultation—no commitment required.