WhatsApp appointment booking AI agent
Customers book appointments on WhatsApp in their own dialect — the agent checks your calendar, books the slot and tells your team.
How it works
- A customer asks to book on WhatsApp.
- The agent checks your calendar and offers 2–3 free slots within opening hours.
- It repeats the day, time and service, then books the appointment.
- It alerts your team on Telegram about the new booking.
What it can do
Unlike a fixed flow, an agent decides which of its tools to use, in what order — and remembers the conversation.
- Books in Egyptian, Gulf or Standard Arabic — or English
- Offers only real free slots from your calendar
- Answers questions about your services and prices
- Saves the customer's phone in the booking, so the WhatsApp reminder flow works automatically
- Passes cancellations and changes to your team
System prompt
The instructions that shape the agent. It's already inside the n8n template — copy it into Make or Zapier, and adjust the YOUR_… parts.
You are the WhatsApp booking assistant for YOUR_BUSINESS (a clinic, salon or studio).
Today is {{ $now.toFormat('cccc d LLLL yyyy, HH:mm') }}. Our timezone is YOUR_TIMEZONE. Opening hours: YOUR_OPENING_HOURS. Each appointment is YOUR_DURATION minutes. Services and prices: YOUR_SERVICES.
Reply in the customer's language and dialect (Egyptian Arabic, Gulf Arabic, Modern Standard Arabic or English). Be warm and brief.
Tools:
- "Check free slots": lists booked appointments in a time range. Use it to find free slots within opening hours, then offer 2–3 options.
- "Book appointment": books a confirmed slot. Use it only after the customer picks a time and gives their name and the service.
- "Notify team": alerts our team about every new booking, cancellation request, or question you can't answer.
Rules:
- Never invent services, prices or free slots — always check the calendar first.
- Never give medical, legal or other professional advice; offer to book an appointment instead.
- Repeat the day, time and service back to the customer before booking.
- For cancellations or changes, use "Notify team" and tell the customer the team will confirm.Safety rules
Built into the prompt and the tools:
- Never invents services, prices or free slots
- Never gives medical or professional advice
- Confirms day, time and service before booking
Uses your own AI key (Claude, OpenAI or another model). Cost depends on the model and conversation length — a small, fast model keeps most conversations to a fraction of a cent.
Diagram
Code
JavaScript used in the Code step — already included in the template below.
// Keeps only text messages and pulls out who sent it and what they asked.
const msg = $input.first().json.messages?.[0];
if (!msg || msg.type !== "text") return [];
return [{ json: { from: msg.from, question: msg.text.body } }];Build it
Pick your tool — same automation, step by step.
Copy and paste straight into an n8n canvas (Ctrl+V), or download and use Import from File. Then connect your own credentials and replace every YOUR_… placeholder. AI steps use a Claude model node — swap it for OpenAI, Gemini or Ollama if you prefer.
Show code (284 lines)
{
"name": "WhatsApp appointment booking AI agent (Flowngn)",
"nodes": [
{
"parameters": {
"content": "## WhatsApp appointment booking AI agent\nCustomers book appointments on WhatsApp in their own dialect — the agent checks your calendar, books the slot and tells your team.\n\n**Setup**\n1. Open each node and connect your own credentials.\n2. Replace every YOUR_… placeholder.\n3. Test once, then activate.\n\nFree template from Flowngn",
"height": 260,
"width": 340
},
"id": "3f36c28d-dcaa-4fe7-afb0-dde2cffcb7d1",
"name": "Setup notes",
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
-420,
-60
]
},
{
"parameters": {
"updates": [
"messages"
]
},
"id": "3f36c28d-dcaa-4fe7-afb0-dde2cffcb7d1",
"name": "Incoming message",
"type": "n8n-nodes-base.whatsAppTrigger",
"typeVersion": 1,
"position": [
0,
0
],
"webhookId": "3f36c28d-dcaa-4fe7-afb0-dde2cffcb7d1"
},
{
"parameters": {
"jsCode": "// Keeps only text messages and pulls out who sent it and what they asked.\nconst msg = $input.first().json.messages?.[0];\nif (!msg || msg.type !== \"text\") return [];\n\nreturn [{ json: { from: msg.from, question: msg.text.body } }];"
},
"id": "3f36c28d-dcaa-4fe7-afb0-dde2cffcb7d1",
"name": "Get question",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
300,
0
]
},
{
"parameters": {
"promptType": "define",
"text": "={{ $json.question }}",
"options": {
"systemMessage": "=You are the WhatsApp booking assistant for YOUR_BUSINESS (a clinic, salon or studio).\n\nToday is {{ $now.toFormat('cccc d LLLL yyyy, HH:mm') }}. Our timezone is YOUR_TIMEZONE. Opening hours: YOUR_OPENING_HOURS. Each appointment is YOUR_DURATION minutes. Services and prices: YOUR_SERVICES.\n\nReply in the customer's language and dialect (Egyptian Arabic, Gulf Arabic, Modern Standard Arabic or English). Be warm and brief.\n\nTools:\n- \"Check free slots\": lists booked appointments in a time range. Use it to find free slots within opening hours, then offer 2–3 options.\n- \"Book appointment\": books a confirmed slot. Use it only after the customer picks a time and gives their name and the service.\n- \"Notify team\": alerts our team about every new booking, cancellation request, or question you can't answer.\n\nRules:\n- Never invent services, prices or free slots — always check the calendar first.\n- Never give medical, legal or other professional advice; offer to book an appointment instead.\n- Repeat the day, time and service back to the customer before booking.\n- For cancellations or changes, use \"Notify team\" and tell the customer the team will confirm."
}
},
"id": "3f36c28d-dcaa-4fe7-afb0-dde2cffcb7d1",
"name": "Booking agent",
"type": "@n8n/n8n-nodes-langchain.agent",
"typeVersion": 1.9,
"position": [
600,
0
]
},
{
"parameters": {
"model": {
"__rl": true,
"value": "claude-sonnet-5",
"mode": "list"
},
"options": {}
},
"id": "3f36c28d-dcaa-4fe7-afb0-dde2cffcb7d1",
"name": "Claude model",
"type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
"typeVersion": 1.3,
"position": [
260,
220
]
},
{
"parameters": {
"sessionIdType": "customKey",
"sessionKey": "={{ $('Get question').item.json.from }}",
"contextWindowLength": 10
},
"id": "3f36c28d-dcaa-4fe7-afb0-dde2cffcb7d1",
"name": "Memory",
"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
"typeVersion": 1.3,
"position": [
430,
220
]
},
{
"parameters": {
"descriptionType": "manual",
"toolDescription": "Lists booked appointments between two dates, so you can find free slots within opening hours.",
"operation": "getAll",
"calendar": {
"__rl": true,
"value": "primary",
"mode": "id"
},
"returnAll": true,
"timeMin": "={{ $fromAI('start', \"Start of the time range, ISO 8601\", 'string') }}",
"timeMax": "={{ $fromAI('end', \"End of the time range, ISO 8601\", 'string') }}",
"options": {
"singleEvents": true,
"orderBy": "startTime"
}
},
"id": "3f36c28d-dcaa-4fe7-afb0-dde2cffcb7d1",
"name": "Check free slots",
"type": "n8n-nodes-base.googleCalendarTool",
"typeVersion": 1.3,
"position": [
600,
220
]
},
{
"parameters": {
"descriptionType": "manual",
"toolDescription": "Books a confirmed appointment in the calendar.",
"calendar": {
"__rl": true,
"value": "primary",
"mode": "id"
},
"start": "={{ $fromAI('start', \"Appointment start, ISO 8601 with timezone\", 'string') }}",
"end": "={{ $fromAI('end', \"Appointment end, ISO 8601 with timezone\", 'string') }}",
"additionalFields": {
"summary": "={{ $fromAI('title', \"Customer name - service, e.g. Sara - Haircut\", 'string') }}",
"description": "=Phone: +{{ $('Get question').item.json.from }}\nBooked via WhatsApp agent"
}
},
"id": "3f36c28d-dcaa-4fe7-afb0-dde2cffcb7d1",
"name": "Book appointment",
"type": "n8n-nodes-base.googleCalendarTool",
"typeVersion": 1.3,
"position": [
770,
220
]
},
{
"parameters": {
"descriptionType": "manual",
"toolDescription": "Sends a message to our team's Telegram group: new bookings, cancellation requests, or questions you can't answer.",
"chatId": "YOUR_TEAM_CHAT_ID",
"text": "={{ $fromAI('message', \"What the team needs to know, including the customer's phone\", 'string') }}",
"additionalFields": {
"appendAttribution": false
}
},
"id": "3f36c28d-dcaa-4fe7-afb0-dde2cffcb7d1",
"name": "Notify team",
"type": "n8n-nodes-base.telegramTool",
"typeVersion": 1.2,
"position": [
940,
220
]
},
{
"parameters": {
"operation": "send",
"phoneNumberId": "YOUR_PHONE_NUMBER_ID",
"recipientPhoneNumber": "={{ $('Get question').item.json.from }}",
"textBody": "={{ $json.output }}"
},
"id": "3f36c28d-dcaa-4fe7-afb0-dde2cffcb7d1",
"name": "Reply on WhatsApp",
"type": "n8n-nodes-base.whatsApp",
"typeVersion": 1,
"position": [
900,
0
]
}
],
"connections": {
"Incoming message": {
"main": [
[
{
"node": "Get question",
"type": "main",
"index": 0
}
]
]
},
"Get question": {
"main": [
[
{
"node": "Booking agent",
"type": "main",
"index": 0
}
]
]
},
"Booking agent": {
"main": [
[
{
"node": "Reply on WhatsApp",
"type": "main",
"index": 0
}
]
]
},
"Claude model": {
"ai_languageModel": [
[
{
"node": "Booking agent",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Memory": {
"ai_memory": [
[
{
"node": "Booking agent",
"type": "ai_memory",
"index": 0
}
]
]
},
"Check free slots": {
"ai_tool": [
[
{
"node": "Booking agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Book appointment": {
"ai_tool": [
[
{
"node": "Booking agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Notify team": {
"ai_tool": [
[
{
"node": "Booking agent",
"type": "ai_tool",
"index": 0
}
]
]
}
},
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"meta": {
"templateCredsSetupCompleted": false
},
"tags": []
}In Make, create a new scenario and add these modules in order:
- WhatsApp Business Cloud › Watch Events (messages)
- Tools › Set variable / Iterator + Array aggregator (same logic as the Code step)
- Make AI Agents › Run an agent — give it these tools: “Check free slots” (Google Calendar), “Book appointment” (Google Calendar), “Notify team” (Telegram Bot); paste the system prompt as the agent's instructions
- WhatsApp Business Cloud › Send a Message
- Every module run uses Make operations — the free plan includes a monthly quota.
- Make's built-in functions (map, sum, formatDate…) can replace most Code steps; for complex logic use a code module.
- Module and step names can differ slightly as Make and Zapier update their apps.
In Zapier, create a new Zap and add these steps in order:
- WhatsApp — New Message
- Code by Zapier — Run JavaScript (paste the code from the Code section)
- Zapier Agents — create an agent (or AI by Zapier for a single step) — give it these tools: “Check free slots” (Google Calendar), “Book appointment” (Google Calendar), “Notify team” (Telegram); paste the system prompt as the agent's instructions
- WhatsApp — Send Message
- Zaps with more than two steps need a paid Zapier plan.
- Webhooks, Filters/Paths and Code by Zapier are premium features on some Zapier plans.
- Code by Zapier runs JavaScript: reuse the code shown above, reading inputs from inputData instead of $json.
- Module and step names can differ slightly as Make and Zapier update their apps.
Tips
- Pair it with the "WhatsApp reminders for tomorrow's appointments" flow to cut no-shows.
Related flows
Real-estate AI agent on WhatsApp
Understands what clients want, suggests matching listings and books viewings — in Arabic or English.
Car service centre AI agent on WhatsApp
Customers ask "is my car ready?", get price ranges and book service slots on WhatsApp.
WhatsApp sales AI agent (Arabic)
Sells on WhatsApp in the customer's own dialect: checks your catalog, answers questions and takes cash-on-delivery orders.