How to build a powerful, no-code appointment scheduler Agent using WhatsApp, Google tools, and AI for any service-based business
Booking appointments manually is time-consuming and error-prone. What if you could fully automate the process through WhatsApp, offer available time slots in real-time, store customer data, and send confirmations instantly? In this article, I’ll walk you through building a complete appointment booking system using n8n, Google Calendar, Google Sheets, Gmail, and OpenAI, all triggered by WhatsApp messages.
Whether you’re a consultant, therapist, clinic, or salon owner, this system adapts to your workflow without writing a single line of code.
Download the Workflow JSON and use it!
🔧 Tools You’ll Need
- n8n: A powerful open-source workflow automation tool
- Wassenger: For receiving and sending WhatsApp messages
- Google Calendar: To manage and check availability
- Google Sheets: To store client data and appointment details
- Gmail: For sending confirmation emails
- OpenAI (ChatGPT): For conversation and voice-to-text transcription
Start transforming how your business handles scheduling with WhatsApp and AI, no coding required.
✅ Register your WhatsApp number on Wassenger✅ Download the complete JSON workflow to plug into your n8n instance✅ Start booking appointments automatically in minutes
🔢 The Workflow Overview
The process follows this structure:
- Trigger: A user sends a WhatsApp message
- Detect message type: Text or voice
- Transcribe voice (if needed)
- AI Agent: Responds naturally and collects data
- Google Sheets: Stores or updates user data
- Google Calendar: Offers available appointment slots
- User confirms
- A calendar event is created
- Confirmation email is sent
Let’s break it down step-by-step.
1. 📲 WhatsApp Message Trigger
Use the Wassenger Trigger node to listen for incoming messages. This connects your n8n instance to your WhatsApp business number. The trigger captures both text and voice notes.
2. ⚙️ Switch Node: Text vs Audio
Next, use a Switch node to detect if the incoming message is a text or audio file. If it’s audio, use an HTTP Request node to download it and then pass it to OpenAI’s Whisper model via the Transcribe Audio node.
Start transforming how your business handles scheduling with WhatsApp and AI, no coding required.
✅ Register your WhatsApp number on Wassenger✅ Download the complete JSON workflow to plug into your n8n instance✅ Start booking appointments automatically in minutes
3. 🤖 Chat with AI Agent
Pass the text (from user or transcribed audio) to an AI Agent node using the LangChain integration in n8n. This agent:
- Analyses user intent
- Responds naturally
- Asks if they want to book an appointment
If yes, it collects:
- Email (used as unique ID)
- Name
- Phone number
Each field is captured one at a time and stored in Google Sheets using Add Row or Update Row.
Get the AI Agent instructions free at the JSON file available from our app
4. 📄 Google Sheets Integration
The AI Agent checks if the email already exists in the sheet:
- If yes, updates the row
- If no, add a new one
It also stores discussion topics or appointment notes once the user mentions them.
Start transforming how your business handles scheduling with WhatsApp and AI, no coding required.
✅ Register your WhatsApp number on Wassenger✅ Download the complete JSON workflow to plug into your n8n instance✅ Start booking appointments automatically in minutes
5. ⏰ Offer Available Time Slots
The system uses the Google Calendar Tool to fetch free 30-minute time blocks during working hours:
- Monday–Friday
- 09:00–12:00 and 13:00–17:00
Only future time slots (24 h+ ahead) that don’t conflict with existing events are offered. The assistant formats the reply in a friendly list:
Here are the next available appointments:
- Thursday at 10:00 AM
- Friday at 11:30 AM
...
6. 📝 Confirm & Save Appointment
Once the user selects a slot:
- The AI creates a Google Calendar event
- Updates the user’s row in Google Sheets
- Marks the appointment as “Confirmed”
All stored times are saved in the assistant’s time zone (e.g., Germany) but presented to the user in their local time (e.g., London).
7. 📧 Send Confirmation Email
Finally, a confirmation email is sent to the user via Gmail. It includes:
- Appointment time (in user’s local time)
- Their name
- Discussion topic
Start transforming how your business handles scheduling with WhatsApp and AI, no coding required.
✅ Register your WhatsApp number on Wassenger✅ Download the complete JSON workflow to plug into your n8n instance✅ Start booking appointments automatically in minutes
Copy and save this code as JSON and upload it into your n8n instance
{
"name": "WhatsApp Appointment Setter",
"nodes": [
{
"parameters": {
"events": ["message:in:new"]
},
"type": "n8n-nodes-wassenger.wassengerTrigger",
"typeVersion": 1,
"position": [1080, 700],
"id": "2c24ff1f-8b4d-4341-b2c7-c81ba4c2208c",
"name": "Wassenger Trigger",
"webhookId": "83130e74-a519-4153-b901-f03769d2f04f",
"credentials": {
"wassengerApiKey": {
"id": "9du3UAbFSzEaTSQE",
"name": "WhatsApp API key"
}
}
},
{
"parameters": {
"promptType": "define",
"text": "={{ $json.data.body }}",
"options": {
"systemMessage": "=You are a helpful assistant for a dental clinic based in London.\n\n# You have access to these tools:\n\n1.A Google Calendar Tool that allows you to create, reschedule, and delete events in the calendar.\n\n2.Google Sheets Tools:\n\n- Google Sheet - Add Row: Adds a new row to a Google Sheet.\n\n- Google Sheet - Update Row: Updates a row in the Google Sheet.\n\n- Google Sheet - Read: Reads content from the Google Sheet.\n\n3.Gmail - Send Confirmation User: Sends a confirmation email to the user after the appointment is confirmed.\n\nThe current time and date is in the German Time Zone:\n{{ $now }}\n\n# Your Task: \n\n1.When the conversation starts:\n\nAnalyze the first message sent by the user.\n\nRespond naturally based on its intent, tone, or content(for example: greeting, question, or request).\n\nKeep your reply short, polite, and friendly.\n\nThen, follow up with:\n\"Would you like to book an appointment?\"\n\nExamples:\n\nIf the user says: “Hi, how are you?”\n→ Respond: “I'm doing great, thanks for asking! Would you like to book an appointment?”\n\nIf the user says: “I need help with pricing”\n→ Respond: “Happy to help! Would you like to book an appointment so we can discuss it?”\n\nIf the user responds with yes, begin collecting their contact information.\n\nYou must collect the information in the following strict order:\n\n- First: Email address\n > This is used as the unique identifier for matching rows in the Google Sheet.\n > After receiving the email: Use \"Google Sheet - Read\" to check if the email exists.\n\nIf it exists, use Google Sheet - Update Row to update that row.\n\nIf it does not exist, use Google Sheet - Add Row to create a new one.\n\n- Then: Full name \n- Then: Confirm the phone number with the patient taken from:\n{{ $('Wassenger Trigger').item.json.data.fromNumber }}\n\nGuidelines:\n\n! Ask for only one piece of information at a time.\n! Wait for the user's response before asking the next question.\n! After every response, immediately update the Google Sheet using Google Sheet - Update Row, matched by the email address.\n\n2.You must always store all the user information(email address, name, phone number) in the Google Sheet.\n\nAfter collecting the information, ask the user:\n\"What would you like to discuss during your appointment?\"\n\n- Wait for their response.\n- Update the row in the Google Sheet with the topic or notes field using Google Sheet - Update Row to save the response as the appointment topic or notes.\n\n3.Offering Appointment Slots \nOnce the user's contact details and discussion topic have been collected:\n\nOffer 5 available time slots.\n\n- Use the assistant's local time zone(London) to determine available hours.\n\nOffice hours:\n\nMonday to Friday \nMorning: 09:00 to 12:00 \nAfternoon: 13:00 to 17:00\n\nDo not offer any times between 12:00 and 13:00.\n\nImportant:\n\n- Only offer time slots that fall within the office hours listed above.\n- You must check that a full 30-minute block is available:\n - The start and end time must not conflict with any existing calendar event.\n - The time slot must begin at least 24 hours in the future.\n\n- Always offer the next 5 available 30-minute time slots that meet the above criteria.\n\n- Only display the time slots in the user’s time zone(London time).\n Do not mention time conversions or other time zones in your response.\n\n- Present the time slots in a simple, friendly format like: \n \"Here are the next available appointments for you: \n - Thursday at 10:00 AM \n - Friday at 11:30 AM \n...\"\n\n- If no valid slots match the user's requested period(e.g., afternoon), politely inform the user and offer the next closest options.\n\n- Never mention unavailable or already booked time slots.\n Only show the free ones.\n\n! You must not manually calculate or estimate time zone offsets.\nUse the Google Calendar tool to convert and format times.\n\n4.When the user confirms a preferred date and time, you must:\n\nCreate an event in the Google Calendar at the selected time.\n\nAppointments should always be scheduled for 30 minutes unless the user specifies otherwise.\n\nDo not create a new row in the Google Sheet.\n\nInstead, use \"Google Sheet - Update Row\" to update the existing row corresponding to the user(matched by email address), and add the selected date and time as the confirmed appointment.\n\nThe appointment time saved in the Google Sheet must always be in the assistant's local time(German time) — never in the user's time zone.\n\nAfter the booking is confirmed, send a confirmation email to the user using the \"Gmail - Send Confirmation User\" tool.\n\nThe email must include:\n\n- The confirmed appointment date and time(in London time) \n- The user's name and topic of discussion \n- A short, friendly message confirming the booking\n\nOnly send the confirmation email after the calendar event has been created and all data has been stored in the Google Sheet."
}
},
"type": "@n8n/n8n-nodes-langchain.agent",
"typeVersion": 1.8,
"position": [2440, 720],
"id": "2df07709-f74d-4816-8969-141a8502cc64",
"name": "AI Agent"
},
{
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "gpt-4o-mini"
},
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"typeVersion": 1.2,
"position": [2040, 960],
"id": "5b974204-0b48-483a-9306-9f8a53bf0aa7",
"name": "OpenAI Chat Model"
},
{
"parameters": {
"sessionIdType": "customKey",
"sessionKey": "={{ $('Message Type') }}",
"contextWindowLength": 20
},
"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
"typeVersion": 1.3,
"position": [2200, 960],
"id": "7f3c1455-c110-48f0-b330-7da555dce523",
"name": "Simple Memory"
},
{
"parameters": {
"operation": "getAll",
"calendar": {
"__rl": true,
"value": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Calendar', ``, 'string') }}",
"mode": "id",
"__regex": "(^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*)"
},
"options": {}
},
"type": "n8n-nodes-base.googleCalendarTool",
"typeVersion": 1.3,
"position": [2340, 960],
"id": "a02cdef3-2958-4a31-b033-3c7472e6262e",
"name": "Calendar Read",
"credentials": {
"googleCalendarOAuth2Api": {
"id": "LL4HXXOSECspo8kd",
"name": "Google Calendar account"
}
}
},
{
"parameters": {
"calendar": {
"__rl": true,
"value": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Calendar', ``, 'string') }}",
"mode": "id"
},
"additionalFields": {}
},
"type": "n8n-nodes-base.googleCalendarTool",
"typeVersion": 1.3,
"position": [2480, 960],
"id": "5bf56efe-4e6a-496f-992e-9463184d5a31",
"name": "Calendar Create"
},
{
"parameters": {
"operation": "delete",
"calendar": {
"__rl": true,
"value": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Calendar', ``, 'string') }}",
"mode": "id"
},
"eventId": "={{ fromAI(\"id\", \"the id of the event\") }}",
"options": {}
},
"type": "n8n-nodes-base.googleCalendarTool",
"typeVersion": 1.3,
"position": [2620, 960],
"id": "3d4e631b-c9ef-43d7-b159-d5a677ee0e71",
"name": "Calendar Delete"
},
{
"parameters": {
"documentId": {
"__rl": true,
"value": "1CTk-H0P6-ca8NK3T79_KL6LS0_7Xq8bVOP1Ldun281Q",
"mode": "list",
"cachedResultName": "Appointment Setter",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1CTk-H0P6-ca8NK3T79_KL6LS0_7Xq8bVOP1Ldun281Q/edit?usp=drivesdk"
},
"sheetName": {
"__rl": true,
"value": "gid=0",
"mode": "list",
"cachedResultName": "Sheet1",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1CTk-H0P6-ca8NK3T79_KL6LS0_7Xq8bVOP1Ldun281Q/edit#gid=0"
},
"options": {
"dataLocationOnSheet": {
"values": {
"rangeDefinition": "detectAutomatically",
"readRowsUntil": "firstEmptyRow"
}
},
"outputFormatting": {
"values": {
"general": "UNFORMATTED_VALUE",
"date": "FORMATTED_STRING"
}
}
}
},
"type": "n8n-nodes-base.googleSheetsTool",
"typeVersion": 4.5,
"position": [2760, 960],
"id": "f405d7a1-b830-4030-87a4-c9726f012661",
"name": "Google Sheets"
},
{
"parameters": {
"operation": "append",
"documentId": {
"__rl": true,
"value": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Document', ``, 'string') }}",
"mode": "id"
},
"sheetName": {
"__rl": true,
"value": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Sheet', ``, 'string') }}",
"mode": "id"
},
"columns": {
"mappingMode": "defineBelow",
"value": {
"Email": "={{ $fromAI(\"email\", \"the email address that the user tells you\") }}"
},
"matchingColumns": [],
"schema": [
{
"id": "Appointment Date",
"displayName": "Appointment Date",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": true
},
{
"id": "Booking Status",
"displayName": "Booking Status",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": true
},
{
"id": "Time Zone",
"displayName": "Time Zone",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": true
},
{
"id": "Name",
"displayName": "Name",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": true
},
{
"id": "Phone",
"displayName": "Phone",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": true
},
{
"id": "Email",
"displayName": "Email",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "Intake Form",
"displayName": "Intake Form",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": true
},
{
"id": "Reminder Sent",
"displayName": "Reminder Sent",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": true
}
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {}
},
"type": "n8n-nodes-base.googleSheetsTool",
"typeVersion": 4.5,
"position": [2900, 960],
"id": "42769806-5ad3-4d01-b119-6002bd6e44aa",
"name": "Google Sheets - Add rows"
},
{
"parameters": {
"operation": "update",
"documentId": {
"__rl": true,
"value": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Document', ``, 'string') }}",
"mode": "id"
},
"sheetName": {
"__rl": true,
"value": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Sheet', ``, 'string') }}",
"mode": "id"
},
"columns": {
"mappingMode": "defineBelow",
"value": {
"Email": "={{ $fromAI(\"email\", \"the email address that the user tells you\") }}",
"Appointment Date": "={{ $fromAI(\"date\", \"the appointment date and time converted to Central European Time that the user confirmed as his appointment\") }}",
"Booking Status": "={{ $fromAI(\"status\", \"the status of the appointment which is either confirmed or cancelled\") }}",
"Time Zone": "={{ $fromAI(\"timeZone\", \"the time zone and location the the user tells you\") }}",
"Name": "={{ $fromAI(\"name\", \"the name of the user\") }}",
"Phone": "={{ $fromAI(\"phone\", \"the phone number that the user tells you.\") }}",
"Intake Form": "={{ $fromAI(\"intake_form\", \"specific topics or issues the user likes to discuss during the appointment\") }}"
},
"matchingColumns": ["Email"],
"schema": [
{
"id": "Appointment Date",
"displayName": "Appointment Date",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": false
},
{
"id": "Booking Status",
"displayName": "Booking Status",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": false
},
{
"id": "Time Zone",
"displayName": "Time Zone",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": false
},
{
"id": "Name",
"displayName": "Name",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": false
},
{
"id": "Phone",
"displayName": "Phone",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": false
},
{
"id": "Email",
"displayName": "Email",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": false
},
{
"id": "Intake Form",
"displayName": "Intake Form",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": false
},
{
"id": "Reminder Sent",
"displayName": "Reminder Sent",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": true
},
{
"id": "row_number",
"displayName": "row_number",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"readOnly": true,
"removed": true
}
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {}
},
"type": "n8n-nodes-base.googleSheetsTool",
"typeVersion": 4.5,
"position": [3060, 960],
"id": "ad4b0c89-bfd2-4016-b9ff-599178632e75",
"name": "Google Sheets - Update Row"
},
{
"parameters": {
"sendTo": "={{ $fromAI(\"email\", \"the email address provided by the user earlier\") }}",
"subject": "={{ $fromAI(\"subject\", \"the email subjectline that just is [New Booking] + Booking date and time converted to Local Timezone that the user confirmed as this appointment\") }}",
"message": "={{ $fromAI(\"body\", \"the email body taht contains the message that the booking if thge user was confirmed along with booking date, email, name, timezone, what user wants to discuss during the appointment\") }}",
"options": {
"bccList": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('BCC', ``, 'string') }}"
}
},
"type": "n8n-nodes-base.gmailTool",
"typeVersion": 2.1,
"position": [3180, 960],
"id": "0510a247-2e16-4746-88ef-cf70a61ad409",
"name": "Gmail",
"webhookId": "6244c414-188e-4e55-a323-145b5238faf2"
},
{
"parameters": {
"url": "=https://api.wassenger.com{{ $('Wassenger Trigger').item.json.data.media.links.download }}",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"options": {}
},
"id": "d85d8848-4a0a-44e2-8f33-032a51302f98",
"name": "Download Audio",
"type": "n8n-nodes-base.httpRequest",
"position": [1640, 360],
"typeVersion": 4.2,
"credentials": {
"httpHeaderAuth": {
"id": "GTzBwI8uSTXV0UvT",
"name": "Header Auth account"
}
}
},
{
"parameters": {
"resource": "audio",
"operation": "transcribe",
"options": {}
},
"id": "1637b236-94ea-4270-a0bf-980a8f3db218",
"name": "Transcribe Audio",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [1880, 360],
"typeVersion": 1.8,
"credentials": {
"openAiApi": {
"id": "LOYODT0dLN0xy31E",
"name": "OpenAi account"
}
}
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "219577d5-b028-48fc-90be-980f4171ab68",
"name": "data.body",
"type": "string",
"value": "={{ $json.text }}"
}
]
},
"options": {}
},
"id": "ed7c9be2-bf82-4374-93af-3b40e9c0f1c1",
"name": "Audio Info",
"type": "n8n-nodes-base.set",
"position": [2120, 360],
"typeVersion": 3.4
},
{
"parameters": {
"device": "66d1a54430541033576feca2",
"phone": "={{ $('Wassenger Trigger').item.json.data.fromNumber }}",
"message": "={{ $json.output }}",
"options": {}
},
"type": "n8n-nodes-wassenger.wassenger",
"typeVersion": 1,
"position": [3020, 720],
"id": "b2547711-f27a-43f0-8adb-f9d9e7606bd4",
"name": "Send Message",
"credentials": {
"wassengerApiKey": {
"id": "9du3UAbFSzEaTSQE",
"name": "WhatsApp API key"
}
}
},
{
"parameters": {
"rules": {
"values": [
{
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"leftValue": "={{ $json.data.media.type }}",
"rightValue": "audio",
"operator": {
"type": "string",
"operation": "equals"
},
"id": "94a56d29-cb88-4eb0-8d6b-07b1b91bfc3f"
}
],
"combinator": "and"
},
"renameOutput": true,
"outputKey": "Voice message"
},
{
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "6ce0d87f-bdfc-4c65-a3fb-8d86bb682c4e",
"leftValue": "={{ $json.data.type }}",
"rightValue": "text",
"operator": {
"type": "string",
"operation": "equals"
}
}
],
"combinator": "and"
},
"renameOutput": true,
"outputKey": "Text message"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.switch",
"typeVersion": 3.2,
"position": [1320, 700],
"id": "3df50a7f-5ab3-421d-939b-ebb762a451ce",
"name": "Message Type"
},
{
"parameters": {
"content": "📅 WhatsApp Appointment Booking Workflow(n8n)\nThis n8n workflow automates appointment scheduling through WhatsApp for any business offering time-based services(e.g.clinics, consultancies, salons, etc.).It combines AI-driven messaging with Google services to streamline the entire booking process.\n\n🔧 Tools & Services Used\nWassenger Trigger: Captures incoming WhatsApp messages.\n\nLangchain AI Agent: Manages the conversational flow, understands intent, and gathers required info.\n\nGoogle Calendar: Checks for availability and books appointments.\n\nGoogle Sheets: Stores and updates client records and booking info.\n\nGmail: Sends personalized appointment confirmations.\n\nOpenAI(gpt-4o-mini): Generates intelligent and friendly chat replies.\n\nAudio Transcription(Optional): Converts voice messages to text for processing.\n\n📋 Step-by-Step Workflow Description\n1.Trigger: Incoming WhatsApp Message\nThe flow starts when a new message(text or voice) is received via Wassenger.\n\n2.Message Type Detection\nThe system checks whether the message is:\n\nText: Processes it directly.\n\nVoice: Downloads and transcribes it using OpenAI.\n\n3.AI Agent Engagement\nThe AI assistant analyzes the first message and responds naturally.\n\nIt then asks if the user would like to book an appointment.\n\nIf the user agrees, it collects the following information in strict order:\n\nEmail address(used as a unique identifier)\n\nFull name\n\nPhone number\n\nAfter each input, the AI updates Google Sheets(adding or updating rows as needed).\n\n4.Purpose of Appointment\nThe assistant asks what the user would like to discuss during the appointment.\n\nThis input is recorded in the sheet as notes or discussion topic.\n\n5.Appointment Slot Offering\nThe system checks Google Calendar for available 30-minute time blocks.\n\nOnly time slots during business hours are offered:\n\nMonday to Friday\n\nMorning: 09:00–12:00\n\nAfternoon: 13:00–17:00(noon hour excluded)\n\nThe next 5 available slots(at least 24h in the future) are displayed in the user’s local time(e.g., London).\n\n6.Appointment Confirmation\nOnce the user picks a time:\n\nA calendar event is created.\n\nThe associated Google Sheets row is updated with the confirmed date/time(stored in system time).\n\nA confirmation email is sent via Gmail.\n\n🕒 Timezone Notes\nUsers are assumed to be in a fixed known timezone(e.g., London).\n\nInternally, scheduling and calendar checks are based on a consistent system timezone(e.g., German time).\n\n✅ Key Benefits\nFully automated booking via WhatsApp — no human intervention needed.\n\nWorks with both text and voice messages.\n\nEliminates double bookings by checking calendar availability.\n\nCentralized data collection in Google Sheets.\n\nProfessional email confirmations sent instantly.",
"height": 1700,
"width": 700
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [180, -100],
"id": "d5c7f667-e407-48e1-8403-91ed141bfb10",
"name": "Sticky Note"
}
],
"pinData": {},
"connections": {
"Wassenger Trigger": {
"main": [
[
{
"node": "Message Type",
"type": "main",
"index": 0
}
]
]
},
"AI Agent": {
"main": [
[
{
"node": "Send Message",
"type": "main",
"index": 0
}
]
]
},
"OpenAI Chat Model": {
"ai_languageModel": [
[
{
"node": "AI Agent",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Simple Memory": {
"ai_memory": [
[
{
"node": "AI Agent",
"type": "ai_memory",
"index": 0
}
]
]
},
"Calendar Read": {
"ai_tool": [
[
{
"node": "AI Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Calendar Create": {
"ai_tool": [
[
{
"node": "AI Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Calendar Delete": {
"ai_tool": [
[
{
"node": "AI Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Google Sheets": {
"ai_tool": [
[
{
"node": "AI Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Google Sheets - Add rows": {
"ai_tool": [
[
{
"node": "AI Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Google Sheets - Update Row": {
"ai_tool": [
[
{
"node": "AI Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Gmail": {
"ai_tool": [
[
{
"node": "AI Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Download Audio": {
"main": [
[
{
"node": "Transcribe Audio",
"type": "main",
"index": 0
}
]
]
},
"Transcribe Audio": {
"main": [
[
{
"node": "Audio Info",
"type": "main",
"index": 0
}
]
]
},
"Audio Info": {
"main": [
[
{
"node": "AI Agent",
"type": "main",
"index": 0
}
]
]
},
"Message Type": {
"main": [
[
{
"node": "Download Audio",
"type": "main",
"index": 0
}
],
[
{
"node": "AI Agent",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "d011fa51-2f82-43cb-944a-97cd6e1004f6",
"meta": {
"templateCredsSetupCompleted": true,
"instanceId": "c0c412df2bcbb328d1da93d511311c0daafeaf44d260c460a12fb00a2f795b04"
},
"id": "qoOnTL7CBgGV7DSC",
"tags": []
}
🔍 Why This Works
This system offers:
- 24/7 intelligent WhatsApp booking
- Voice support via transcription
- Calendar conflict avoidance
- Dynamic slot suggestions
- No-code extensibility
With this setup, you’ve created an AI-powered WhatsApp assistant that saves time, improves user experience, and ensures your calendar stays organised. All without hiring staff or writing code.
Have questions or want to expand the workflow with reminders or cancellations? Let me know in the comments!
🚀 Get Started Today
To replicate this workflow:
- Register on Wassenger to connect your WhatsApp Business number.
- Use n8n Cloud or the self-hosted version.
- Download the complete JSON workflow template to get started instantly.
Have questions or want to expand the workflow with reminders or cancellations? Let me know in the comments!













