AutomationFlowsAI & RAG › Handle Gmail Reply-based Scheduling with Google Calendar and Gpt-4o-mini

Handle Gmail Reply-based Scheduling with Google Calendar and Gpt-4o-mini

Bykota @takasuka on n8n.io

Reply Handling (Optional Extension)

Webhook trigger★★★★☆ complexityAI-powered23 nodesOpenAIGoogle CalendarGmail TriggerGmail
AI & RAG Trigger: Webhook Nodes: 23 Complexity: ★★★★☆ AI nodes: yes Added:

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 →

Download .json
{
  "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.

Pro

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 →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

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

Google Sheets, OpenAI, Gmail +2
AI & RAG

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

Google Calendar, OpenAI, Gmail +2
AI & RAG

Eu Clara – Funil Kiwify Completo. Uses postgres, openAi, httpRequest, gmail. Webhook trigger; 70 nodes.

Postgres, OpenAI, HTTP Request +1
AI & RAG

Personalized Outreach & Follow-Up - Phase 2. Uses googleSheets, openAi, gmail, gmailTrigger. Scheduled trigger; 59 nodes.

Google Sheets, OpenAI, Gmail +2
AI & RAG

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

Postgres, HTTP Request, OpenAI +2