{"workflow":{"id":12831,"name":"Book, manage, and check appointments using Vapi and Google Calendar","views":644,"recentViews":1,"totalViews":644,"createdAt":"2026-01-19T23:49:04.131Z","description":"Use this workflow to book, cancel, or reschedule appointments using Vapi and Google Calendar\n\n## How it works\nThe Check Availability workflow checks if appointments exist on Google Calendar and returns a response to Vapi.\n\nThe Book Appointment workflow schedules an appointment on Google Calendar.\n\nThe Manage Appointments workflow updates or cancels appointments based on the user’s request.\n\n## Key Features:\n1. Ability to book, update, or cancel an appointment\n\n2. Validates required fields before booking\n\n3. Handles errors with helpful user messages\n\n4. Returns a Vapi-compatible response format\n\n\n## Set up steps\n### Prerequisites\n1. Vapi.ai account\n\n2. Google Calendar\n\n3. n8n instance - Self-hosted or cloud\n\n### Steps\n- Step 1: Configure Google Calendar Access\n\n- Step 2: Import and Configure Workflows\n\n- Step 3: Create Vapi Custom Tools\n\n- Step 4: Configure Vapi Assistant\n\n### Use Cases\nAppointment booking automation for service businesses\n\n\n","workflow":{"id":"ZEt8fHPKy3Ye5CYX","meta":{"instanceId":"906d7555fb45eb5dbb66f91c85d3a70f7d0a2e79e2768d0cef50cbf035bc3f18"},"name":"Voice AI Appointment Booking System with Vapi & Google Calendar - Template","tags":[],"nodes":[{"id":"e7503d57-8408-4b88-bcc7-52b8b9a0751f","name":"Book Appointment Webhook","type":"n8n-nodes-base.webhook","position":[2608,2432],"webhookId":"YOUR_WEBHOOK_ID_BOOK_APPOINTMENT","parameters":{"path":"book-appointment","options":{},"httpMethod":"POST","responseMode":"responseNode"},"typeVersion":2.1},{"id":"ffaa0c7e-ebe5-4794-9b08-7772630ab556","name":"Extract Booking Data","type":"n8n-nodes-base.set","position":[2832,2432],"parameters":{"options":{},"assignments":{"assignments":[{"id":"888090a8-b557-4d1e-8ead-c247b701a37a","name":"name","type":"string","value":"={{ $json.body.message.toolCalls[0].function.arguments.name }}"},{"id":"25750d43-8579-4eb5-bf84-bdd3753fd69d","name":"email","type":"string","value":"={{ $json.body.message.toolCalls[0].function.arguments.email }}"},{"id":"57ae0306-b762-4e4e-8af3-45ed50c9dd59","name":"phone","type":"string","value":"={{ $json.body.message.toolCalls[0].function.arguments.phoneNumber }}"},{"id":"fc18bf95-65f2-4d5c-81c3-59cbd8b33d06","name":"appointmentDate","type":"string","value":"={{ $json.body.message.toolCalls[0].function.arguments.appointmentDate }}"},{"id":"1db91e90-015a-4dd5-829b-84588352e1eb","name":"appointmentTime","type":"string","value":"={{ $json.body.message.toolCalls[0].function.arguments.appointmentTime }}"},{"id":"4260e29b-4098-46e5-9c17-0a0e823953da","name":"duration","type":"string","value":"={{ $json.body.message.toolCalls[0].function.arguments.duration }}"},{"id":"54728c90-79d8-4a7e-90dc-b7d2fa023258","name":"service","type":"string","value":"={{ $json.body.message.toolCalls[0].function.arguments.service }}"},{"id":"f26383cd-3d5c-45ea-b042-57b85261c3a4","name":"notes","type":"string","value":"={{ $json.body.message.toolCalls[0].function.arguments.notes }}"},{"id":"ae3e11d8-bb91-4717-9a3b-4b4cad1f68bd","name":"toolCallId","type":"string","value":"={{ $json.body.message.toolCalls[0].id }}"}]}},"typeVersion":3.4},{"id":"93cabadc-fc25-4779-9c59-f63662518615","name":"Validate Required Fields","type":"n8n-nodes-base.if","position":[3056,2432],"parameters":{"options":{},"conditions":{"options":{"version":3,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"67d148c4-4e97-41cd-a98b-5e3cd9d18898","operator":{"type":"string","operation":"notEmpty","singleValue":true},"leftValue":"={{ $json.name }}","rightValue":""},{"id":"d78fff76-793d-40d1-b9e0-f25be4e69ce7","operator":{"type":"string","operation":"notEmpty","singleValue":true},"leftValue":"={{ $json.phone }}","rightValue":""},{"id":"343af58d-4768-4e74-870f-3f36d7911ae5","operator":{"type":"string","operation":"notEmpty","singleValue":true},"leftValue":"={{ $json.appointmentDate }}","rightValue":""},{"id":"f0ecd392-52d3-4b58-92e0-63d9e8e2e16d","operator":{"type":"string","operation":"notEmpty","singleValue":true},"leftValue":"={{ $json.appointmentTime }}","rightValue":""}]}},"typeVersion":2.3},{"id":"9b26b185-7285-4ed1-a47b-21046b0052c4","name":"Respond - Validation Error","type":"n8n-nodes-base.respondToWebhook","position":[3664,2528],"parameters":{"options":{}},"typeVersion":1.5},{"id":"b5dc67a8-f6d6-4ff5-82d1-9345c98cb5c8","name":"Create Calendar Event","type":"n8n-nodes-base.googleCalendar","position":[3248,2272],"parameters":{"end":"={{ DateTime.fromISO($json.appointmentDate + 'T' + $json.appointmentTime + ':00', {zone: 'America/Vancouver'}).plus({minutes: parseInt($json.duration) || 30}).toISO() }}","start":"={{ DateTime.fromISO($json.appointmentDate + 'T' + $json.appointmentTime + ':00', {zone: 'America/Vancouver'}).toISO() }}","calendar":{"__rl":true,"mode":"list","value":"user@example.com","cachedResultName":"Bookings"},"additionalFields":{"summary":"={{ $json.service + ' - ' + $json.name }}","attendees":[],"description":"=Customer: {{ $json.name }} Phone: {{ $json.phone }} Service: {{ $json.service }} Notes: {{ $json.notes }}"}},"typeVersion":1.3},{"id":"948e3ab6-bddc-432f-a918-c03d41c4836f","name":"Respond - Booking Success","type":"n8n-nodes-base.respondToWebhook","position":[3664,2272],"parameters":{"options":{}},"typeVersion":1.5},{"id":"f4f3b539-ac7b-471d-bbb9-8d35dc9fc1df","name":"Format Booking Success Response","type":"n8n-nodes-base.code","position":[3456,2272],"parameters":{"jsCode":"// Get data from Extract Booking Data node\nconst editFieldsData = $('Extract Booking Data').first().json;\nconst webhookData = $('Book Appointment Webhook').first().json;\n\n// Get toolCallId from webhook body\nconst toolCallId = webhookData.body?.message?.toolCallList?.[0]?.id;\n\n// Create Vapi response format\nreturn [{\n  json: {\n    results: [{\n      toolCallId: toolCallId,\n      result: `The appointment for ${editFieldsData.name} at ${editFieldsData.appointmentDate} at ${editFieldsData.appointmentTime} was booked successfully.`\n    }]\n  }\n}];"},"typeVersion":2},{"id":"d06933a5-aa49-462d-bc71-31e14cd39170","name":"Format Validation Error Response","type":"n8n-nodes-base.code","position":[3440,2528],"parameters":{"jsCode":"// Get data from Extract Booking Data node\nconst editFieldsData = $('Extract Booking Data').first().json;\nconst webhookData = $('Book Appointment Webhook').first().json;\n\n// Get toolCallId from webhook body\nconst toolCallId = webhookData.body?.message?.toolCallList?.[0]?.id;\n\n// Create Vapi response format\nreturn [{\n  json: {\n    results: [{\n      toolCallId: toolCallId,\n      result: `The input data from webhook is missing required fields.`\n    }]\n  }\n}];"},"typeVersion":2},{"id":"9b9c9b54-8564-42b2-bedc-c08faceb61b9","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[2128,2416],"parameters":{"color":6,"width":284,"height":244,"content":"## Tool 2: Book Appointment\n\nReceives booking data from Vapi, validates required fields, creates Google Calendar event, and returns formatted response."},"typeVersion":1},{"id":"8fa0a809-d354-4a68-b33f-baff4d2196e6","name":"Get Calendar Events for Date","type":"n8n-nodes-base.googleCalendar","position":[3056,1456],"parameters":{"options":{"timeZone":{"__rl":true,"mode":"list","value":"America/Vancouver","cachedResultName":"America/Vancouver"}},"timeMax":"={{ $json.appointmentDate }}T23:59:59-08:00","timeMin":"={{ $json.appointmentDate }}T00:00:00-08:00","calendar":{"__rl":true,"mode":"id","value":"user@example.com","__regex":"(^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*)"},"operation":"getAll"},"typeVersion":1.3,"alwaysOutputData":true},{"id":"76b97cbd-354b-4793-a106-a1f706d1cd68","name":"Check Availability Webhook","type":"n8n-nodes-base.webhook","position":[2608,1456],"webhookId":"YOUR_WEBHOOK_ID_CHECK_AVAILABILITY","parameters":{"path":"availability","options":{},"httpMethod":"POST","responseMode":"responseNode"},"typeVersion":2.1},{"id":"3dd18a71-b6fc-4ae9-a3c6-842a8b618b23","name":"Extract Availability Request","type":"n8n-nodes-base.set","position":[2832,1456],"parameters":{"options":{},"assignments":{"assignments":[{"id":"74d32727-53c1-4097-be98-6890c7d42a45","name":"appointmentDate","type":"string","value":"={{ $json.body.message.toolCalls[0].function.arguments.appointmentDate }}"},{"id":"58b24bc7-3cea-4596-9401-d028bca697a4","name":"appointmentTime","type":"string","value":"={{ $json.body.message.toolCalls[0].function.arguments.appointmentTime }}"},{"id":"2d2d38d9-f680-4e4b-9bb1-270bc810dbcd","name":"requestedDatetime","type":"string","value":"={{ DateTime.fromISO($json.body.message.toolCalls[0].function.arguments.appointmentDate + 'T' + $json.body.message.toolCalls[0].function.arguments.appointmentTime + ':00', { zone: 'America/Vancouver' }).toFormat(\"yyyy-MM-dd'T'HH:mm:ssZZ\") }}"}]}},"typeVersion":3.4},{"id":"324e6bdb-55bb-44d7-9efc-8a727ca8bc86","name":"Check Time Slot Availability","type":"n8n-nodes-base.if","position":[3280,1456],"parameters":{"options":{},"conditions":{"options":{"version":3,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"20c2de12-9104-4211-99c1-623bcc344a1e","operator":{"type":"string","operation":"equals"},"leftValue":"={{ $json.start.dateTime }}","rightValue":"={{ $items('Edit Fields1')[0].json.requestedDatetime }}"}]}},"typeVersion":2.3},{"id":"7e25e200-ae98-412b-92cd-29d9267a5be3","name":"Respond - Time Available","type":"n8n-nodes-base.respondToWebhook","position":[3728,1552],"parameters":{"options":{}},"typeVersion":1.5},{"id":"3aab7fb2-6089-49a8-9ceb-7a93febfed13","name":"Respond - Time Unavailable","type":"n8n-nodes-base.respondToWebhook","position":[3728,1360],"parameters":{"options":{}},"typeVersion":1.5},{"id":"b168952e-55aa-4584-8558-bda1f5e28c63","name":"Format Unavailable Time Response","type":"n8n-nodes-base.code","position":[3504,1360],"parameters":{"jsCode":"// Get data from previous nodes\nconst calendarEvents = $('Get Calendar Events for Date').all().map(item => item.json);\nconst requestedDate = $('Extract Availability Request').first().json.appointmentDate;\nconst requestedTime = $('Extract Availability Request').first().json.appointmentTime;\nconst duration = $('Extract Availability Request').first().json.duration;\nconst timeZone = $('Extract Availability Request').first().json.timeZone;\nconst toolCallId = $('Check Availability Webhook').first().json.body.message.toolCallList[0].id;\n\n// Business hours (customize as needed)\nconst WORKDAY_START = \"09:00\";\nconst WORKDAY_END = \"18:00\";\nconst SLOT_DURATION_MINUTES = 30;\n\n// Helper function to format time as HH:MM\nfunction formatTime(date) {\n  return date.toLocaleTimeString('en-US', { \n    hour: '2-digit', \n    minute: '2-digit',\n    hour12: true,\n    timeZone: timeZone \n  });\n}\n\n// Generate all possible 30-minute slots for the day\nfunction generateDaySlots(date) {\n  const slots = [];\n  const [startHour, startMin] = WORKDAY_START.split(':').map(Number);\n  const [endHour, endMin] = WORKDAY_END.split(':').map(Number);\n  \n  let current = new Date(`${date}T${WORKDAY_START}:00`);\n  const end = new Date(`${date}T${WORKDAY_END}:00`);\n  \n  while (current < end) {\n    const slotEnd = new Date(current.getTime() + SLOT_DURATION_MINUTES * 60 * 1000);\n    slots.push({\n      start: current.toISOString(),\n      end: slotEnd.toISOString(),\n      startTime: formatTime(current),\n      endTime: formatTime(slotEnd)\n    });\n    current = slotEnd;\n  }\n  \n  return slots;\n}\n\n// Check if a slot overlaps with any calendar events\nfunction isSlotAvailable(slot, events) {\n  const slotStart = new Date(slot.start);\n  const slotEnd = new Date(slot.end);\n  \n  for (const event of events) {\n    const eventStart = new Date(event.start.dateTime);\n    const eventEnd = new Date(event.end.dateTime);\n    \n    // Check for overlap\n    if (slotStart < eventEnd && slotEnd > eventStart) {\n      return false;\n    }\n  }\n  \n  return true;\n}\n\n// Generate all slots for the requested day\nconst allSlots = generateDaySlots(requestedDate);\n\n// Filter to only available slots\nconst availableSlots = allSlots.filter(slot => \n  isSlotAvailable(slot, calendarEvents)\n);\n\n// Take first 3 available slots as suggestions\nconst suggestedSlots = availableSlots.slice(0, 3);\n\nreturn {\n    results: [{\n      toolCallId: toolCallId,\nresult: `UNAVAILABLE - That requested time slot is already booked. However, I have these available times that day: ${suggestedSlots.map(s => `${s.startTime} to ${s.endTime}`).join(', ')}`  }]};"},"typeVersion":2},{"id":"ed8ce086-844b-4207-888e-7f5def845232","name":"Format Available Time Response","type":"n8n-nodes-base.code","position":[3504,1552],"parameters":{"jsCode":"// Get data from Extract Availability Request node\nconst editFieldsData = $('Extract Availability Request').first().json;\nconst webhookData = $('Check Availability Webhook').first().json;\n\n// Get toolCallId from webhook body\nconst toolCallId = webhookData.body?.message?.toolCallList?.[0]?.id || 'available-check';\n\n// Create Vapi response format\nreturn [{\n  json: {\n    results: [{\n      toolCallId: toolCallId,\n      result: `The time slot on ${editFieldsData.appointmentDate} at ${editFieldsData.appointmentTime} is available for booking.`\n    }]\n  }\n}];"},"typeVersion":2},{"id":"92eec412-0717-40cc-bc2e-456e798ab190","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[2080,1472],"parameters":{"color":4,"width":300,"height":212,"content":"## Tool 1: Check Availability\n\nQueries Google Calendar for requested date, checks if time slot is available, and suggests alternatives if booked."},"typeVersion":1},{"id":"c57866e7-e8b8-4817-b664-54bea38622e8","name":"Route by Action Type","type":"n8n-nodes-base.switch","position":[2992,3488],"parameters":{"rules":{"values":[{"outputKey":"Update","conditions":{"options":{"version":3,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"55619954-92f2-44ed-9c74-4f2bf3aae47b","operator":{"type":"string","operation":"equals"},"leftValue":"={{ $json.action }}","rightValue":"update"}]},"renameOutput":true},{"outputKey":"Cancel","conditions":{"options":{"version":3,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"66c8b926-7005-415d-9d4a-385f71d9aa2a","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.action }}","rightValue":"cancel"}]},"renameOutput":true}]},"options":{}},"typeVersion":3.4},{"id":"43ad4f84-5636-4ce7-833f-db74fb6cad01","name":"Update Calendar Event","type":"n8n-nodes-base.googleCalendar","position":[3440,3312],"parameters":{"eventId":"={{ $json.id }}","calendar":{"__rl":true,"mode":"list","value":"user@example.com","cachedResultName":"Bookings"},"operation":"update","updateFields":{"end":"={{ DateTime.fromISO($('Extract Appointment Management Data').item.json.newDate + 'T' + $('Extract Appointment Management Data').item.json.newTime + ':00', { zone: 'America/Vancouver' }).plus({minutes: 30}).toISO() }}","start":"={{ DateTime.fromISO($('Extract Appointment Management Data').item.json.newDate + 'T' + $('Extract Appointment Management Data').item.json.newTime + ':00', { zone: 'America/Vancouver' }).toISO() }}"}},"typeVersion":1.3},{"id":"be76caef-429e-47da-8a3a-172608ef38a9","name":"Find Appointment to Cancel","type":"n8n-nodes-base.googleCalendar","position":[3216,3584],"parameters":{"options":{},"timeMax":"={{ DateTime.fromISO($json.originalDate + 'T' + $json.originalTime + ':00', { zone: 'America/Vancouver' }).plus({ minutes: 1 }).toISO() }}","timeMin":"={{ DateTime.fromISO($json.originalDate + 'T' + $json.originalTime + ':00', { zone: 'America/Vancouver' }).toISO() }}","calendar":{"__rl":true,"mode":"list","value":"user@example.com","cachedResultName":"Bookings"},"operation":"getAll"},"typeVersion":1.3},{"id":"6815d0a0-b874-4f19-a46f-db8a40738685","name":"Delete Calendar Event","type":"n8n-nodes-base.googleCalendar","position":[3440,3584],"parameters":{"eventId":"={{ $json.id }}","options":{},"calendar":{"__rl":true,"mode":"list","value":"user@example.com","cachedResultName":"Bookings"},"operation":"delete"},"typeVersion":1.3},{"id":"7510b91c-2635-47e4-b8bc-1191c5f47e01","name":"Manage Appointment Webhook","type":"n8n-nodes-base.webhook","position":[2544,3488],"webhookId":"YOUR_WEBHOOK_ID_MANAGE_APPOINTMENT","parameters":{"path":"manage-appointment","options":{},"httpMethod":"POST","responseMode":"responseNode"},"typeVersion":2.1},{"id":"98b1dd20-fe60-476c-bbc3-518dd66aaf5a","name":"Extract Appointment Management Data","type":"n8n-nodes-base.set","position":[2768,3488],"parameters":{"options":{},"assignments":{"assignments":[{"id":"88789c10-5026-48cf-8272-2779a9a9b99b","name":"action","type":"string","value":"={{ $json.body.message.toolCallList[0].function.arguments.action }}"},{"id":"08604b29-ed0b-415a-9d65-1ade89e5d9c6","name":"email","type":"string","value":"={{ $json.body.message.toolCallList[0].function.arguments.email }}"},{"id":"811ec028-3f20-442a-a228-938ef8b441ee","name":"originalTime","type":"string","value":"={{ $json.body.message.toolCallList[0].function.arguments.appointmentTime }}"},{"id":"460cd369-65d2-4190-aeec-6b4a0fdd8693","name":"originalDate","type":"string","value":"={{ $json.body.message.toolCallList[0].function.arguments.appointmentDate }}"},{"id":"d38bda2b-3d1c-407e-9277-2c4cd2613ee1","name":"newDate","type":"string","value":"={{ $json.body.message.toolCallList[0].function.arguments.newDate }}"},{"id":"8fe3ce2d-3f5b-4ce3-9623-7afd0a7d9ca7","name":"newTime","type":"string","value":"={{ $json.body.message.toolCallList[0].function.arguments.newTime }}"},{"id":"dda2ab30-6425-4296-8e48-0989828fd623","name":"phoneNumber","type":"string","value":"={{ $json.body.message.toolCallList[0].function.arguments.phoneNumber }}"},{"id":"86b4031c-6b5d-4a59-84e3-f814d24123eb","name":"name","type":"string","value":"={{ $json.body.message.toolCalls[0].function.arguments.name }}"}]}},"typeVersion":3.4},{"id":"44b36764-836d-4997-8a09-27667a51c482","name":"Find Appointment to Update","type":"n8n-nodes-base.googleCalendar","position":[3216,3312],"parameters":{"options":{"timeZone":{"__rl":true,"mode":"list","value":"America/Vancouver","cachedResultName":"America/Vancouver"}},"timeMax":"={{ DateTime.fromISO($json.originalDate + 'T' + $json.originalTime + ':00', { zone: 'America/Vancouver' }).plus({ minutes: 1 }).toISO() }}","timeMin":"={{ DateTime.fromISO($json.originalDate + 'T' + $json.originalTime + ':00', { zone: 'America/Vancouver' }).toISO() }}","calendar":{"__rl":true,"mode":"list","value":"user@example.com","cachedResultName":"Bookings"},"operation":"getAll"},"typeVersion":1.3},{"id":"1d4de4a8-3e05-48fb-a598-be2b55f1010e","name":"Respond - Reschedule Success","type":"n8n-nodes-base.respondToWebhook","position":[3888,3312],"parameters":{"options":{}},"typeVersion":1.5},{"id":"c3cea1dd-973e-47c9-887f-6f9580e8522b","name":"Respond - Cancellation Success","type":"n8n-nodes-base.respondToWebhook","position":[3888,3584],"parameters":{"options":{}},"typeVersion":1.5},{"id":"df6347f3-3fb2-44d0-9f21-79a67d233d3a","name":"Format Cancellation Success Response","type":"n8n-nodes-base.code","position":[3664,3584],"parameters":{"jsCode":"const toolCallId = $('Manage Appointment Webhook').first().json.body.message.toolCallList[0].id;\n\nreturn {\n  results: [\n    {\n      toolCallId: toolCallId,\n      result: \"Appointment cancelled successfully\"\n    }\n  ]\n};"},"typeVersion":2},{"id":"02444c73-db46-4bf3-a1d7-13952e602a8c","name":"Format Reschedule Success Response","type":"n8n-nodes-base.code","position":[3664,3312],"parameters":{"jsCode":"const toolCallId = $('Manage Appointment Webhook').first().json.body.message.toolCallList[0].id;\n\nreturn {\n  results: [\n    {\n      toolCallId: toolCallId,\n      result: \"Appointment rescheduled successfully\"\n    }\n  ]\n};"},"typeVersion":2},{"id":"f49778a4-e30d-4b02-8ac8-dfc6497d7fe9","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[2016,3376],"parameters":{"color":3,"width":300,"height":260,"content":"## Tool 3: Manage Appointments\n\nHandles cancellations and rescheduling. Routes by action type, finds existing appointment, then updates or deletes calendar event."},"typeVersion":1},{"id":"9501e517-7cb6-47b6-a219-21778d2d3f88","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[5024,1520],"parameters":{"color":5,"width":1232,"height":1904,"content":"# VAPI VOICE ASSISTANT PROMPT\n\n### Booking Appointments\nBook the appointment using the **bookAppointment** tool.\nOnce the customer has confirmed their preferred date and time slot, collect **all required information** before booking.\n\n**Required information:**\n- Name (use the name you already collected)\n- Phone number (use the number you already collected)\n- Service type (identified during service identification)\n- Date: YYYY-MM-DD format (e.g., 2026-01-15)\n- Time: HH:MM 24-hour format (e.g., 14:30 for 2:30 PM)\n- Duration: Default to 30 minutes unless otherwise specified\n- Notes: Any special requests or additional information\n\n**CRITICAL RULES for booking:**\n- Only book after the customer explicitly confirms the date and time.\n- Always use **checkAvailability** first to verify the slot is available.\n- Never book a time slot that shows as **UNAVAILABLE**.\n- If **checkAvailability** returns **UNAVAILABLE**, offer the suggested alternative times.\n- After booking, confirm all details with the customer: date, time, service type, and address.\n\n\n### Managing Existing Appointments\nWhen a customer wants to cancel or reschedule an existing appointment, use the following process.\n\n#### Locating the Appointment\nFirst, collect the information needed to find their appointment:\n\n#### Determining the Action\nAsk if they want to cancel or reschedule their appointment:  \n\n#### For Cancellations\n1. Confirm the action\n2. Use the **manageAppointment** tool with `action=\"cancel\"` to cancel the existing appointment.\n\n#### For Rescheduling\n1. Confirm the change:from [date] at [time] to [newDate] at [newTime].\"\n2. Use the **manageAppointment** tool with `action=\"update\"` to update the existing appointment.\n\n### Using the manageAppointment Tool\nWhen calling the **manageAppointment** tool, you need:\n- `name`: Customer's name\n- `phoneNumber`: Customer's phone number\n- `appointmentDate`: Current appointment date in YYYY-MM-DD format\n- `appointmentTime`: Current appointment time in HH:MM format (24-hour)\n- `action`: \"cancel\" or \"update\"\n- `newDate`: New appointment date in YYYY-MM-DD format (rescheduling only)\n- `newTime`: New appointment time in HH:MM format (24-hour) (rescheduling only)\n\n**CRITICAL:** Always verify the appointment details with the customer before using the tool. Never cancel or reschedule without explicit confirmation.\n\n### Confirmation and Wrap-up\n1. Summarize details:\n\n## Response Guidelines\n- Use explicit confirmation for addresses, dates, and times.\n- Ask only one question at a time.\n- For addresses, confirm:\n  - \"That's [house number] [street name], [city], [zip code]. Is that correct?\"\n\n### For Rescheduling Requests\n- Locate the existing appointment:\n- Verify details:\n- Offer alternatives:\n- Confirm change:\n\n**When you receive a response from the checkAvailability tool:**\n- Always read and use the exact information provided in the tool response.\n- If the response says the time slot is available, inform the customer it is available.\n- If the response says the time slot is not available, tell the customer it is not available and offer the alternative time slots provided.\n- Do not make assumptions or provide different information than what the tool returned.\n- The tool response contains real-time availability data—trust it completely."},"typeVersion":1},{"id":"389acfc3-2633-47c1-92d2-b715bce1d48b","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[240,1840],"parameters":{"width":976,"height":864,"content":"# Book Appointments using Vapi and Google Calendar\nUse this workflow to book, cancel, or reschedule appointments using Vapi and Google Calendar\n\n## How it works\nThe Check Availability workflow checks if appointments exist on Google Calendar and returns a response to Vapi.\nThe Book Appointment workflow schedules an appointment on Google Calendar.\nThe Manage Appointments workflow updates or cancels appointments based on the user’s request.\n\n## Key Features:\n1. Ability to book, update, or cancel an appointment\n2. Validates required fields before booking\n3. Handles errors with helpful user messages\n4. Returns a Vapi-compatible response format\n\n\n## Set up steps\n### Prerequisites\n1. Vapi.ai account\n2. Google Calendar\n3. n8n instance - Self-hosted or cloud\n\n### Steps\n- Step 1: Configure Google Calendar Access\n- Step 2: Import and Configure Workflows\n- Step 3: Create Vapi Custom Tools\n- Step 4: Configure Vapi Assistant\n\n### Use Cases\nAppointment booking automation for service businesses\n\n\n\n\n"},"typeVersion":1},{"id":"c8da4a29-3b68-46c1-b8b8-067c53412556","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[3440,1168],"parameters":{"color":7,"width":528,"height":560,"content":"The top code node pulls all events, checks that time and data requested does not overlap with any events, returns time periods as unavailable and then suggests 3 alternate times closest to the requested time and returns a result in the required vapi response format. The bottom code node returns the result as available in the required vapi response format.\n"},"typeVersion":1},{"id":"c7ec83f6-17a4-4a70-baf9-1a774c16aeb5","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[3376,2144],"parameters":{"color":7,"width":496,"height":592,"content":"The top and bottom code node format the results in the required vapi response format"},"typeVersion":1},{"id":"4b9ddc95-13f0-4b08-b577-dcf84f46ead8","name":"Sticky Note7","type":"n8n-nodes-base.stickyNote","position":[3600,3168],"parameters":{"color":7,"width":512,"height":592,"content":"The code nodes format results in the required vapi response format for easy debugging on vapi terminal"},"typeVersion":1}],"active":false,"pinData":{},"settings":{"availableInMCP":false,"executionOrder":"v1"},"versionId":"11f51e95-34ee-4c62-8ea3-8fd0b3f33b67","connections":{"Extract Booking Data":{"main":[[{"node":"Validate Required Fields","type":"main","index":0}]]},"Route by Action Type":{"main":[[{"node":"Find Appointment to Update","type":"main","index":0}],[{"node":"Find Appointment to Cancel","type":"main","index":0}]]},"Create Calendar Event":{"main":[[{"node":"Format Booking Success Response","type":"main","index":0}]]},"Delete Calendar Event":{"main":[[{"node":"Format Cancellation Success Response","type":"main","index":0}]]},"Update Calendar Event":{"main":[[{"node":"Format Reschedule Success Response","type":"main","index":0}]]},"Book Appointment Webhook":{"main":[[{"node":"Extract Booking Data","type":"main","index":0}]]},"Validate Required Fields":{"main":[[{"node":"Create Calendar Event","type":"main","index":0}],[{"node":"Format Validation Error Response","type":"main","index":0}]]},"Check Availability Webhook":{"main":[[{"node":"Extract Availability Request","type":"main","index":0}]]},"Find Appointment to Cancel":{"main":[[{"node":"Delete Calendar Event","type":"main","index":0}]]},"Find Appointment to Update":{"main":[[{"node":"Update Calendar Event","type":"main","index":0}]]},"Manage Appointment Webhook":{"main":[[{"node":"Extract Appointment Management Data","type":"main","index":0}]]},"Check Time Slot Availability":{"main":[[{"node":"Format Unavailable Time Response","type":"main","index":0}],[{"node":"Format Available Time Response","type":"main","index":0}]]},"Extract Availability Request":{"main":[[{"node":"Get Calendar Events for Date","type":"main","index":0}]]},"Get Calendar Events for Date":{"main":[[{"node":"Check Time Slot Availability","type":"main","index":0}]]},"Format Available Time Response":{"main":[[{"node":"Respond - Time Available","type":"main","index":0}]]},"Format Booking Success Response":{"main":[[{"node":"Respond - Booking Success","type":"main","index":0}]]},"Format Unavailable Time Response":{"main":[[{"node":"Respond - Time Unavailable","type":"main","index":0}]]},"Format Validation Error Response":{"main":[[{"node":"Respond - Validation Error","type":"main","index":0}]]},"Format Reschedule Success Response":{"main":[[{"node":"Respond - Reschedule Success","type":"main","index":0}]]},"Extract Appointment Management Data":{"main":[[{"node":"Route by Action Type","type":"main","index":0}]]},"Format Cancellation Success Response":{"main":[[{"node":"Respond - Cancellation Success","type":"main","index":0}]]}}},"lastUpdatedBy":1,"workflowInfo":{"nodeCount":35,"nodeTypes":{"n8n-nodes-base.if":{"count":2},"n8n-nodes-base.set":{"count":3},"n8n-nodes-base.code":{"count":6},"n8n-nodes-base.switch":{"count":1},"n8n-nodes-base.webhook":{"count":3},"n8n-nodes-base.stickyNote":{"count":8},"n8n-nodes-base.googleCalendar":{"count":6},"n8n-nodes-base.respondToWebhook":{"count":6}}},"status":"published","readyToDemo":null,"user":{"name":"Johnpaul Nwagwu","username":"johnpaulnwagwu","bio":"","verified":false,"links":[],"avatar":"https://gravatar.com/avatar/2fe334174853d8419e272c2634b28cd49917448cfb1d86d80b2a1439cfe547fa?r=pg&d=retro&size=200"},"nodes":[{"id":20,"icon":"fa:map-signs","name":"n8n-nodes-base.if","codex":{"data":{"alias":["Router","Filter","Condition","Logic","Boolean","Branch"],"details":"The IF node can be used to implement binary conditional logic in your workflow. You can set up one-to-many conditions to evaluate each item of data being inputted into the node. That data will either evaluate to TRUE or FALSE and route out of the node accordingly.\n\nThis node has multiple types of conditions: Bool, String, Number, and Date & Time.","resources":{"generic":[{"url":"https://n8n.io/blog/learn-to-automate-your-factorys-incident-reporting-a-step-by-step-guide/","icon":"🏭","label":"Learn to Automate Your Factory's Incident Reporting: A Step by Step Guide"},{"url":"https://n8n.io/blog/2021-the-year-to-automate-the-new-you-with-n8n/","icon":"☀️","label":"2021: The Year to Automate the New You with n8n"},{"url":"https://n8n.io/blog/why-business-process-automation-with-n8n-can-change-your-daily-life/","icon":"🧬","label":"Why business process automation with n8n can change your daily life"},{"url":"https://n8n.io/blog/create-a-toxic-language-detector-for-telegram/","icon":"🤬","label":"Create a toxic language detector for Telegram in 4 step"},{"url":"https://n8n.io/blog/no-code-ecommerce-workflow-automations/","icon":"store","label":"6 e-commerce workflows to power up your Shopify s"},{"url":"https://n8n.io/blog/how-to-build-a-low-code-self-hosted-url-shortener/","icon":"🔗","label":"How to build a low-code, self-hosted URL shortener in 3 steps"},{"url":"https://n8n.io/blog/automate-your-data-processing-pipeline-in-9-steps-with-n8n/","icon":"⚙️","label":"Automate your data processing pipeline in 9 steps"},{"url":"https://n8n.io/blog/how-to-get-started-with-crm-automation-and-no-code-workflow-ideas/","icon":"👥","label":"How to get started with CRM automation (with 3 no-code workflow ideas"},{"url":"https://n8n.io/blog/5-tasks-you-can-automate-with-notion-api/","icon":"⚡️","label":"5 tasks you can automate with the new Notion API "},{"url":"https://n8n.io/blog/automate-google-apps-for-productivity/","icon":"💡","label":"15 Google apps you can combine and automate to increase productivity"},{"url":"https://n8n.io/blog/automation-for-maintainers-of-open-source-projects/","icon":"🏷️","label":"How to automatically manage contributions to open-source projects"},{"url":"https://n8n.io/blog/how-uproc-scraped-a-multi-page-website-with-a-low-code-workflow/","icon":" 🕸️","label":"How uProc scraped a multi-page website with a low-code workflow"},{"url":"https://n8n.io/blog/5-workflow-automations-for-mattermost-that-we-love-at-n8n/","icon":"🤖","label":"5 workflow automations for Mattermost that we love at n8n"},{"url":"https://n8n.io/blog/why-this-product-manager-loves-workflow-automation-with-n8n/","icon":"🧠","label":"Why this Product Manager loves workflow automation with n8n"},{"url":"https://n8n.io/blog/sending-automated-congratulations-with-google-sheets-twilio-and-n8n/","icon":"🙌","label":"Sending Automated Congratulations with Google Sheets, Twilio, and n8n "},{"url":"https://n8n.io/blog/how-to-set-up-a-ci-cd-pipeline-with-no-code/","icon":"🎡","label":"How to set up a no-code CI/CD pipeline with GitHub and TravisCI"},{"url":"https://n8n.io/blog/benefits-of-automation-and-n8n-an-interview-with-hubspots-hugh-durkin/","icon":"🎖","label":"Benefits of automation and n8n: An interview with HubSpot's Hugh Durkin"},{"url":"https://n8n.io/blog/aws-workflow-automation/","label":"7 no-code workflow automations for Amazon Web Services"}],"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.if/"}]},"categories":["Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"Core Nodes":["Flow"]}}},"group":"[\"transform\"]","defaults":{"name":"If","color":"#408000"},"iconData":{"icon":"map-signs","type":"icon"},"displayName":"If","typeVersion":2,"nodeCategories":[{"id":9,"name":"Core Nodes"}]},{"id":38,"icon":"fa:pen","name":"n8n-nodes-base.set","codex":{"data":{"alias":["Set","JS","JSON","Filter","Transform","Map"],"resources":{"generic":[{"url":"https://n8n.io/blog/learn-to-automate-your-factorys-incident-reporting-a-step-by-step-guide/","icon":"🏭","label":"Learn to Automate Your Factory's Incident Reporting: A Step by Step Guide"},{"url":"https://n8n.io/blog/2021-the-year-to-automate-the-new-you-with-n8n/","icon":"☀️","label":"2021: The Year to Automate the New You with n8n"},{"url":"https://n8n.io/blog/automatically-pulling-and-visualizing-data-with-n8n/","icon":"📈","label":"Automatically pulling and visualizing data with n8n"},{"url":"https://n8n.io/blog/database-monitoring-and-alerting-with-n8n/","icon":"📡","label":"Database Monitoring and Alerting with n8n"},{"url":"https://n8n.io/blog/automatically-adding-expense-receipts-to-google-sheets-with-telegram-mindee-twilio-and-n8n/","icon":"🧾","label":"Automatically Adding Expense Receipts to Google Sheets with Telegram, Mindee, Twilio, and n8n"},{"url":"https://n8n.io/blog/no-code-ecommerce-workflow-automations/","icon":"store","label":"6 e-commerce workflows to power up your Shopify s"},{"url":"https://n8n.io/blog/how-to-build-a-low-code-self-hosted-url-shortener/","icon":"🔗","label":"How to build a low-code, self-hosted URL shortener in 3 steps"},{"url":"https://n8n.io/blog/automate-your-data-processing-pipeline-in-9-steps-with-n8n/","icon":"⚙️","label":"Automate your data processing pipeline in 9 steps"},{"url":"https://n8n.io/blog/how-to-get-started-with-crm-automation-and-no-code-workflow-ideas/","icon":"👥","label":"How to get started with CRM automation (with 3 no-code workflow ideas"},{"url":"https://n8n.io/blog/5-tasks-you-can-automate-with-notion-api/","icon":"⚡️","label":"5 tasks you can automate with the new Notion API "},{"url":"https://n8n.io/blog/automate-google-apps-for-productivity/","icon":"💡","label":"15 Google apps you can combine and automate to increase productivity"},{"url":"https://n8n.io/blog/how-uproc-scraped-a-multi-page-website-with-a-low-code-workflow/","icon":" 🕸️","label":"How uProc scraped a multi-page website with a low-code workflow"},{"url":"https://n8n.io/blog/building-an-expense-tracking-app-in-10-minutes/","icon":"📱","label":"Building an expense tracking app in 10 minutes"},{"url":"https://n8n.io/blog/the-ultimate-guide-to-automate-your-video-collaboration-with-whereby-mattermost-and-n8n/","icon":"📹","label":"The ultimate guide to automate your video collaboration with Whereby, Mattermost, and n8n"},{"url":"https://n8n.io/blog/5-workflow-automations-for-mattermost-that-we-love-at-n8n/","icon":"🤖","label":"5 workflow automations for Mattermost that we love at n8n"},{"url":"https://n8n.io/blog/learn-to-build-powerful-api-endpoints-using-webhooks/","icon":"🧰","label":"Learn to Build Powerful API Endpoints Using Webhooks"},{"url":"https://n8n.io/blog/how-a-membership-development-manager-automates-his-work-and-investments/","icon":"📈","label":"How a Membership Development Manager automates his work and investments"},{"url":"https://n8n.io/blog/a-low-code-bitcoin-ticker-built-with-questdb-and-n8n-io/","icon":"📈","label":"A low-code bitcoin ticker built with QuestDB and n8n.io"},{"url":"https://n8n.io/blog/how-to-set-up-a-ci-cd-pipeline-with-no-code/","icon":"🎡","label":"How to set up a no-code CI/CD pipeline with GitHub and TravisCI"},{"url":"https://n8n.io/blog/benefits-of-automation-and-n8n-an-interview-with-hubspots-hugh-durkin/","icon":"🎖","label":"Benefits of automation and n8n: An interview with HubSpot's Hugh Durkin"},{"url":"https://n8n.io/blog/how-goomer-automated-their-operations-with-over-200-n8n-workflows/","icon":"🛵","label":"How Goomer automated their operations with over 200 n8n workflows"},{"url":"https://n8n.io/blog/aws-workflow-automation/","label":"7 no-code workflow automations for Amazon Web Services"}],"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.set/"}]},"categories":["Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"Core Nodes":["Data Transformation"]}}},"group":"[\"input\"]","defaults":{"name":"Edit Fields"},"iconData":{"icon":"pen","type":"icon"},"displayName":"Edit Fields (Set)","typeVersion":3,"nodeCategories":[{"id":9,"name":"Core Nodes"}]},{"id":47,"icon":"file:webhook.svg","name":"n8n-nodes-base.webhook","codex":{"data":{"alias":["HTTP","API","Build","WH"],"resources":{"generic":[{"url":"https://n8n.io/blog/learn-how-to-automatically-cross-post-your-content-with-n8n/","icon":"✍️","label":"Learn how to automatically cross-post your content with n8n"},{"url":"https://n8n.io/blog/running-n8n-on-ships-an-interview-with-maranics/","icon":"🛳","label":"Running n8n on ships: An interview with Maranics"},{"url":"https://n8n.io/blog/how-to-build-a-low-code-self-hosted-url-shortener/","icon":"🔗","label":"How to build a low-code, self-hosted URL shortener in 3 steps"},{"url":"https://n8n.io/blog/what-are-apis-how-to-use-them-with-no-code/","icon":" 🪢","label":"What are APIs and how to use them with no code"},{"url":"https://n8n.io/blog/5-tasks-you-can-automate-with-notion-api/","icon":"⚡️","label":"5 tasks you can automate with the new Notion API "},{"url":"https://n8n.io/blog/how-a-digital-strategist-uses-n8n-for-online-marketing/","icon":"💻","label":"How a digital strategist uses n8n for online marketing"},{"url":"https://n8n.io/blog/the-ultimate-guide-to-automate-your-video-collaboration-with-whereby-mattermost-and-n8n/","icon":"📹","label":"The ultimate guide to automate your video collaboration with Whereby, Mattermost, and n8n"},{"url":"https://n8n.io/blog/how-to-automatically-give-kudos-to-contributors-with-github-slack-and-n8n/","icon":"👏","label":"How to automatically give kudos to contributors with GitHub, Slack, and n8n"},{"url":"https://n8n.io/blog/5-workflow-automations-for-mattermost-that-we-love-at-n8n/","icon":"🤖","label":"5 workflow automations for Mattermost that we love at n8n"},{"url":"https://n8n.io/blog/why-this-product-manager-loves-workflow-automation-with-n8n/","icon":"🧠","label":"Why this Product Manager loves workflow automation with n8n"},{"url":"https://n8n.io/blog/creating-custom-incident-response-workflows-with-n8n/","label":"How to automate every step of an incident response workflow"},{"url":"https://n8n.io/blog/learn-to-build-powerful-api-endpoints-using-webhooks/","icon":"🧰","label":"Learn to Build Powerful API Endpoints Using Webhooks"},{"url":"https://n8n.io/blog/learn-how-to-use-webhooks-with-mattermost-slash-commands/","icon":"🦄","label":"Learn how to use webhooks with Mattermost slash commands"},{"url":"https://n8n.io/blog/how-goomer-automated-their-operations-with-over-200-n8n-workflows/","icon":"🛵","label":"How Goomer automated their operations with over 200 n8n workflows"}],"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.webhook/"}]},"categories":["Development","Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"Core Nodes":["Helpers"]}}},"group":"[\"trigger\"]","defaults":{"name":"Webhook"},"iconData":{"type":"file","fileBuffer":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0OCIgaGVpZ2h0PSI0OCI+PHBhdGggZmlsbD0iIzM3NDc0ZiIgZD0iTTM1IDM3Yy0yLjIgMC00LTEuOC00LTRzMS44LTQgNC00IDQgMS44IDQgNC0xLjggNC00IDQiLz48cGF0aCBmaWxsPSIjMzc0NzRmIiBkPSJNMzUgNDNjLTMgMC01LjktMS40LTcuOC0zLjdsMy4xLTIuNWMxLjEgMS40IDIuOSAyLjMgNC43IDIuMyAzLjMgMCA2LTIuNyA2LTZzLTIuNy02LTYtNmMtMSAwLTIgLjMtMi45LjdsLTEuNyAxTDIzLjMgMTZsMy41LTEuOSA1LjMgOS40YzEtLjMgMi0uNSAzLS41IDUuNSAwIDEwIDQuNSAxMCAxMFM0MC41IDQzIDM1IDQzIi8+PHBhdGggZmlsbD0iIzM3NDc0ZiIgZD0iTTE0IDQzQzguNSA0MyA0IDM4LjUgNCAzM2MwLTQuNiAzLjEtOC41IDcuNS05LjdsMSAzLjlDOS45IDI3LjkgOCAzMC4zIDggMzNjMCAzLjMgMi43IDYgNiA2czYtMi43IDYtNnYtMmgxNXY0SDIzLjhjLS45IDQuNi01IDgtOS44IDgiLz48cGF0aCBmaWxsPSIjZTkxZTYzIiBkPSJNMTQgMzdjLTIuMiAwLTQtMS44LTQtNHMxLjgtNCA0LTQgNCAxLjggNCA0LTEuOCA0LTQgNCIvPjxwYXRoIGZpbGw9IiMzNzQ3NGYiIGQ9Ik0yNSAxOWMtMi4yIDAtNC0xLjgtNC00czEuOC00IDQtNCA0IDEuOCA0IDQtMS44IDQtNCA0Ii8+PHBhdGggZmlsbD0iI2U5MWU2MyIgZD0ibTE1LjcgMzQtMy40LTIgNS45LTkuN2MtMi0xLjktMy4yLTQuNS0zLjItNy4zIDAtNS41IDQuNS0xMCAxMC0xMHMxMCA0LjUgMTAgMTBjMCAuOS0uMSAxLjctLjMgMi41bC0zLjktMWMuMS0uNS4yLTEgLjItMS41IDAtMy4zLTIuNy02LTYtNnMtNiAyLjctNiA2YzAgMi4xIDEuMSA0IDIuOSA1LjFsMS43IDF6Ii8+PC9zdmc+"},"displayName":"Webhook","typeVersion":2,"nodeCategories":[{"id":5,"name":"Development"},{"id":9,"name":"Core Nodes"}]},{"id":112,"icon":"fa:map-signs","name":"n8n-nodes-base.switch","codex":{"data":{"alias":["Router","If","Path","Filter","Condition","Logic","Branch","Case"],"resources":{"generic":[{"url":"https://n8n.io/blog/2021-the-year-to-automate-the-new-you-with-n8n/","icon":"☀️","label":"2021: The Year to Automate the New You with n8n"},{"url":"https://n8n.io/blog/how-to-get-started-with-crm-automation-and-no-code-workflow-ideas/","icon":"👥","label":"How to get started with CRM automation (with 3 no-code workflow ideas"},{"url":"https://n8n.io/blog/build-your-own-virtual-assistant-with-n8n-a-step-by-step-guide/","icon":"👦","label":"Build your own virtual assistant with n8n: A step by step guide"},{"url":"https://n8n.io/blog/automation-for-maintainers-of-open-source-projects/","icon":"🏷️","label":"How to automatically manage contributions to open-source projects"}],"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.switch/"}]},"categories":["Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"Core Nodes":["Flow"]}}},"group":"[\"transform\"]","defaults":{"name":"Switch","color":"#506000"},"iconData":{"icon":"map-signs","type":"icon"},"displayName":"Switch","typeVersion":3,"nodeCategories":[{"id":9,"name":"Core Nodes"}]},{"id":317,"icon":"file:googleCalendar.svg","name":"n8n-nodes-base.googleCalendar","codex":{"data":{"resources":{"generic":[{"url":"https://n8n.io/blog/how-to-host-virtual-coffee-breaks-with-n8n/","icon":"☕️","label":"How to host virtual coffee breaks with n8n"},{"url":"https://n8n.io/blog/supercharging-your-conference-registration-process-with-n8n/","icon":"🎫","label":"Supercharging your conference registration process with n8n"},{"url":"https://n8n.io/blog/automate-google-apps-for-productivity/","icon":"💡","label":"15 Google apps you can combine and automate to increase productivity"},{"url":"https://n8n.io/blog/your-business-doesnt-need-you-to-operate/","icon":" 🖥️","label":"Hey founders! Your business doesn't need you to operate"},{"url":"https://n8n.io/blog/5-workflow-automations-for-mattermost-that-we-love-at-n8n/","icon":"🤖","label":"5 workflow automation for Mattermost that we love at n8n"},{"url":"https://n8n.io/blog/tracking-time-spent-in-meetings-with-google-calendar-twilio-and-n8n/","icon":"🗓","label":"Tracking Time Spent in Meetings With Google Calendar, Twilio, and n8n"}],"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.googlecalendar/"}],"credentialDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/credentials/google/oauth-single-service/"}]},"categories":["Productivity"],"nodeVersion":"1.0","codexVersion":"1.0"}},"group":"[\"input\"]","defaults":{"name":"Google Calendar"},"iconData":{"type":"file","fileBuffer":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiBmaWxsPSIjZmZmIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiB2aWV3Qm94PSIwIDAgODEgODIiPjx1c2UgeGxpbms6aHJlZj0iI2EiIHg9Ii41IiB5PSIuNSIvPjxzeW1ib2wgaWQ9ImEiIG92ZXJmbG93PSJ2aXNpYmxlIj48ZyBmaWxsLXJ1bGU9Im5vbnplcm8iIHN0cm9rZT0ibm9uZSI+PHBhdGggZD0iTTYxLjA1MiAxOC45NDdIMTguOTQ3djQyLjEwNWg0Mi4xMDV6Ii8+PHBhdGggZmlsbD0iI2VhNDMzNSIgZD0iTTYxLjA1MyA4MCA4MCA2MS4wNTNINjEuMDUzeiIvPjxwYXRoIGZpbGw9IiNmYmJjMDQiIGQ9Ik04MCAxOC45NDdINjEuMDUzdjQyLjEwNUg4MHoiLz48cGF0aCBmaWxsPSIjMzRhODUzIiBkPSJNNjEuMDUyIDYxLjA1M0gxOC45NDdWODBoNDIuMTA1eiIvPjxwYXRoIGZpbGw9IiMxODgwMzgiIGQ9Ik0wIDYxLjA1M3YxMi42MzJBNi4zMTQgNi4zMTQgMCAwIDAgNi4zMTYgODBoMTIuNjMyVjYxLjA1M3oiLz48cGF0aCBmaWxsPSIjMTk2N2QyIiBkPSJNODAgMTguOTQ3VjYuMzE2QTYuMzE0IDYuMzE0IDAgMCAwIDczLjY4NSAwSDYxLjA1M3YxOC45NDd6Ii8+PHBhdGggZmlsbD0iIzQyODVmNCIgZD0iTTYxLjA1MyAwSDYuMzE2QTYuMzE0IDYuMzE0IDAgMCAwIDAgNi4zMTZ2NTQuNzM3aDE4Ljk0N1YxOC45NDdoNDIuMTA1VjB6TTI3LjU4NCA1MS42MTFjLTEuNTc0LTEuMDYzLTIuNjYzLTIuNjE2LTMuMjU4LTQuNjY4bDMuNjUzLTEuNTA1cS40OTggMS44OTQgMS43MzcgMi45MzdjMS4yMzkgMS4wNDMgMS44MjEgMS4wMzcgMi45ODkgMS4wMzdxMS43OTIgMCAzLjA3OS0xLjA4OWMxLjI4Ny0xLjA4OSAxLjI5LTEuNjUzIDEuMjktMi43NzRhMy40NCAzLjQ0IDAgMCAwLTEuMzU4LTIuODExYy0uOTA1LS43MjctMi4wNDItMS4wODktMy40LTEuMDg5aC0yLjExMXYtMy42MTZIMzIuMXExLjc1MiAwIDIuOTUzLS45NDdjMS4yMDEtLjk0NyAxLjItMS40OTUgMS4yLTIuNTk1cTAtMS40NjctMS4wNzQtMi4zNDJjLTEuMDc0LS44NzUtMS42MjEtLjg3OS0yLjcyMS0uODc5cS0xLjYxLS4wMDItMi41NTguODU4Yy0uOTQ4Ljg2LTEuMTA2IDEuMzAxLTEuMzc5IDIuMTExbC0zLjYxNi0xLjUwNWMuNDc5LTEuMzU4IDEuMzU4LTIuNTU4IDIuNjQ3LTMuNTk1czIuOTM3LTEuNTU4IDQuOTM3LTEuNTU4cTIuMjItLjAwMiAzLjk4OS44NThjMS43NjkuODYgMi4xMDUgMS4zNjggMi43NzQgMi4zNzlzMSAyLjE1MyAxIDMuNDE2cTAgMS45MzItLjkzMiAzLjI3NGMtLjkzMiAxLjM0Mi0xLjM4NCAxLjU3OS0yLjI4OSAyLjA1OHYuMjE2YTYuOTUgNi45NSAwIDAgMSAyLjkzNyAyLjI4OXExLjE0NiAxLjUzOCAxLjE0NyAzLjY4NGMuMDAxIDIuMTQ2LS4zNjMgMi43MTEtMS4wODkgMy44MzJzLTEuNzMyIDIuMDA1LTMuMDA1IDIuNjQ3Yy0xLjI3OS42NDItMi43MTYuOTY4LTQuMzExLjk2OC0xLjg0Ny4wMDUtMy41NTMtLjUyNi01LjEyNi0xLjU4OXptMjIuNDM3LTE4LjEyNi00LjAxIDIuOS0yLjAwNS0zLjA0MiA3LjE5NS01LjE4OWgyLjc1OHYyNC40NzloLTMuOTM3VjMzLjQ4NHoiLz48L2c+PC9zeW1ib2w+PC9zdmc+"},"displayName":"Google Calendar","typeVersion":1,"nodeCategories":[{"id":4,"name":"Productivity"}]},{"id":535,"icon":"file:webhook.svg","name":"n8n-nodes-base.respondToWebhook","codex":{"data":{"resources":{"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.respondtowebhook/"}]},"categories":["Core Nodes","Utility"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"Core Nodes":["Helpers"]}}},"group":"[\"transform\"]","defaults":{"name":"Respond to Webhook"},"iconData":{"type":"file","fileBuffer":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0OCIgaGVpZ2h0PSI0OCI+PHBhdGggZmlsbD0iIzM3NDc0ZiIgZD0iTTM1IDM3Yy0yLjIgMC00LTEuOC00LTRzMS44LTQgNC00IDQgMS44IDQgNC0xLjggNC00IDQiLz48cGF0aCBmaWxsPSIjMzc0NzRmIiBkPSJNMzUgNDNjLTMgMC01LjktMS40LTcuOC0zLjdsMy4xLTIuNWMxLjEgMS40IDIuOSAyLjMgNC43IDIuMyAzLjMgMCA2LTIuNyA2LTZzLTIuNy02LTYtNmMtMSAwLTIgLjMtMi45LjdsLTEuNyAxTDIzLjMgMTZsMy41LTEuOSA1LjMgOS40YzEtLjMgMi0uNSAzLS41IDUuNSAwIDEwIDQuNSAxMCAxMFM0MC41IDQzIDM1IDQzIi8+PHBhdGggZmlsbD0iIzM3NDc0ZiIgZD0iTTE0IDQzQzguNSA0MyA0IDM4LjUgNCAzM2MwLTQuNiAzLjEtOC41IDcuNS05LjdsMSAzLjlDOS45IDI3LjkgOCAzMC4zIDggMzNjMCAzLjMgMi43IDYgNiA2czYtMi43IDYtNnYtMmgxNXY0SDIzLjhjLS45IDQuNi01IDgtOS44IDgiLz48cGF0aCBmaWxsPSIjZTkxZTYzIiBkPSJNMTQgMzdjLTIuMiAwLTQtMS44LTQtNHMxLjgtNCA0LTQgNCAxLjggNCA0LTEuOCA0LTQgNCIvPjxwYXRoIGZpbGw9IiMzNzQ3NGYiIGQ9Ik0yNSAxOWMtMi4yIDAtNC0xLjgtNC00czEuOC00IDQtNCA0IDEuOCA0IDQtMS44IDQtNCA0Ii8+PHBhdGggZmlsbD0iI2U5MWU2MyIgZD0ibTE1LjcgMzQtMy40LTIgNS45LTkuN2MtMi0xLjktMy4yLTQuNS0zLjItNy4zIDAtNS41IDQuNS0xMCAxMC0xMHMxMCA0LjUgMTAgMTBjMCAuOS0uMSAxLjctLjMgMi41bC0zLjktMWMuMS0uNS4yLTEgLjItMS41IDAtMy4zLTIuNy02LTYtNnMtNiAyLjctNiA2YzAgMi4xIDEuMSA0IDIuOSA1LjFsMS43IDF6Ii8+PC9zdmc+"},"displayName":"Respond to Webhook","typeVersion":2,"nodeCategories":[{"id":7,"name":"Utility"},{"id":9,"name":"Core Nodes"}]},{"id":565,"icon":"fa:sticky-note","name":"n8n-nodes-base.stickyNote","codex":{"data":{"alias":["Comments","Notes","Sticky"],"categories":["Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"Core Nodes":["Helpers"]}}},"group":"[\"input\"]","defaults":{"name":"Sticky Note","color":"#FFD233"},"iconData":{"icon":"sticky-note","type":"icon"},"displayName":"Sticky Note","typeVersion":1,"nodeCategories":[{"id":9,"name":"Core Nodes"}]},{"id":834,"icon":"file:code.svg","name":"n8n-nodes-base.code","codex":{"data":{"alias":["cpde","Javascript","JS","Python","Script","Custom Code","Function"],"details":"The Code node allows you to execute JavaScript in your workflow.","resources":{"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.code/"}]},"categories":["Development","Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"Core Nodes":["Helpers","Data Transformation"]}}},"group":"[\"transform\"]","defaults":{"name":"Code"},"iconData":{"type":"file","fileBuffer":"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTEyIiBoZWlnaHQ9IjUxMiIgdmlld0JveD0iMCAwIDUxMiA1MTIiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMF8xMTcxXzQ0MSkiPgo8cGF0aCBkPSJNMTcwLjI4MyA0OEgxOTYuNUMyMDMuMTI3IDQ4IDIwOC41IDQyLjYyNzQgMjA4LjUgMzZWMTJDMjA4LjUgNS4zNzI1OCAyMDMuMTI3IDAgMTk2LjUgMEgxNzAuMjgzQzEyNi4xIDAgOTAuMjgzIDM1LjgxNzIgOTAuMjgzIDgwVjE3NkM5MC4yODMgMjA2LjkyOCA2NS4yMTA5IDIzMiAzNC4yODMgMjMySDIzQzE2LjM3MjYgMjMyIDExIDIzNy4zNzIgMTEgMjQ0VjI2OEMxMSAyNzQuNjI3IDE2LjM3MjQgMjgwIDIyLjk5OTYgMjgwTDM0LjI4MyAyODBDNjUuMjEwOSAyODAgOTAuMjgzIDMwNS4wNzIgOTAuMjgzIDMzNlY0NDBDOTAuMjgzIDQ3OS43NjQgMTIyLjUxOCA1MTIgMTYyLjI4MyA1MTJIMTk2LjVDMjAzLjEyNyA1MTIgMjA4LjUgNTA2LjYyNyAyMDguNSA1MDBWNDc2QzIwOC41IDQ2OS4zNzMgMjAzLjEyNyA0NjQgMTk2LjUgNDY0SDE2Mi4yODNDMTQ5LjAyOCA0NjQgMTM4LjI4MyA0NTMuMjU1IDEzOC4yODMgNDQwVjMzNkMxMzguMjgzIDMwOS4wMjIgMTI4LjAxMSAyODQuNDQzIDExMS4xNjQgMjY1Ljk2MUMxMDYuMTA5IDI2MC40MTYgMTA2LjEwOSAyNTEuNTg0IDExMS4xNjQgMjQ2LjAzOUMxMjguMDExIDIyNy41NTcgMTM4LjI4MyAyMDIuOTc4IDEzOC4yODMgMTc2VjgwQzEzOC4yODMgNjIuMzI2OSAxNTIuNjEgNDggMTcwLjI4MyA0OFoiIGZpbGw9IiNGRjk5MjIiLz4KPHBhdGggZD0iTTMwNSAzNkMzMDUgNDIuNjI3NCAzMTAuMzczIDQ4IDMxNyA0OEgzNDIuOTc5QzM2MC42NTIgNDggMzc0Ljk3OCA2Mi4zMjY5IDM3NC45NzggODBWMTc2QzM3NC45NzggMjAyLjk3OCAzODUuMjUxIDIyNy41NTcgNDAyLjA5OCAyNDYuMDM5QzQwNy4xNTMgMjUxLjU4NCA0MDcuMTUzIDI2MC40MTYgNDAyLjA5OCAyNjUuOTYxQzM4NS4yNTEgMjg0LjQ0MyAzNzQuOTc4IDMwOS4wMjIgMzc0Ljk3OCAzMzZWNDMyQzM3NC45NzggNDQ5LjY3MyAzNjAuNjUyIDQ2NCAzNDIuOTc5IDQ2NEgzMTdDMzEwLjM3MyA0NjQgMzA1IDQ2OS4zNzMgMzA1IDQ3NlY1MDBDMzA1IDUwNi42MjcgMzEwLjM3MyA1MTIgMzE3IDUxMkgzNDIuOTc5QzM4Ny4xNjEgNTEyIDQyMi45NzggNDc2LjE4MyA0MjIuOTc4IDQzMlYzMzZDNDIyLjk3OCAzMDUuMDcyIDQ0OC4wNTEgMjgwIDQ3OC45NzkgMjgwSDQ5MEM0OTYuNjI3IDI4MCA1MDIgMjc0LjYyOCA1MDIgMjY4VjI0NEM1MDIgMjM3LjM3MyA0OTYuNjI4IDIzMiA0OTAgMjMyTDQ3OC45NzkgMjMyQzQ0OC4wNTEgMjMyIDQyMi45NzggMjA2LjkyOCA0MjIuOTc4IDE3NlY4MEM0MjIuOTc4IDM1LjgxNzIgMzg3LjE2MSAwIDM0Mi45NzkgMEgzMTdDMzEwLjM3MyAwIDMwNSA1LjM3MjU4IDMwNSAxMlYzNloiIGZpbGw9IiNGRjk5MjIiLz4KPC9nPgo8ZGVmcz4KPGNsaXBQYXRoIGlkPSJjbGlwMF8xMTcxXzQ0MSI+CjxyZWN0IHdpZHRoPSI1MTIiIGhlaWdodD0iNTEyIiBmaWxsPSJ3aGl0ZSIvPgo8L2NsaXBQYXRoPgo8L2RlZnM+Cjwvc3ZnPgo="},"displayName":"Code","typeVersion":2,"nodeCategories":[{"id":5,"name":"Development"},{"id":9,"name":"Core Nodes"}]}],"categories":[{"id":40,"name":"Support Chatbot"},{"id":47,"name":"AI Chatbot"}],"image":[]}}