This workflow corresponds to n8n.io template #12167 — we link there as the canonical source.
This workflow follows the Gmail → Gmail Trigger 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": "Rs89a3dE84qNpJAx",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "Smart Calendar Availability & Auto Scheduling",
"tags": [],
"nodes": [
{
"id": "85250e5d-ebdb-48ad-9d31-d0cb6bdba315",
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"position": [
0,
0
],
"parameters": {
"path": "ai-schedule-copilot",
"options": {},
"httpMethod": "POST"
},
"typeVersion": 2.1
},
{
"id": "718737fa-c29a-42a0-9e31-42d9db85b7e9",
"name": "Sample Input",
"type": "n8n-nodes-base.set",
"position": [
208,
0
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "0a0a0eb7-d853-4add-9d0b-81fa3f01497a",
"name": "text",
"type": "string",
"value": "Meeting in Shibuya on December 28 from 7:00 to 8:00 PM.\nAttendee: user@example.com\nAgenda: Collaboration discussion\n"
},
{
"id": "68e90298-db6a-44fd-a626-82f2070ef5c4",
"name": "timezone",
"type": "string",
"value": "Asia/Tokyo"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "42932d59-aa99-4811-932c-ad3d765707bf",
"name": "Message a model",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
416,
0
],
"parameters": {
"modelId": {
"__rl": true,
"mode": "list",
"value": "gpt-4o-mini",
"cachedResultName": "GPT-4O-MINI"
},
"options": {},
"responses": {
"values": [
{
"role": "system",
"content": "You are an assistant that extracts structured calendar event data.\n\nReturn ONLY valid JSON in the following format:\n{\n \"title\": string,\n \"start_datetime\": string (ISO 8601),\n \"end_datetime\": string (ISO 8601),\n \"location\": string,\n \"attendees\": [string],\n \"description\": string\n}\n\nDo not include any extra text.\n"
},
{
"content": "=Extract calendar event details from the text below.\n\nReturn JSON with:\n- title\n- start_datetime (ISO 8601)\n- end_datetime (ISO 8601)\n- location\n- attendees (array of emails)\n- description\n\nText:\n{{ $json.text }}\n"
}
]
},
"builtInTools": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "c089808a-bb75-4222-a4c0-54cf44e62819",
"name": "Prepare Calendar Payload",
"type": "n8n-nodes-base.set",
"position": [
768,
0
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "6af6597a-db0d-4aba-ba48-843bd0a6d720",
"name": "title",
"type": "string",
"value": "Collaboration meeting"
},
{
"id": "0da95e44-b660-4d90-83fb-dee5a12c7681",
"name": "start_datetime",
"type": "string",
"value": "2023-12-28T19:00:00+09:00"
},
{
"id": "5b4d6b90-334d-444c-8288-c05067db2d8f",
"name": "end_datetime",
"type": "string",
"value": "2023-12-28T20:00:00+09:00"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "a2130e8b-a3bd-49f0-a0f5-7836edd7fb1d",
"name": "Get availability in a calendar",
"type": "n8n-nodes-base.googleCalendar",
"position": [
976,
0
],
"parameters": {
"options": {},
"calendar": {
"__rl": true,
"mode": "list",
"value": "user@example.com",
"cachedResultName": "user@example.com"
},
"resource": "calendar"
},
"credentials": {
"googleCalendarOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1.3
},
{
"id": "1533ceca-cbf2-40f8-8ea8-07d5c6909606",
"name": "If",
"type": "n8n-nodes-base.if",
"position": [
1184,
0
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "1d216ab5-b007-4c23-9fa0-aaafad53fddc",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": "={{$json.available}}",
"rightValue": "="
}
]
}
},
"typeVersion": 2.3
},
{
"id": "515f53f5-e5b0-44d0-af8c-5fc880fd93da",
"name": "Create an event",
"type": "n8n-nodes-base.googleCalendar",
"position": [
1440,
-80
],
"parameters": {
"end": "={{ $('Prepare Calendar Payload').item.json.end_datetime }}",
"start": "={{ $('Prepare Calendar Payload').item.json.start_datetime }}",
"calendar": {
"__rl": true,
"mode": "list",
"value": "user@example.com",
"cachedResultName": "user@example.com"
},
"additionalFields": {
"summary": "={{ $('Prepare Calendar Payload').item.json.title }}",
"attendees": [
"={{ $('Prepare Calendar Payload').item.json.attendees }}\n"
],
"description": "={{ $('Prepare Calendar Payload').item.json.description }}\n"
}
},
"credentials": {
"googleCalendarOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1.3
},
{
"id": "593abbaf-1371-4bff-ba81-971c7fcedf8d",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-80,
-656
],
"parameters": {
"width": 800,
"height": 432,
"content": "## \ud83d\udcc5 Smart Calendar Scheduling Workflow\n\nWhat this workflow does:\nThis workflow automatically checks Google Calendar availability and either creates a new event or sends a notification email if the time slot is already booked.\n\nHow it works:\n1. The workflow is triggered via a Webhook.\n2. Input data such as title, start time, and end time is prepared.\n3. Google Calendar availability is checked for the requested time slot.\n4. If the time is available, a calendar event is created automatically.\n5. If the time is not available, an email notification is sent instead.\n\nWhen it is used:\nThis workflow is used when scheduling meetings automatically without manual calendar checks.\n\nWho benefits:\nAnyone who wants to automate meeting scheduling, avoid double bookings, and save time using Google Calendar.\n"
},
"typeVersion": 1
},
{
"id": "79271e2b-ed4d-4604-be1d-04e0b9042e3d",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-80,
-144
],
"parameters": {
"color": 7,
"width": 432,
"height": 336,
"content": "## Trigger & Input\nTrigger & input layer.\nStarts the workflow via webhook or test input.\nProvides initial data to the system.\n\n"
},
"typeVersion": 1
},
{
"id": "676d1d08-135a-4e4f-8b20-2f5316a30834",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
384,
-144
],
"parameters": {
"color": 7,
"width": 528,
"height": 336,
"content": "## AI & Data Preparation \nAI processing and data preparation.\nGenerates text and formats calendar payload.\nPrepares clean scheduling data.\n"
},
"typeVersion": 1
},
{
"id": "6425b9a1-c9a7-4d4f-b77c-7eab2b1e149b",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
944,
-144
],
"parameters": {
"color": 7,
"width": 432,
"height": 336,
"content": "## Availability Decision \nAvailability check and decision logic.\nChecks if the time slot is free.\nRoutes the workflow based on the result.\n"
},
"typeVersion": 1
},
{
"id": "bc0fec80-0b96-4c7b-a44c-4909a374c805",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
1408,
-224
],
"parameters": {
"color": 7,
"width": 256,
"height": 512,
"content": "## Final Action\nFinal action layer.\nCreates a calendar event or sends a notification email.\nCompletes the workflow.\n"
},
"typeVersion": 1
},
{
"id": "8c789449-402b-4ca7-b215-df7b90205544",
"name": "Build Alternative Slots",
"type": "n8n-nodes-base.set",
"position": [
1440,
96
],
"parameters": {
"include": "=all",
"options": {},
"assignments": {
"assignments": [
{
"id": "38b9da31-c40d-4ac8-b153-e82ad3c96cf0",
"name": "requested_start",
"type": "string",
"value": "={{$json.start_datetime}}"
},
{
"id": "cb40e53c-94f6-4748-bafc-8747cca6f65d",
"name": "requested_end",
"type": "string",
"value": "={{$json.end_datetime}}"
},
{
"id": "8e7bbebe-4db9-474e-9b30-00cec1558746",
"name": "alternative_slots_text",
"type": "string",
"value": "={{ \n \"1) \" + $moment($json.start_datetime).add(1, 'days').format('YYYY-MM-DD HH:mm') + \" - \" + $moment($json.end_datetime).add(1, 'days').format('HH:mm') \n + \"\\n2) \" + $moment($json.start_datetime).add(2, 'days').format('YYYY-MM-DD HH:mm') + \" - \" + $moment($json.end_datetime).add(2, 'days').format('HH:mm')\n + \"\\n3) \" + $moment($json.start_datetime).add(3, 'days').format('YYYY-MM-DD HH:mm') + \" - \" + $moment($json.end_datetime).add(3, 'days').format('HH:mm')\n}}\n"
}
]
},
"includeOtherFields": true
},
"typeVersion": 3.4
},
{
"id": "fa1d5a39-5708-472f-92f6-7f94d2017ccc",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
-80,
320
],
"parameters": {
"color": 5,
"width": 2128,
"height": 400,
"content": "## Reply Handling (Optional Extension)\nThis section demonstrates how email replies can be handled\nas an extension to the main scheduling workflow in production.\n\nThis workflow showcases an end-to-end,\nemail-based scheduling system.\n\nIt automatically:\n- Checks calendar availability\n- Sends alternative time slots if unavailable\n- Listens for email replies\n- Confirms and creates calendar events upon user confirmation\n"
},
"typeVersion": 1
},
{
"id": "cfee87c2-7ca5-470f-8842-18d742861a8a",
"name": "Gmail Trigger (User Reply)",
"type": "n8n-nodes-base.gmailTrigger",
"position": [
416,
448
],
"parameters": {
"filters": {
"sender": "user@example.com"
},
"pollTimes": {
"item": [
{
"mode": "everyMinute"
}
]
}
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 1.3
},
{
"id": "8fb39df9-e27a-4d80-9235-7d8ef3f43a84",
"name": "Normalize Incoming Reply",
"type": "n8n-nodes-base.set",
"position": [
640,
448
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "2c3c5082-ea78-4286-a23d-4866e2a670dc",
"name": "reply_text",
"type": "string",
"value": "={{$json.text || $json.snippet}}\n"
},
{
"id": "b275f8f7-e932-420c-80d4-ccb5c6f10520",
"name": "from_email",
"type": "string",
"value": "={{$json.from}}\n"
},
{
"id": "9577658a-2c5e-461c-9a8d-ab538ca5aac7",
"name": "thread_id",
"type": "string",
"value": "={{$json.threadId}}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "eda359d7-e258-43c5-802e-b0a8fdd97790",
"name": "Check Selected Option (1 or 2)",
"type": "n8n-nodes-base.if",
"position": [
848,
448
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "f9a14bd3-7882-4cfe-a911-fe569c3aeb84",
"operator": {
"type": "string",
"operation": "contains"
},
"leftValue": "={{ $json.reply_text }}",
"rightValue": "1"
}
]
}
},
"typeVersion": 2.3
},
{
"id": "61917f89-bc25-4ff7-9299-4afc33a94203",
"name": "Prepare Confirmed Slot Data",
"type": "n8n-nodes-base.set",
"position": [
1056,
352
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "2abf08ba-77bb-41c2-99f1-538dc937b1ac",
"name": "selected_option",
"type": "string",
"value": "1"
},
{
"id": "21fdd298-128c-4969-b6c1-e9b195f80ea1",
"name": "chosen_start",
"type": "string",
"value": "={{ $json.requested_start }}"
},
{
"id": "4562b858-534d-4e6b-a343-77d924d0abb9",
"name": "chosen_end",
"type": "string",
"value": "={{ $json.requested_end }}"
},
{
"id": "928ebe52-1506-4a22-a2de-41cc4281f29c",
"name": "attendee_email",
"type": "string",
"value": "={{ $json.from_email }}"
},
{
"id": "e8eace46-6da3-4932-8573-bcc0baf9b723",
"name": "selected_option",
"type": "string",
"value": "1"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "403f331f-a4c2-48fc-9550-ee9ac303521c",
"name": "Prepare Alternative Request",
"type": "n8n-nodes-base.set",
"position": [
1056,
544
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "47cbea66-e532-4425-ad0a-bf0585f3dfe7",
"name": "is_valid_reply",
"type": "boolean",
"value": false
},
{
"id": "20948c65-6203-4a9b-8954-c4c1ccd45b4e",
"name": "reply_reason",
"type": "string",
"value": "Invalid option (not 1)"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "10cda059-c8da-427e-b1e8-22b1ef91f52c",
"name": "Is Valid Confirmation",
"type": "n8n-nodes-base.if",
"position": [
1264,
448
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "8da5a319-545b-40ce-a3b8-89da6ce29735",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": "={{ $json.is_valid_reply }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.3
},
{
"id": "f51621df-fb61-4cfe-a73a-8632f3d545fc",
"name": "Create Calendar Event",
"type": "n8n-nodes-base.googleCalendar",
"position": [
1472,
352
],
"parameters": {
"end": "={{ $json.chosen_end }}\n",
"start": "={{ $json.chosen_start }}\n",
"calendar": {
"__rl": true,
"mode": "list",
"value": "user@example.com",
"cachedResultName": "user@example.com"
},
"additionalFields": {
"summary": "Meeting confirmed",
"attendees": [
"={{ $json.attendee_email.match(/<(.+?)>/)?.[1] || $json.attendee_email }}"
],
"description": "Scheduled via email reply"
}
},
"credentials": {
"googleCalendarOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1.3
},
{
"id": "3eaa536c-184f-4c79-9265-c928e267a291",
"name": "Send Confirmation Email",
"type": "n8n-nodes-base.gmail",
"position": [
1680,
448
],
"parameters": {
"sendTo": "={{ $json.attendee_email.match(/<(.+?)>/)?.[1] || $json.attendee_email }}",
"message": "=Hi! \ud83d\udc4b<br><br> Your meeting has been confirmed.<br><br> \ud83d\udcc5 <b>Date & Time</b><br> {{ $json.chosen_start }} \u2013 {{ $json.chosen_end }}<br><br> The event has been added to Google Calendar.<br><br> See you then! \ud83d\ude0a",
"options": {},
"subject": "Meeting confirmed"
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.2
},
{
"id": "f24283fc-e9a5-4da2-bfbc-329fa3a8f625",
"name": "Request Alternative Slots",
"type": "n8n-nodes-base.gmail",
"position": [
1472,
544
],
"parameters": {
"message": "Sorry, I couldn\u2019t clearly understand your reply. Please reply with one of the options below: 1: This time works for me 2: I\u2019d like to see other available options",
"options": {},
"messageId": "={{ $json.id }}",
"operation": "reply"
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.2
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "fbfc4f5b-8553-43cd-a8cd-1508c4aa1f05",
"connections": {
"If": {
"main": [
[
{
"node": "Create an event",
"type": "main",
"index": 0
}
],
[
{
"node": "Build Alternative Slots",
"type": "main",
"index": 0
}
]
]
},
"Webhook": {
"main": [
[
{
"node": "Sample Input",
"type": "main",
"index": 0
}
]
]
},
"Sample Input": {
"main": [
[
{
"node": "Message a model",
"type": "main",
"index": 0
}
]
]
},
"Message a model": {
"main": [
[
{
"node": "Prepare Calendar Payload",
"type": "main",
"index": 0
}
]
]
},
"Create Calendar Event": {
"main": [
[
{
"node": "Send Confirmation Email",
"type": "main",
"index": 0
}
]
]
},
"Is Valid Confirmation": {
"main": [
[
{
"node": "Create Calendar Event",
"type": "main",
"index": 0
}
],
[
{
"node": "Request Alternative Slots",
"type": "main",
"index": 0
},
{
"node": "Build Alternative Slots",
"type": "main",
"index": 0
}
]
]
},
"Normalize Incoming Reply": {
"main": [
[
{
"node": "Check Selected Option (1 or 2)",
"type": "main",
"index": 0
}
]
]
},
"Prepare Calendar Payload": {
"main": [
[
{
"node": "Get availability in a calendar",
"type": "main",
"index": 0
}
]
]
},
"Gmail Trigger (User Reply)": {
"main": [
[
{
"node": "Normalize Incoming Reply",
"type": "main",
"index": 0
}
]
]
},
"Prepare Alternative Request": {
"main": [
[
{
"node": "Is Valid Confirmation",
"type": "main",
"index": 0
}
]
]
},
"Prepare Confirmed Slot Data": {
"main": [
[
{
"node": "Is Valid Confirmation",
"type": "main",
"index": 0
}
]
]
},
"Check Selected Option (1 or 2)": {
"main": [
[
{
"node": "Prepare Confirmed Slot Data",
"type": "main",
"index": 0
}
],
[
{
"node": "Prepare Alternative Request",
"type": "main",
"index": 0
}
]
]
},
"Get availability in a calendar": {
"main": [
[
{
"node": "If",
"type": "main",
"index": 0
}
]
]
}
}
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
gmailOAuth2googleCalendarOAuth2ApiopenAiApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Reply Handling (Optional Extension)
Source: https://n8n.io/workflows/12167/ — 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.
Imagine your recruitment process transformed into a sleek, efficient, AI-powered assembly line for talent. That's exactly what this system creates. It automates the heavy lifting, allowing your human
This workflow automates the end-to-end process of scheduling technical or behavioral interviews. It captures interview data via Webhook, creates a Google Calendar event with an integrated Google Meet
This workflow captures new leads via webhook, enriches and scores them with Apollo and Google Gemini, logs everything in Google Sheets, and automates outreach, reply handling, follow-ups, meeting prep
Eu Clara – Funil Kiwify Completo. Uses postgres, openAi, httpRequest, gmail. Webhook trigger; 70 nodes.
Personalized Outreach & Follow-Up - Phase 2. Uses googleSheets, openAi, gmail, gmailTrigger. Scheduled trigger; 59 nodes.