This workflow corresponds to n8n.io template #10468 — we link there as the canonical source.
This workflow follows the Agent → Google Calendar Tool recipe pattern — see all workflows that pair these two integrations.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"id": "O16uLHqzb7kXJH0u",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "My Smart Calendar Agent",
"tags": [],
"nodes": [
{
"id": "bb61c707-22be-4816-8bc9-8303a17a372d",
"name": "Intent Agent",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
-272,
144
],
"parameters": {
"text": "=User query: {{ $json.messages[0].text.body }}",
"options": {
"systemMessage": "=# Overview\nYou are a calendar assistant. Your job is to look at the incoming query and determine the intent.\n\n## Tools\nContacts Data - Use this tool to get contact information like email address. This tool must be used if the user requests to create an event with an attendee. If no attendee is specified, you don't need to use this tool.\nGet_Events - Use this to get events when the user wants to create, delete, or update an event. You should provide details about the event to confirm it is the right one to delete or update.\n\n## Rules\n- You must always get events using the 'Get_Events' tool to make sure there are no scheduling conflicts.\n- When you are asked to move, update, or delete an event, you must use 'Get_Events' to confirm the event. You must output the event details like date, time, and any attendee emails\n\n## Output\n- You must output the request from the user and ask any clarification questions.\n- Always output the email of the contact the user requested if requested.\n- If there are two records of contact information for a single name, output the email and the type of contact.\n\n## Final notes\nHere is the current date/time: {{ $now }}"
},
"promptType": "define"
},
"typeVersion": 1.7
},
{
"id": "66efefea-3c23-4399-869c-b551dd2b73c6",
"name": "Get_Events",
"type": "n8n-nodes-base.googleCalendarTool",
"position": [
-320,
320
],
"parameters": {
"options": {},
"timeMax": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Before', `11:59 PM of the day the user requested`, 'string') }}",
"timeMin": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('After', `12:01 AM of the day the user requested`, 'string') }}",
"calendar": {
"__rl": true,
"mode": "id",
"value": "=yourmail@gmail.com"
},
"operation": "getAll",
"returnAll": true
},
"typeVersion": 1.3
},
{
"id": "a3037cd8-650a-4fa2-a524-b41a02d2047a",
"name": "Set Intent",
"type": "n8n-nodes-base.set",
"position": [
144,
-320
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "3ab6c175-d35c-48a3-a9db-5162f962d5f9",
"name": "intent",
"type": "string",
"value": "={{ $json.output }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "9254a734-712f-485a-8e5d-fe398cbc9e3a",
"name": "Check Feedback",
"type": "@n8n/n8n-nodes-langchain.textClassifier",
"position": [
544,
-320
],
"parameters": {
"options": {},
"inputText": "={{ $json.data.text }}",
"categories": {
"categories": [
{
"category": "Approved",
"description": "The human is confirming or agreeing with our request. This means they acknowledge that the provided information or action is correct and ready to proceed. Approval messages often include phrases like:\n\n\"Yes\"\n\"Looks good to me\"\n\"Send it\"\n\"Correct\"\n\"Approved\"\n\"That works\"\n\"Sounds good\"\n\"Go ahead\""
},
{
"category": "Denied",
"description": "The human is providing feedback that does not indicate approval. This could include requests for changes, corrections, or additional clarifications. A denial may also involve specifying a type of email, like 'business' or 'personal'.\n\nExamples \"Denied\" phrases:\n'business'\n'change the time'\n'personal'\n'delete both'\n'delete the first one'\n'today'\n'tomorrow'\n'february 22nd'"
}
]
}
},
"typeVersion": 1
},
{
"id": "317055fd-c0a8-4946-b3e8-d1282cf7e611",
"name": "Correction Agent",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
832,
-192
],
"parameters": {
"text": "=Original intent: {{ $('Set Intent').item.json.intent }}\n\nHuman feedback: {{ $json.data.text }}",
"options": {
"systemMessage": "=# Overview\nYou are a correction agent. Your job is to look at the original output, and correct it based on the human feedback.\n\n## Output\n- Your job is to output the new intent of the request. \n- Always include all of the details required like email address of attendees, time, date, summary, etc.\n- Ask a clarification question if necessary. If there is nothing to clarify, just ask \"Is this correct?\""
},
"promptType": "define"
},
"typeVersion": 1.7
},
{
"id": "47535e2e-d291-456f-84ff-d3497b91a613",
"name": "Calendar Agent",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
1296,
112
],
"parameters": {
"text": "={{ $('Set Intent').item.json.intent }}",
"options": {
"systemMessage": "=# Overview You are a calendar assistant. Your responsibilities include creating, getting, and deleting events in the user's calendar. **Calendar Management Tools** - Use \"Create Event with Attendee\" when an event includes a participant. - Use \"Create Event\" for solo events. - Use \"Get Events\" to fetch calendar schedules when requested. - Use \"Delete Event\" to delete an event. You must use \"Get Events\" first to get the ID of the event to delete. - Use \"Update Event\" to update an event. You must use \"Get Events\" first to get the ID of the event to update. ## Rules - Turn the incoming query into an action. Ignore clarification questions, just take action based on the intent you receive. ## Final Notes Here is the current date/time: {{ $now }} If a duration for an event isn't specified, assume it will be one hour."
},
"promptType": "define"
},
"typeVersion": 1.7
},
{
"id": "1ea90a5c-1340-4262-ab79-e2bc812c93a6",
"name": "Create Event",
"type": "n8n-nodes-base.googleCalendarTool",
"position": [
1184,
320
],
"parameters": {
"end": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('End', ``, 'string') }}",
"start": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Start', ``, 'string') }}",
"calendar": {
"__rl": true,
"mode": "id",
"value": "=yourmail@gmail.com"
},
"additionalFields": {
"summary": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Summary', ``, 'string') }}"
}
},
"typeVersion": 1.3
},
{
"id": "edc4be29-f410-483e-bd88-d27be6554b92",
"name": "Create Event with Attendee",
"type": "n8n-nodes-base.googleCalendarTool",
"position": [
1312,
320
],
"parameters": {
"end": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('End', ``, 'string') }}",
"start": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Start', ``, 'string') }}",
"calendar": {
"__rl": true,
"mode": "id",
"value": "=yourmail@gmail.com"
},
"additionalFields": {
"summary": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Summary', ``, 'string') }}",
"attendees": [
"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Attendees', ``, 'string') }}"
]
}
},
"typeVersion": 1.3
},
{
"id": "f1398793-9d9a-4ed4-b819-ea800825616b",
"name": "Update Event",
"type": "n8n-nodes-base.googleCalendarTool",
"position": [
1440,
320
],
"parameters": {
"eventId": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Event_ID', ``, 'string') }}",
"calendar": {
"__rl": true,
"mode": "list",
"value": "user@example.com",
"cachedResultName": "user@example.com"
},
"operation": "update",
"updateFields": {
"end": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('End', ``, 'string') }}",
"start": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Start', ``, 'string') }}"
}
},
"typeVersion": 1.3
},
{
"id": "85270aec-5307-49f5-9d93-81e0b7b9487b",
"name": "Delete Event",
"type": "n8n-nodes-base.googleCalendarTool",
"position": [
1568,
320
],
"parameters": {
"eventId": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Event_ID', ``, 'string') }}",
"options": {},
"calendar": {
"__rl": true,
"mode": "id",
"value": "=yourmail@gmail.com"
},
"operation": "delete"
},
"typeVersion": 1.3
},
{
"id": "6dfbc357-cad7-4dba-bbfa-316a85a077ea",
"name": "Contacts Data",
"type": "n8n-nodes-base.googleSheetsTool",
"position": [
-80,
320
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1u_VppYHt9GUdH0FPIGm2lzd1kCstP9M_0qtgUt6rqqc/edit#gid=0",
"cachedResultName": "Sheet1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1u_VppYHt9GUdH0FPIGm2lzd1kCstP9M_0qtgUt6rqqc",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1u_VppYHt9GUdH0FPIGm2lzd1kCstP9M_0qtgUt6rqqc/edit?usp=drivesdk",
"cachedResultName": "Contacts Data"
}
},
"typeVersion": 4.7
},
{
"id": "a42bb1c2-1cf5-43e3-bb71-1d3c5a2b04c8",
"name": "WhatsApp Trigger",
"type": "n8n-nodes-base.whatsAppTrigger",
"position": [
-528,
144
],
"parameters": {
"options": {},
"updates": [
"messages"
]
},
"typeVersion": 1
},
{
"id": "c56ea940-cd86-4c3a-869c-e806c86ef10d",
"name": "Send message and wait for response",
"type": "n8n-nodes-base.whatsApp",
"position": [
336,
-320
],
"parameters": {
"message": "={{ $('Intent Agent').item.json.output }}",
"options": {
"appendAttribution": false
},
"operation": "sendAndWait",
"responseType": "freeText",
"phoneNumberId": "={{ $('WhatsApp Trigger').item.json.metadata.phone_number_id }}",
"recipientPhoneNumber": "={{ $('WhatsApp Trigger').item.json.messages[0].from }}"
},
"typeVersion": 1
},
{
"id": "f90cf33d-da10-4894-9d3a-7e84e4b18a81",
"name": "Response",
"type": "n8n-nodes-base.whatsApp",
"position": [
1904,
176
],
"parameters": {
"textBody": "={{ $json.output }}",
"operation": "send",
"phoneNumberId": "={{ $('WhatsApp Trigger').item.json.metadata.phone_number_id }}",
"additionalFields": {},
"recipientPhoneNumber": "={{ $('WhatsApp Trigger').item.json.messages[0].from }}"
},
"typeVersion": 1
},
{
"id": "149ef5a1-56d8-4374-93cc-19832b39bc80",
"name": "Code",
"type": "n8n-nodes-base.code",
"position": [
1680,
176
],
"parameters": {
"jsCode": "// Loop over input items and add a new field called 'myNewField' to the JSON of each one\nfor (const item of $input.all()) {\n item.json.myNewField = 1;\n}\n\nreturn $input.all();"
},
"typeVersion": 2
},
{
"id": "195a0592-d0b5-40d7-b64e-3bf3b7fa27cf",
"name": "Google Gemini Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
576,
272
],
"parameters": {
"options": {}
},
"typeVersion": 1
},
{
"id": "ca6525e2-801a-4c30-9874-4cd5c80dc807",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-576,
32
],
"parameters": {
"color": 5,
"width": 640,
"height": 432,
"content": "# Capture Request"
},
"typeVersion": 1
},
{
"id": "0083842a-aaaf-4481-abf9-098b47bdc013",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
80,
-432
],
"parameters": {
"color": 3,
"width": 1056,
"height": 432,
"content": "# Validate Details"
},
"typeVersion": 1
},
{
"id": "3d7749da-c962-4de9-a816-7599850c4e5a",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
1152,
32
],
"parameters": {
"color": 4,
"width": 944,
"height": 432,
"content": "# Schedule Event & Notify"
},
"typeVersion": 1
},
{
"id": "5ba2c7a4-8834-4db6-8640-43baab2b0c04",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
480,
176
],
"parameters": {
"color": 6,
"width": 256,
"height": 256,
"content": "## Chat Model"
},
"typeVersion": 1
},
{
"id": "983ddfc3-3b01-4ab0-a939-aa6ee3974180",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
224,
-544
],
"parameters": {
"color": 7,
"width": 768,
"height": 80,
"content": "# Muhammad Ali Zubair | AI Automation Expert"
},
"typeVersion": 1
},
{
"id": "093dda17-8ede-47f0-8614-8ba727d53cd0",
"name": "Sticky Note7",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1392,
-368
],
"parameters": {
"width": 720,
"height": 832,
"content": "# \ud83e\udd16 AI WhatsApp Calendar Assistant\n\n## \ud83c\udf1f Description\nThis workflow turns your **WhatsApp messages** into an intelligent **calendar scheduling assistant** using **Google Gemini**, **Google Calendar**, and **Google Sheets**. \nIt automatically interprets user messages like \u201cschedule meeting with John at 10am tomorrow,\u201d finds contact details, checks for calendar conflicts, and creates, updates, or deletes events all through chat.\n\n## \u2699\ufe0f How It Works\n1. **WhatsApp Trigger** \u2192 Captures incoming messages from users.\n2. **Intent Agent (Gemini)** \u2192 Understands the user\u2019s request (create, delete, update event).\n3. **Contacts Data (Google Sheets)** \u2192 Retrieves attendee emails or contact details.\n4. **Get_Events** \u2192 Checks your calendar for existing events to avoid overlaps.\n5. **Set Intent + Check Feedback** \u2192 Confirms user intent or corrections.\n6. **Calendar Agent** \u2192 Performs the actual action (create, update, or delete event).\n7. **Create/Update/Delete Event** \u2192 Executes the correct Google Calendar operation.\n8. **Response & Notify Attendee** \u2192 Sends WhatsApp confirmation and email notification.\n9. **Google Gemini Chat Model** \u2192 Powers the LLM reasoning and message generation.\n\n## \ud83d\udc65 Who It\u2019s For\n- Business owners or freelancers who schedule via WhatsApp \n- Customer service or sales teams managing meeting bookings \n- Virtual assistants automating calendar management \n- Anyone who wants an AI agent to manage appointments conversationally\n\n## \ud83d\udca1 Key Benefits\n- Fully automated scheduling via WhatsApp \n- AI handles natural language like \u201creschedule meeting to tomorrow 3 PM\u201d \n- Avoids double-booking with calendar conflict checks \n- Sends instant WhatsApp + Gmail confirmations \n- Saves time and reduces manual coordination\n"
},
"typeVersion": 1
},
{
"id": "39e8dcc1-129c-4fc0-bb17-12e050bbda3c",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
2128,
-432
],
"parameters": {
"color": 6,
"width": 704,
"height": 1120,
"content": "# \u2699\ufe0f Setup Instructions\n\n## \ud83d\udd52 Setup Time\nApprox. 15\u201320 minutes\n\n## \ud83e\udde9 Required Integrations\n- **WhatsApp Cloud API** (for message trigger and replies)\n- **Google Calendar** (for scheduling)\n- **Google Sheets** (as contact database)\n- **Google Gemini API Key** (for AI reasoning)\n\n## \ud83d\udd27 Step-by-Step Setup\n\n1. **WhatsApp Connection**\n - Connect your WhatsApp Cloud API to n8n.\n - Replace webhook and phone number ID with your own.\n\n2. **Google Calendar Connection**\n - Connect your Google account.\n - Choose your primary calendar (e.g. `youremail@gmail.com`).\n\n3. **Google Sheets (Contacts Data)**\n - Create a sheet with columns like: \n `Name | Email | Type` \n - Paste its ID and tab name inside the \u201cContacts Data\u201d node.\n\n4. **Gemini Model Setup**\n - Add your **Google Gemini API key** under \u201cGoogle Gemini Chat Model\u201d.\n - Ensure it\u2019s linked to all AI Agent nodes (`Intent Agent`, `Correction Agent`, `Calendar Agent`).\n\n5. **Customize Prompts**\n - Edit system messages in each agent to match your tone or workflow style.\n - Example: Adjust the assistant\u2019s language or confirmation tone.\n\n6. **Test Workflow**\n - Send a WhatsApp message like: \n _\u201cSchedule meeting with Ali at 10am on Friday\u201d_ \n - Confirm the event is added in Google Calendar.\n - Check that attendee notification email is sent automatically.\n\n## \u2705 Optional Enhancements\n- Add Slack notifications for scheduled events.\n- Add time zone conversion if working with international clients.\n- Extend logic to support recurring meetings.\n\n"
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "e9dafb17-f19e-4852-b454-1a4fc9d77020",
"connections": {
"Code": {
"main": [
[
{
"node": "Response",
"type": "main",
"index": 0
}
]
]
},
"Get_Events": {
"ai_tool": [
[
{
"node": "Intent Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Set Intent": {
"main": [
[
{
"node": "Send message and wait for response",
"type": "main",
"index": 0
}
]
]
},
"Create Event": {
"ai_tool": [
[
{
"node": "Calendar Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Delete Event": {
"ai_tool": [
[
{
"node": "Calendar Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Intent Agent": {
"main": [
[
{
"node": "Set Intent",
"type": "main",
"index": 0
}
]
]
},
"Update Event": {
"ai_tool": [
[
{
"node": "Calendar Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Contacts Data": {
"ai_tool": [
[
{
"node": "Intent Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Calendar Agent": {
"main": [
[
{
"node": "Code",
"type": "main",
"index": 0
}
]
]
},
"Check Feedback": {
"main": [
[
{
"node": "Calendar Agent",
"type": "main",
"index": 0
}
],
[
{
"node": "Correction Agent",
"type": "main",
"index": 0
}
]
]
},
"Correction Agent": {
"main": [
[
{
"node": "Set Intent",
"type": "main",
"index": 0
}
]
]
},
"WhatsApp Trigger": {
"main": [
[
{
"node": "Intent Agent",
"type": "main",
"index": 0
}
]
]
},
"Google Gemini Chat Model": {
"ai_languageModel": [
[
{
"node": "Intent Agent",
"type": "ai_languageModel",
"index": 0
},
{
"node": "Check Feedback",
"type": "ai_languageModel",
"index": 0
},
{
"node": "Correction Agent",
"type": "ai_languageModel",
"index": 0
},
{
"node": "Calendar Agent",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Create Event with Attendee": {
"ai_tool": [
[
{
"node": "Calendar Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Send message and wait for response": {
"main": [
[
{
"node": "Check Feedback",
"type": "main",
"index": 0
}
]
]
}
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Turn your WhatsApp chats into an AI-powered meeting scheduler with Google Gemini, Google Calendar, and Google Sheets. This workflow understands natural language like “Book a meeting with Ali at 3 PM tomorrow”, checks your contacts, avoids overlaps, and updates your calendar…
Source: https://n8n.io/workflows/10468/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
This workflow implements an AI-powered WhatsApp booking assistant for a hair salon. The system allows customers to book, reschedule, or cancel appointments automatically via text or voice messages on
This template is designed for businesses that provide customer support and appointment-based services over WhatsApp. It’s ideal for service providers (e.g., clinics, salons, repair shops, consultants)
Youtube Explanation: https://youtu.be/KgmNiV7SwkU
This template is designed for anyone who wants to use WhatsApp as a personal AI assistant hub. If you often juggle tasks, emails, calendars, and expenses across multiple tools, this workflow consolida
WhatsApp AI Assistant for Clinic Appointment Booking Automate your entire appointment lifecycle with an intelligent AI assistant that lives on WhatsApp. This workflow empowers any clinic or independen