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
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.
User Signup & Verification: The workflow starts when a user signs up. It generates a verification code and sends it via SMS using Twilio. Code Validation: The user replies with the code. The workflow