WhatsApp + Google Sheets: intake logged, replies fast
Your WhatsApp inbox turns into a messy intake form fast. People send voice notes, screenshots, PDFs, half-finished details, and you’re left piecing it together, then copying it into a spreadsheet you don’t even trust anymore.
This WhatsApp Sheets automation hits support leads first, but clinic admins and service businesses feel it too. You get every message captured in Google Sheets, plus a clean, consistent reply back to the sender so you’re not typing the same thing 30 times a week.
Below is the workflow logic, what it changes day-to-day, and what you’ll need to run it safely (especially if you deal with sensitive information).
How This Automation Works
See how this solves the problem:
n8n Workflow Template: WhatsApp + Google Sheets: intake logged, replies fast
flowchart LR
subgraph sg0["WA Flow"]
direction LR
n0@{ icon: "mdi:robot", form: "rounded", label: "Appointment System", pos: "b", h: 48 }
n1@{ icon: "mdi:memory", form: "rounded", label: "Memory", pos: "b", h: 48 }
n2@{ icon: "mdi:brain", form: "rounded", label: "OpenAI", pos: "b", h: 48 }
n3["<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/whatsapp.svg' width='40' height='40' /></div><br/>WATrigger"]
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/code.svg' width='40' height='40' /></div><br/>PrepareInput"]
n5@{ icon: "mdi:database", form: "rounded", label: "create_patient", pos: "b", h: 48 }
n6@{ icon: "mdi:wrench", form: "rounded", label: "Calculator", pos: "b", h: 48 }
n7@{ icon: "mdi:database", form: "rounded", label: "get_last_patient_id", pos: "b", h: 48 }
n8@{ icon: "mdi:memory", form: "rounded", label: "Memory1", pos: "b", h: 48 }
n9@{ icon: "mdi:brain", form: "rounded", label: "OpenAI1", pos: "b", h: 48 }
n10@{ icon: "mdi:wrench", form: "rounded", label: "Register Patient Tool", pos: "b", h: 48 }
n11@{ icon: "mdi:wrench", form: "rounded", label: "Appointment Scheduler Tool", pos: "b", h: 48 }
n12@{ icon: "mdi:database", form: "rounded", label: "get_clinics", pos: "b", h: 48 }
n13@{ icon: "mdi:database", form: "rounded", label: "get_doctors", pos: "b", h: 48 }
n14@{ icon: "mdi:database", form: "rounded", label: "find_patient", pos: "b", h: 48 }
n15@{ icon: "mdi:database", form: "rounded", label: "create_appointment", pos: "b", h: 48 }
n16@{ icon: "mdi:database", form: "rounded", label: "get_availability", pos: "b", h: 48 }
n17@{ icon: "mdi:database", form: "rounded", label: "find_last_entry_id", pos: "b", h: 48 }
n18@{ icon: "mdi:wrench", form: "rounded", label: "Calculator1", pos: "b", h: 48 }
n19@{ icon: "mdi:memory", form: "rounded", label: "Memory2", pos: "b", h: 48 }
n20@{ icon: "mdi:brain", form: "rounded", label: "OpenAI2", pos: "b", h: 48 }
n21@{ icon: "mdi:swap-horizontal", form: "rounded", label: "If", pos: "b", h: 48 }
n22@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Switch", pos: "b", h: 48 }
n23["<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/whatsapp.svg' width='40' height='40' /></div><br/>Get Audio URL"]
n24["<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/httprequest.dark.svg' width='40' height='40' /></div><br/>Download Audio"]
n25@{ icon: "mdi:robot", form: "rounded", label: "Transcribe Audio", pos: "b", h: 48 }
n26@{ icon: "mdi:swap-vertical", form: "rounded", label: "Audio Prompt", pos: "b", h: 48 }
n27["<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/httprequest.dark.svg' width='40' height='40' /></div><br/>Download Image"]
n28["<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/whatsapp.svg' width='40' height='40' /></div><br/>Get Image URL"]
n29@{ icon: "mdi:robot", form: "rounded", label: "Analyze Image", pos: "b", h: 48 }
n30@{ icon: "mdi:swap-vertical", form: "rounded", label: "Text Prompt", pos: "b", h: 48 }
n31@{ icon: "mdi:robot", form: "rounded", label: "Generate Audio", pos: "b", h: 48 }
n32@{ icon: "mdi:swap-horizontal", form: "rounded", label: "response", pos: "b", h: 48 }
n33["<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/whatsapp.svg' width='40' height='40' /></div><br/>Text Message"]
n34["<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/code.svg' width='40' height='40' /></div><br/>Code"]
n35["<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/whatsapp.svg' width='40' height='40' /></div><br/>Audio Response"]
n36["<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/whatsapp.svg' width='40' height='40' /></div><br/>Get Document"]
n37["<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/httprequest.dark.svg' width='40' height='40' /></div><br/>Download Document"]
n38["<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/whatsapp.svg' width='40' height='40' /></div><br/>Analyzing Image Text"]
n39@{ icon: "mdi:swap-horizontal", form: "rounded", label: "If PDF File", pos: "b", h: 48 }
n40@{ icon: "mdi:cog", form: "rounded", label: "Extract from PDF File", pos: "b", h: 48 }
n41@{ icon: "mdi:swap-vertical", form: "rounded", label: "Document Prompt", pos: "b", h: 48 }
n42@{ icon: "mdi:swap-vertical", form: "rounded", label: "Image Prompt", pos: "b", h: 48 }
n43@{ icon: "mdi:wrench", form: "rounded", label: "Report Analyzer Tool", pos: "b", h: 48 }
n44@{ icon: "mdi:brain", form: "rounded", label: "OpenAI3", pos: "b", h: 48 }
n45@{ icon: "mdi:memory", form: "rounded", label: "Memory3", pos: "b", h: 48 }
n46@{ icon: "mdi:wrench", form: "rounded", label: "Prescription Medicine Analyz..", pos: "b", h: 48 }
n47@{ icon: "mdi:brain", form: "rounded", label: "OpenAI4", pos: "b", h: 48 }
n48@{ icon: "mdi:memory", form: "rounded", label: "Memory4", pos: "b", h: 48 }
n21 --> n0
n34 --> n35
n1 -.-> n0
n2 -.-> n0
n22 --> n38
n22 --> n36
n22 --> n23
n22 --> n4
n8 -.-> n10
n19 -.-> n11
n45 -.-> n43
n48 -.-> n46
n9 -.-> n10
n20 -.-> n11
n44 -.-> n43
n47 -.-> n46
n32 --> n31
n32 --> n33
n3 --> n22
n6 -.-> n10
n18 -.-> n11
n39 --> n40
n30 --> n21
n12 -.-> n11
n13 -.-> n11
n26 --> n21
n36 --> n37
n42 --> n21
n4 --> n30
n14 -.-> n11
n29 --> n42
n23 --> n24
n28 --> n27
n24 --> n25
n27 --> n29
n31 --> n34
n5 -.-> n10
n41 --> n21
n25 --> n26
n16 -.-> n11
n37 --> n39
n0 --> n32
n15 -.-> n11
n17 -.-> n11
n7 -.-> n10
n38 --> n28
n43 -.-> n0
n40 --> n41
n10 -.-> n0
n11 -.-> n0
n46 -.-> n0
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 n3 trigger
class n0,n25,n29,n31 ai
class n2,n9,n20,n44,n47 aiModel
class n6,n10,n11,n18,n43,n46 ai
class n1,n8,n19,n45,n48 ai
class n21,n22,n32,n39 decision
class n5,n7,n12,n13,n14,n15,n16,n17 database
class n24,n27,n37 api
class n4,n34 code
classDef customIcon fill:none,stroke:none
class n3,n4,n23,n24,n27,n28,n33,n34,n35,n36,n37,n38 customIcon
The Challenge: WhatsApp Intake Is Unstructured (And It Spreads)
WhatsApp is great for speed. It’s terrible for consistency. One person sends a neat text message, the next sends a 2-minute voice note, and the next drops a blurry photo of a document with “can you check this?” Now you’re hunting for context, asking follow-up questions, and manually logging details into Google Sheets so the rest of the team can see what’s going on. The real cost isn’t just time. It’s the mental load of remembering what’s missing, plus the mistakes that happen when you’re doing copy-paste while multitasking.
None of these alone is the problem. Together, they are.
- Messages arrive in different formats, so your “intake process” changes every single time.
- Manual logging to Sheets steals focus, and it’s easy to miss a field or enter the wrong value.
- Follow-up questions get repetitive, which means response quality drops when the inbox gets busy.
- Audio, images, and PDFs force you to switch tools just to understand what the customer sent.
The Fix: Multi-Format WhatsApp Intake Logged to Google Sheets
This n8n workflow turns incoming WhatsApp messages into structured intake records and reliable replies. It starts the moment a message hits your WhatsApp Business API webhook, then routes it based on what the person actually sent (plain text, audio, image, or a document). Audio gets downloaded and transcribed, images can be analyzed for context, and PDFs can be extracted into readable text. From there, an AI “orchestrator” agent decides which specialized helper should handle the request, so intake, scheduling, and document review don’t all get mushed together. Finally, key details are summarized, logged into Google Sheets, and the workflow sends a consistent response back through WhatsApp (as text or audio).
The workflow starts with WhatsApp capture and normalization. Then it processes media into text, routes the conversation through the right AI agent, and stores the outcome in Google Sheets (with conversation memory so replies stay coherent). The sender gets a clean next-step message without you jumping into the thread.
What Changes: Before vs. After
| What This Eliminates | Impact You’ll See |
|---|---|
|
|
Real-World Impact
Say you handle 25 WhatsApp inquiries a day. Manually, you might spend about 5 minutes understanding the message (especially voice notes and screenshots) and another 3 minutes logging it into Google Sheets, which is roughly 3 hours daily. With this workflow, the “work” becomes reviewing a summary and a pre-drafted reply, usually under a minute per inquiry. That’s about 2 hours back each day, while your sheet stays up to date automatically.
Requirements
- n8n instance (try n8n Cloud free)
- Self-hosting option if you prefer (Hostinger works well)
- WhatsApp Business API to receive and send messages.
- Google Sheets to store intake and appointment records.
- OpenAI API key (get it from the OpenAI dashboard).
- PostgreSQL database for conversation memory across chats.
Skill level: Intermediate. You’ll connect credentials, confirm sheet columns, and test a few message types (text, audio, image, PDF).
Need help implementing this? Talk to an automation expert (free 15-minute consultation).
The Workflow Flow
A WhatsApp message arrives. The workflow triggers from your WhatsApp Business integration and immediately checks that there’s real input (so empty pings don’t waste executions).
The content gets normalized. Text messages are cleaned up, while audio is downloaded and transcribed, images are analyzed, and PDFs are extracted into readable text via HTTP download plus file extraction.
An AI orchestrator routes the request. A main agent decides which specialized “tool” should handle the conversation next, like patient registration, appointment scheduling, medical report analysis, or prescription review. Conversation memory keeps context across multiple back-and-forth messages.
Results get logged and a reply goes out. The workflow appends structured rows to Google Sheets (patient record, appointment record, lookups, IDs), then responds in WhatsApp as text or synthesized audio depending on the situation.
You can easily modify Google Sheets fields to match your intake form and swap the reply style to fit your brand voice. See the full implementation guide below for customization options.
Step-by-Step Implementation Guide
Step 1: Configure the WhatsApp Trigger
This workflow starts with WhatsApp inbound messages and routes them by media type.
- Add and open WhatsApp Entry Hook.
- Set the webhook configuration as needed; keep Updates to
messages. - Credential Required: Connect your
whatsAppTriggerApicredentials. - Confirm the execution flow: WhatsApp Entry Hook → Route by Media Type.
Step 2: Connect Google Sheets
Patient and appointment data is stored in Google Sheets using multiple tool nodes.
- Open Append Patient Record and verify Operation is
append. - Set the spreadsheet IDs where required, for example in Append Patient Record set Document ID to
REPLACE_WITH_YOUR_GOOGLE_SHEET_IDand Sheet Name to the “Patients” sheet. - Repeat for scheduling data: Append Appointment Record, Fetch Availability Slots, Get Last Appointment ID, Retrieve Clinic List, Retrieve Doctor List, Lookup Patient Record, and Fetch Last Patient ID.
- Credential Required: Connect your
googleSheetsOAuth2Apicredentials to all Google Sheets tool nodes (8+ nodes handle patient, appointment, clinic, and availability data).
REPLACE_WITH_YOUR_GOOGLE_SHEET_ID in any Sheets node will cause tool failures and the AI tools will return empty results.Step 3: Configure Media Routing and Normalization
The workflow routes messages by type and normalizes them into a consistent prompt for AI processing.
- In Route by Media Type, keep the rules that test for message payloads such as
={{ $json.messages[0].image }},={{ $json.messages[0].document }},={{ $json.messages[0].audio }}, and={{ $json.messages[0].text }}. - For text messages, verify Normalize Incoming Text outputs
sessionIdandchatInput, then Build Text Prompt sets mode totext. - For audio messages, ensure Fetch Audio URL uses
={{ $json.messages[0].audio.id }}, Download Audio File uses={{ $json.url }}, and Transcribe Audio Clip sends output into Build Audio Prompt with mode set toaudio. - For images, confirm Notify Image Analysis sends
Analyzing image…and then Fetch Image URL uses={{ $('WhatsApp Entry Hook').item.json.messages[0].image.id }}before Analyze Image Content builds the prompt. - For documents, check Fetch Document URL uses
={{ $json.messages[0].document.id }}, then Download Document File → Check PDF Type → Extract PDF Text → Build Document Prompt with mode set todocument.
={{ $json.url }}.Step 4: Set Up the AI Orchestration and Memory
The agent-driven AI layer controls scheduling, registration, reports, and prescription review with shared conversation memory.
- Open Appointment Orchestrator and confirm Text is
={{ $json.chatInput }}and the system prompt is set to the provided medical assistant instructions. - Credential Required: Connect your
openAiApicredentials to Primary LLM Chat, which is the language model for Appointment Orchestrator. - Credential Required: Connect your
postgrescredentials to Chat Memory Core (memory for the main agent). Keep Session Key as={{ $('Input Presence Check').item.json.sessionId }}. - Ensure sub-tools are wired to the parent agent: Patient Intake Tool, Scheduling Assistant Tool, Medical Report Tool, and Prescription Review Tool connect to Appointment Orchestrator as AI tools.
- For the AI tool sub-nodes, add credentials to their parent nodes: LLM Intake Model and Registration Memory belong to Patient Intake Tool; LLM Scheduler Model and Scheduler Memory belong to Scheduling Assistant Tool; LLM Report Model and Report Memory belong to Medical Report Tool; LLM Prescription Model and Prescription Memory belong to Prescription Review Tool.
Step 5: Configure WhatsApp and OpenAI Media Services
This workflow uses WhatsApp media endpoints and OpenAI for transcription, image analysis, and audio synthesis.
- Credential Required: Connect your
whatsAppApicredentials to all WhatsApp send/receive nodes (6+ nodes: Fetch Audio URL, Download Audio File, Fetch Image URL, Download Image File, Fetch Document URL, Download Document File, Notify Image Analysis, Send Text Reply, Send Audio Reply). - Credential Required: Connect your
openAiApicredentials to Transcribe Audio Clip, Analyze Image Content, and Synthesize Audio Reply. - In Analyze Image Content, keep the prompt text set to
=Please analyze this image and tell me what's in it. If it's a document, summarize the key details. If it's a photo, describe the contents.. - In Synthesize Audio Reply, keep Input as
={{ $json.output }}and Voice set tofable. - In Send Text Reply and Send Audio Reply, replace Phone Number ID with your WhatsApp business ID:
REPLACE_WITH_YOUR_PHONE_NUMBER_ID.
audio/mp3 to audio/mpeg before Send Audio Reply.Step 6: Configure Output Routing and Response Modes
The AI output is routed to text or audio responses based on the detected mode.
- Verify Input Presence Check uses the condition
={{ $json.chatInput }}and passes to Appointment Orchestrator. - In Response Mode Check, confirm the condition compares
={{ $('Input Presence Check').item.json.mode }}toaudio. - Ensure Response Mode Check routes to Synthesize Audio Reply (audio branch) and Send Text Reply (text branch).
- Confirm Adjust Audio MIME runs before Send Audio Reply in the audio path.
={{ $json.text }} or ={{ $json.content }}).Step 7: Test and Activate Your Workflow
Validate end-to-end messaging and AI responses before going live.
- Click Execute Workflow and send a WhatsApp message to your connected number.
- Verify that WhatsApp Entry Hook triggers and that Route by Media Type sends the payload to the correct branch.
- Confirm AI processing completes and that the output reaches Send Text Reply or Send Audio Reply.
- Successful execution should show a reply in WhatsApp and populated rows in your Sheets when registration or appointment actions occur.
- When you’re ready, toggle the workflow to Active for production use.
Watch Out For
- WhatsApp Business API credentials can expire or require specific permissions. If things break, check your WhatsApp app/dashboard access and webhook status first.
- If you’re using Wait nodes or external processing (transcription, vision, or PDF extraction), processing times vary. Bump up the wait duration if downstream nodes fail on empty responses.
- OpenAI prompts ship generic by default. Add your tone, disclaimers, and “what to ask next” rules early or you will be editing outputs forever.
Common Questions
About 30-45 minutes if your credentials are ready.
Yes, but you’ll want someone comfortable with connecting accounts and testing webhooks. Once it’s connected, day-to-day use is just “message comes in, sheet updates, reply goes out.”
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 costs (often a few cents per conversation, more with vision or long documents).
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.
Start by adjusting what gets written to Google Sheets in the “Append Patient Record” and “Append Appointment Record” parts of the workflow. You can also replace the OpenAI chat model nodes with a different model/provider while keeping the same routing logic in the “Appointment Orchestrator” agent. Common tweaks include changing the intake questions, adding a “priority” column for urgent cases, and forcing replies to always be text (instead of audio).
Usually it’s expired access tokens or a webhook mismatch. Confirm the WhatsApp Business API credentials inside n8n, then verify the webhook is still pointing to the right public URL. If media downloads fail, it can also be missing permissions to fetch audio/image/document URLs. Rate limiting can show up too when you suddenly process lots of messages at once, so retries matter.
On n8n Cloud, capacity depends on your plan’s monthly executions. If you self-host, there’s no hard execution cap (it mostly depends on your server size and WhatsApp/OpenAI limits). Practically, teams run this for dozens to a few hundred conversations per day without drama, as long as you keep an eye on media processing and API rate limits.
Often, yes. This workflow uses branching, multi-step routing, and conversation memory, which is where Zapier and Make can get clunky or expensive. n8n also lets you self-host for unlimited runs, and it’s more flexible when you need to handle files like PDFs, images, and audio. If your goal is only “WhatsApp message → new row in Sheets,” Zapier/Make can be fine. If you want agents, media handling, and real logic, n8n is the better fit. Talk to an automation expert if you want a quick recommendation for your exact setup.
Once this is running, your WhatsApp inbox stops being a liability and starts acting like a real intake channel. The workflow handles the repetitive sorting, summarizing, logging, and replying so you can focus on the conversations that actually need a human.
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.