{
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "8e9cbd41-5f6f-4209-bc9d-b924925c2d25",
      "name": "Calendly Webhook",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -1280,
        -848
      ],
      "parameters": {
        "path": "calendly-webhook",
        "options": {
          "responseData": "allEntries"
        },
        "httpMethod": "POST"
      },
      "typeVersion": 2
    },
    {
      "id": "decdb973-67e1-479a-9314-8f8231b52fc5",
      "name": "Parse Calendly Event",
      "type": "n8n-nodes-base.code",
      "position": [
        -1040,
        -848
      ],
      "parameters": {
        "jsCode": "// Robust parser for Calendly API v1 and v2\nconst payload = $input.item.json.body || $input.item.json;\nconst event = payload.event || 'invitee.created';\nconst data = payload.payload || payload;\n\n// Extract invitee data\nconst invitee = data.invitee || data;\nconst eventDetails = data.event || data.scheduled_event || {};\nconst questions = data.questions_and_answers || invitee.questions_and_answers || [];\n\n// Process custom form answers\nconst customAnswers = {};\nquestions.forEach(q => {\n  customAnswers[q.question] = q.answer;\n});\n\n// Extract all relevant data\nconst email = invitee.email || '';\nconst name = invitee.name || 'Guest';\nconst startTime = eventDetails.start_time || invitee.start_time || '';\nconst endTime = eventDetails.end_time || invitee.end_time || '';\nconst timezone = invitee.timezone || 'UTC';\nconst meetingUrl = eventDetails.location?.join_url || invitee.meeting_url || '';\nconst eventType = eventDetails.event_type?.name || eventDetails.name || 'Meeting';\nconst cancelUrl = invitee.cancel_url || '';\nconst rescheduleUrl = invitee.reschedule_url || '';\n\n// Determine event category\nlet eventCategory = 'created';\nif (event.includes('canceled')) eventCategory = 'canceled';\nif (event.includes('rescheduled')) eventCategory = 'rescheduled';\n\n// Format dates for display\nconst startDate = new Date(startTime);\nconst formattedDate = startDate.toLocaleDateString('en-US', {\n  weekday: 'long',\n  year: 'numeric',\n  month: 'long',\n  day: 'numeric',\n  timeZone: timezone\n});\nconst formattedTime = startDate.toLocaleTimeString('en-US', {\n  hour: '2-digit',\n  minute: '2-digit',\n  timeZone: timezone\n});\n\nreturn {\n  json: {\n    // Event metadata\n    eventCategory: eventCategory,\n    eventType: event,\n    processedAt: new Date().toISOString(),\n    \n    // Invitee data\n    email: email,\n    name: name,\n    timezone: timezone,\n    \n    // Meeting data\n    meetingName: eventType,\n    startTime: startTime,\n    endTime: endTime,\n    startTimeISO: startTime,\n    formattedDate: formattedDate,\n    formattedTime: formattedTime,\n    meetingUrl: meetingUrl,\n    cancelUrl: cancelUrl,\n    rescheduleUrl: rescheduleUrl,\n    \n    // Custom answers\n    customAnswers: customAnswers,\n    \n    // Unique ID for tracking\n    eventId: `CAL-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "91ebc749-da04-49d4-afa4-18df349bbf07",
      "name": "Event Router",
      "type": "n8n-nodes-base.switch",
      "position": [
        -800,
        -864
      ],
      "parameters": {
        "rules": {
          "rules": [
            {
              "value2": "created"
            },
            {
              "value2": "canceled"
            },
            {
              "value2": "rescheduled"
            }
          ]
        },
        "value1": "={{ $json.eventCategory }}",
        "dataType": "string"
      },
      "typeVersion": 2
    },
    {
      "id": "00db7ebb-0435-48ba-b99d-7161e467745c",
      "name": "Log to Google Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -464,
        -1008
      ],
      "parameters": {
        "columns": {
          "value": {
            "Date": "={{ $json.formattedDate }}",
            "Name": "={{ $json.name }}",
            "Time": "={{ $json.formattedTime }}",
            "Email": "={{ $json.email }}",
            "Status": "Confirmed",
            "Event ID": "={{ $json.eventId }}",
            "Timezone": "={{ $json.timezone }}",
            "Date Logged": "={{ $json.processedAt }}",
            "Meeting URL": "={{ $json.meetingUrl }}",
            "Meeting Type": "={{ $json.meetingName }}"
          },
          "mappingMode": "defineBelow"
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "Bookings"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_DOCUMENT_ID"
        }
      },
      "typeVersion": 4
    },
    {
      "id": "369484ae-7487-4978-ac6e-f31aedb9b147",
      "name": "Create Calendar Event",
      "type": "n8n-nodes-base.googleCalendar",
      "position": [
        -224,
        -1008
      ],
      "parameters": {
        "end": "={{ $('Parse Calendly Event').item.json.endTime }}",
        "start": "={{ $('Parse Calendly Event').item.json.startTime }}",
        "calendar": {
          "__rl": true,
          "mode": "list",
          "value": "primary"
        },
        "additionalFields": {
          "summary": "={{ $('Parse Calendly Event').item.json.meetingName }} - {{ $('Parse Calendly Event').item.json.name }}",
          "description": "Meeting with {{ $('Parse Calendly Event').item.json.name }} ({{ $('Parse Calendly Event').item.json.email }})\n\nJoin: {{ $('Parse Calendly Event').item.json.meetingUrl }}"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "cefb5f50-286c-458d-ac13-c8bbbed78623",
      "name": "Slack - New Booking",
      "type": "n8n-nodes-base.slack",
      "position": [
        16,
        -1008
      ],
      "parameters": {
        "text": ":calendar: *New Meeting Booked*",
        "otherOptions": {
          "includeLinkToWorkflow": false
        }
      },
      "typeVersion": 2
    },
    {
      "id": "b7e4ac62-c2cd-4a18-b5bd-0e7954e5a9b8",
      "name": "Prepare Confirmation Email",
      "type": "n8n-nodes-base.code",
      "position": [
        256,
        -1008
      ],
      "parameters": {
        "jsCode": "// CONFIG - Customize these values\nconst CONFIG = {\n  companyName: 'Your Company',\n  primaryColor: '#10b981',\n  secondaryColor: '#667eea',\n  logoUrl: '', // Optional: Your logo URL\n  footerText: 'Thank you for booking with us'\n};\n\nconst data = $('Parse Calendly Event').first().json;\n\nconst emailHtml = `\n<!DOCTYPE html>\n<html>\n<head>\n  <meta charset=\"UTF-8\">\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n</head>\n<body style=\"margin:0;padding:0;font-family:'Segoe UI',Roboto,Arial,sans-serif;background:#f4f7fa;\">\n  <table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"background:#f4f7fa;padding:40px 20px;\">\n    <tr>\n      <td align=\"center\">\n        <table width=\"600\" cellpadding=\"0\" cellspacing=\"0\" style=\"background:#ffffff;border-radius:16px;box-shadow:0 4px 20px rgba(0,0,0,0.08);overflow:hidden;\">\n          \n          <!-- Header -->\n          <tr>\n            <td style=\"background:linear-gradient(135deg, ${CONFIG.primaryColor} 0%, ${CONFIG.secondaryColor} 100%);padding:40px 30px;text-align:center;\">\n              ${CONFIG.logoUrl ? `<img src=\"${CONFIG.logoUrl}\" alt=\"Logo\" style=\"max-height:50px;margin-bottom:15px;\">` : ''}\n              <h1 style=\"margin:0;color:#ffffff;font-size:28px;font-weight:600;\">Meeting Confirmed!</h1>\n            </td>\n          </tr>\n          \n          <!-- Content -->\n          <tr>\n            <td style=\"padding:40px 30px;\">\n              <h2 style=\"margin:0 0 20px;color:#1a202c;font-size:22px;\">Hi ${data.name},</h2>\n              <p style=\"color:#4a5568;font-size:16px;line-height:1.7;margin:0 0 25px;\">Your meeting with <strong>${CONFIG.companyName}</strong> has been confirmed.</p>\n              \n              <!-- Meeting Details Card -->\n              <div style=\"background:linear-gradient(135deg, #f0fdf4 0%, #ecfdf5 100%);border-radius:12px;padding:25px;margin:25px 0;border-left:4px solid ${CONFIG.primaryColor};\">\n                <table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\">\n                  <tr>\n                    <td style=\"padding:8px 0;\">\n                      <span style=\"color:#166534;font-size:17px;font-weight:600;\">${data.formattedDate}</span>\n                    </td>\n                  </tr>\n                  <tr>\n                    <td style=\"padding:8px 0;\">\n                      <span style=\"color:#166534;font-size:17px;font-weight:600;\">${data.formattedTime}</span>\n                    </td>\n                  </tr>\n                  <tr>\n                    <td style=\"padding:8px 0;\">\n                      <span style=\"color:#166534;font-size:16px;\">${data.meetingName}</span>\n                    </td>\n                  </tr>\n                </table>\n              </div>\n              \n              <!-- Join Button -->\n              ${data.meetingUrl ? `\n              <div style=\"text-align:center;margin:30px 0;\">\n                <a href=\"${data.meetingUrl}\" style=\"display:inline-block;background:linear-gradient(135deg, ${CONFIG.secondaryColor} 0%, #5a67d8 100%);color:#ffffff;text-decoration:none;padding:16px 45px;border-radius:10px;font-size:16px;font-weight:600;box-shadow:0 4px 15px rgba(102,126,234,0.4);\">\n                  Join Meeting\n                </a>\n              </div>\n              ` : ''}\n              \n              <!-- Action Links -->\n              <div style=\"background:#f7fafc;border-radius:10px;padding:20px;margin:25px 0;text-align:center;\">\n                <p style=\"color:#718096;font-size:14px;margin:0 0 15px;\">Need to make changes?</p>\n                <table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\">\n                  <tr>\n                    ${data.rescheduleUrl ? `<td style=\"text-align:center;\"><a href=\"${data.rescheduleUrl}\" style=\"color:${CONFIG.secondaryColor};font-size:14px;text-decoration:none;font-weight:500;\">Reschedule</a></td>` : ''}\n                    ${data.cancelUrl ? `<td style=\"text-align:center;\"><a href=\"${data.cancelUrl}\" style=\"color:#e53e3e;font-size:14px;text-decoration:none;font-weight:500;\">Cancel</a></td>` : ''}\n                  </tr>\n                </table>\n              </div>\n              \n              <!-- Tips -->\n              <div style=\"border-top:1px solid #e2e8f0;padding-top:25px;margin-top:25px;\">\n                <p style=\"color:#718096;font-size:14px;line-height:1.6;margin:0;\">\n                  <strong>Tip:</strong> Join the meeting 2-3 minutes before the scheduled time.\n                </p>\n              </div>\n            </td>\n          </tr>\n          \n          <!-- Footer -->\n          <tr>\n            <td style=\"background:#f7fafc;padding:25px 30px;text-align:center;border-top:1px solid #e2e8f0;\">\n              <p style=\"margin:0 0 10px;color:#718096;font-size:13px;\">${CONFIG.footerText}</p>\n              <p style=\"margin:0;color:#a0aec0;font-size:12px;\">${new Date().getFullYear()} ${CONFIG.companyName}. All rights reserved.</p>\n            </td>\n          </tr>\n          \n        </table>\n      </td>\n    </tr>\n  </table>\n</body>\n</html>\n`;\n\nreturn {\n  json: {\n    to: data.email,\n    subject: `Meeting Confirmed - ${data.formattedDate} at ${data.formattedTime}`,\n    htmlContent: emailHtml,\n    eventId: data.eventId\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "cf36773b-1710-4032-ab9c-b56c0eb53446",
      "name": "Send Confirmation Email",
      "type": "n8n-nodes-base.gmail",
      "position": [
        496,
        -1008
      ],
      "parameters": {
        "sendTo": "={{ $json.to }}",
        "message": "={{ $json.htmlContent }}",
        "options": {
          "appendAttribution": false
        },
        "subject": "={{ $json.subject }}"
      },
      "typeVersion": 2
    },
    {
      "id": "5dcb1944-e95c-4432-a83b-3cf9db38903c",
      "name": "Log Cancellation",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -448,
        -624
      ],
      "parameters": {
        "columns": {
          "value": {
            "Date": "={{ $('Parse Calendly Event').item.json.formattedDate }}",
            "Name": "={{ $('Parse Calendly Event').item.json.name }}",
            "Time": "={{ $('Parse Calendly Event').item.json.formattedTime }}",
            "Email": "={{ $('Parse Calendly Event').item.json.email }}",
            "Status": "Canceled",
            "Event ID": "={{ $('Parse Calendly Event').item.json.eventId }}",
            "Timezone": "={{ $('Parse Calendly Event').item.json.timezone }}",
            "Date Logged": "={{ $('Parse Calendly Event').item.json.processedAt }}",
            "Meeting URL": "={{ $('Parse Calendly Event').item.json.meetingUrl }}",
            "Meeting Type": "={{ $('Parse Calendly Event').item.json.meetingName }}"
          },
          "mappingMode": "defineBelow"
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "Bookings"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_DOCUMENT_ID"
        }
      },
      "typeVersion": 4
    },
    {
      "id": "4fb3f3f9-f83b-4aba-a0b0-58b2377b850c",
      "name": "Slack - Cancellation",
      "type": "n8n-nodes-base.slack",
      "position": [
        -208,
        -624
      ],
      "parameters": {
        "text": ":x: *Meeting Canceled*",
        "otherOptions": {
          "includeLinkToWorkflow": false
        }
      },
      "typeVersion": 2
    },
    {
      "id": "37bc05c0-2061-4a26-ace8-8ed0a674e21d",
      "name": "Prepare Cancellation Email",
      "type": "n8n-nodes-base.code",
      "position": [
        32,
        -624
      ],
      "parameters": {
        "jsCode": "// CONFIG - Customize these values\nconst CONFIG = {\n  companyName: 'Your Company',\n  primaryColor: '#ef4444',\n  calendlyUrl: 'https://calendly.com/your-username' // Your Calendly link\n};\n\nconst data = $('Parse Calendly Event').first().json;\n\nconst emailHtml = `\n<!DOCTYPE html>\n<html>\n<head>\n  <meta charset=\"UTF-8\">\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n</head>\n<body style=\"margin:0;padding:0;font-family:'Segoe UI',Roboto,Arial,sans-serif;background:#f4f7fa;\">\n  <table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"background:#f4f7fa;padding:40px 20px;\">\n    <tr>\n      <td align=\"center\">\n        <table width=\"600\" cellpadding=\"0\" cellspacing=\"0\" style=\"background:#ffffff;border-radius:16px;box-shadow:0 4px 20px rgba(0,0,0,0.08);overflow:hidden;\">\n          \n          <!-- Header -->\n          <tr>\n            <td style=\"background:${CONFIG.primaryColor};padding:40px 30px;text-align:center;\">\n              <h1 style=\"margin:0;color:#ffffff;font-size:28px;font-weight:600;\">Meeting Canceled</h1>\n            </td>\n          </tr>\n          \n          <!-- Content -->\n          <tr>\n            <td style=\"padding:40px 30px;\">\n              <h2 style=\"margin:0 0 20px;color:#1a202c;font-size:22px;\">Hi ${data.name},</h2>\n              <p style=\"color:#4a5568;font-size:16px;line-height:1.7;margin:0 0 25px;\">Your meeting with <strong>${CONFIG.companyName}</strong> has been canceled.</p>\n              \n              <!-- Cancelled Meeting Details -->\n              <div style=\"background:#fef2f2;border-radius:12px;padding:25px;margin:25px 0;border-left:4px solid ${CONFIG.primaryColor};\">\n                <table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\">\n                  <tr>\n                    <td style=\"padding:8px 0;\">\n                      <span style=\"color:#991b1b;font-size:16px;\">${data.formattedDate}</span>\n                    </td>\n                  </tr>\n                  <tr>\n                    <td style=\"padding:8px 0;\">\n                      <span style=\"color:#991b1b;font-size:16px;\">${data.formattedTime}</span>\n                    </td>\n                  </tr>\n                  <tr>\n                    <td style=\"padding:8px 0;\">\n                      <span style=\"color:#991b1b;font-size:16px;\">${data.meetingName}</span>\n                    </td>\n                  </tr>\n                </table>\n              </div>\n              \n              <!-- Reschedule Button -->\n              <div style=\"text-align:center;margin:30px 0;\">\n                <p style=\"color:#4a5568;font-size:16px;margin:0 0 20px;\">Would you like to schedule another meeting?</p>\n                <a href=\"${CONFIG.calendlyUrl}\" style=\"display:inline-block;background:#10b981;color:#ffffff;text-decoration:none;padding:16px 45px;border-radius:10px;font-size:16px;font-weight:600;box-shadow:0 4px 15px rgba(16,185,129,0.4);\">\n                  Book New Meeting\n                </a>\n              </div>\n            </td>\n          </tr>\n          \n          <!-- Footer -->\n          <tr>\n            <td style=\"background:#f7fafc;padding:25px 30px;text-align:center;border-top:1px solid #e2e8f0;\">\n              <p style=\"margin:0;color:#a0aec0;font-size:12px;\">${new Date().getFullYear()} ${CONFIG.companyName}. All rights reserved.</p>\n            </td>\n          </tr>\n          \n        </table>\n      </td>\n    </tr>\n  </table>\n</body>\n</html>\n`;\n\nreturn {\n  json: {\n    to: data.email,\n    subject: `Meeting Canceled - ${data.formattedDate}`,\n    htmlContent: emailHtml\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "9b9b93da-2e01-48ab-9c68-a3cbbcc71abd",
      "name": "Send Cancellation Email",
      "type": "n8n-nodes-base.gmail",
      "position": [
        272,
        -624
      ],
      "parameters": {
        "sendTo": "={{ $json.to }}",
        "message": "={{ $json.htmlContent }}",
        "options": {
          "appendAttribution": false
        },
        "subject": "={{ $json.subject }}"
      },
      "typeVersion": 2
    },
    {
      "id": "0d1e0984-8f1c-4b3e-af68-e5ea6cce2d2c",
      "name": "Log Reschedule",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -464,
        -256
      ],
      "parameters": {
        "columns": {
          "value": {
            "Date": "={{ $('Parse Calendly Event').item.json.formattedDate }}",
            "Name": "={{ $('Parse Calendly Event').item.json.name }}",
            "Time": "={{ $('Parse Calendly Event').item.json.formattedTime }}",
            "Email": "={{ $('Parse Calendly Event').item.json.email }}",
            "Status": "Rescheduled",
            "Event ID": "={{ $('Parse Calendly Event').item.json.eventId }}",
            "Timezone": "={{ $('Parse Calendly Event').item.json.timezone }}",
            "Date Logged": "={{ $('Parse Calendly Event').item.json.processedAt }}",
            "Meeting URL": "={{ $('Parse Calendly Event').item.json.meetingUrl }}",
            "Meeting Type": "={{ $('Parse Calendly Event').item.json.meetingName }}"
          },
          "mappingMode": "defineBelow"
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "Bookings"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_DOCUMENT_ID"
        }
      },
      "typeVersion": 4
    },
    {
      "id": "0cd3d70a-22ee-4e8c-8b1d-32f63e1fbd30",
      "name": "Slack - Rescheduled",
      "type": "n8n-nodes-base.slack",
      "position": [
        -224,
        -256
      ],
      "parameters": {
        "text": ":arrows_counterclockwise: *Meeting Rescheduled*",
        "otherOptions": {
          "includeLinkToWorkflow": false
        }
      },
      "typeVersion": 2
    },
    {
      "id": "6075cd53-0a71-4fee-bb63-968790babc82",
      "name": "Prepare Reschedule Email",
      "type": "n8n-nodes-base.code",
      "position": [
        16,
        -256
      ],
      "parameters": {
        "jsCode": "// CONFIG - Customize these values\nconst CONFIG = {\n  companyName: 'Your Company',\n  primaryColor: '#f59e0b',\n  secondaryColor: '#667eea'\n};\n\nconst data = $('Parse Calendly Event').first().json;\n\nconst emailHtml = `\n<!DOCTYPE html>\n<html>\n<head>\n  <meta charset=\"UTF-8\">\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n</head>\n<body style=\"margin:0;padding:0;font-family:'Segoe UI',Roboto,Arial,sans-serif;background:#f4f7fa;\">\n  <table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"background:#f4f7fa;padding:40px 20px;\">\n    <tr>\n      <td align=\"center\">\n        <table width=\"600\" cellpadding=\"0\" cellspacing=\"0\" style=\"background:#ffffff;border-radius:16px;box-shadow:0 4px 20px rgba(0,0,0,0.08);overflow:hidden;\">\n          \n          <!-- Header -->\n          <tr>\n            <td style=\"background:linear-gradient(135deg, ${CONFIG.primaryColor} 0%, #d97706 100%);padding:40px 30px;text-align:center;\">\n              <h1 style=\"margin:0;color:#ffffff;font-size:28px;font-weight:600;\">Meeting Rescheduled</h1>\n            </td>\n          </tr>\n          \n          <!-- Content -->\n          <tr>\n            <td style=\"padding:40px 30px;\">\n              <h2 style=\"margin:0 0 20px;color:#1a202c;font-size:22px;\">Hi ${data.name},</h2>\n              <p style=\"color:#4a5568;font-size:16px;line-height:1.7;margin:0 0 25px;\">Your meeting with <strong>${CONFIG.companyName}</strong> has been rescheduled.</p>\n              \n              <!-- New Meeting Details -->\n              <div style=\"background:#fffbeb;border-radius:12px;padding:25px;margin:25px 0;border-left:4px solid ${CONFIG.primaryColor};\">\n                <p style=\"color:#92400e;font-size:14px;font-weight:600;margin:0 0 15px;\">NEW DATE AND TIME:</p>\n                <table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\">\n                  <tr>\n                    <td style=\"padding:8px 0;\">\n                      <span style=\"color:#92400e;font-size:18px;font-weight:600;\">${data.formattedDate}</span>\n                    </td>\n                  </tr>\n                  <tr>\n                    <td style=\"padding:8px 0;\">\n                      <span style=\"color:#92400e;font-size:18px;font-weight:600;\">${data.formattedTime}</span>\n                    </td>\n                  </tr>\n                  <tr>\n                    <td style=\"padding:8px 0;\">\n                      <span style=\"color:#92400e;font-size:16px;\">${data.meetingName}</span>\n                    </td>\n                  </tr>\n                </table>\n              </div>\n              \n              <!-- Join Button -->\n              ${data.meetingUrl ? `\n              <div style=\"text-align:center;margin:30px 0;\">\n                <a href=\"${data.meetingUrl}\" style=\"display:inline-block;background:linear-gradient(135deg, ${CONFIG.secondaryColor} 0%, #5a67d8 100%);color:#ffffff;text-decoration:none;padding:16px 45px;border-radius:10px;font-size:16px;font-weight:600;box-shadow:0 4px 15px rgba(102,126,234,0.4);\">\n                  Join Meeting\n                </a>\n              </div>\n              ` : ''}\n              \n              <!-- Action Links -->\n              <div style=\"background:#f7fafc;border-radius:10px;padding:20px;margin:25px 0;text-align:center;\">\n                <p style=\"color:#718096;font-size:14px;margin:0 0 15px;\">Need to make more changes?</p>\n                <table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\">\n                  <tr>\n                    ${data.rescheduleUrl ? `<td style=\"text-align:center;\"><a href=\"${data.rescheduleUrl}\" style=\"color:${CONFIG.secondaryColor};font-size:14px;text-decoration:none;font-weight:500;\">Reschedule</a></td>` : ''}\n                    ${data.cancelUrl ? `<td style=\"text-align:center;\"><a href=\"${data.cancelUrl}\" style=\"color:#e53e3e;font-size:14px;text-decoration:none;font-weight:500;\">Cancel</a></td>` : ''}\n                  </tr>\n                </table>\n              </div>\n            </td>\n          </tr>\n          \n          <!-- Footer -->\n          <tr>\n            <td style=\"background:#f7fafc;padding:25px 30px;text-align:center;border-top:1px solid #e2e8f0;\">\n              <p style=\"margin:0;color:#a0aec0;font-size:12px;\">${new Date().getFullYear()} ${CONFIG.companyName}. All rights reserved.</p>\n            </td>\n          </tr>\n          \n        </table>\n      </td>\n    </tr>\n  </table>\n</body>\n</html>\n`;\n\nreturn {\n  json: {\n    to: data.email,\n    subject: `Meeting Rescheduled - ${data.formattedDate} at ${data.formattedTime}`,\n    htmlContent: emailHtml\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "0a0f4d36-ca44-4d37-ad4b-d36dc5698ee0",
      "name": "Send Reschedule Email",
      "type": "n8n-nodes-base.gmail",
      "position": [
        256,
        -256
      ],
      "parameters": {
        "sendTo": "={{ $json.to }}",
        "message": "={{ $json.htmlContent }}",
        "options": {
          "appendAttribution": false
        },
        "subject": "={{ $json.subject }}"
      },
      "typeVersion": 2
    },
    {
      "id": "56506437-97ed-43e2-a09c-e050f631e0f9",
      "name": "Done - Confirmation",
      "type": "n8n-nodes-base.noOp",
      "position": [
        736,
        -1008
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "d27edce0-051a-42ca-9d56-57b2e305916d",
      "name": "Done - Cancellation",
      "type": "n8n-nodes-base.noOp",
      "position": [
        512,
        -624
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "44225c03-1919-4767-91cb-fc69c13d72ba",
      "name": "Done - Reschedule",
      "type": "n8n-nodes-base.noOp",
      "position": [
        496,
        -256
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "155707a6-2b04-4e54-92de-8a59256d7628",
      "name": "Webhook",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1312,
        -976
      ],
      "parameters": {
        "color": 5,
        "width": 720,
        "height": 312,
        "content": "## Webhook & routing\n\nReceives Calendly events and routes by type."
      },
      "typeVersion": 1
    },
    {
      "id": "120c5a36-68ce-4bf7-8db5-173492c2fc28",
      "name": "New Booking",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -496,
        -1120
      ],
      "parameters": {
        "color": 3,
        "width": 1480,
        "height": 296,
        "content": "## New booking\n\nLogs, syncs calendar, notifies Slack, sends confirmation."
      },
      "typeVersion": 1
    },
    {
      "id": "2d5fc67f-1ac9-4889-9605-a51b1f313551",
      "name": "Cancellation",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -496,
        -752
      ],
      "parameters": {
        "color": 4,
        "width": 1480,
        "height": 280,
        "content": "## Cancellation\n\nLogs cancellation, alerts team, notifies attendee."
      },
      "typeVersion": 1
    },
    {
      "id": "8380eac3-ef05-4760-998e-e63c23ddd2f0",
      "name": "Reschedule",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -480,
        -384
      ],
      "parameters": {
        "color": 6,
        "width": 1464,
        "height": 296,
        "content": "## Reschedule\n\nLogs changes, alerts team, sends updated details."
      },
      "typeVersion": 1
    },
    {
      "id": "db823055-c7c8-4920-8acb-22ca06a1b781",
      "name": "Format Error1",
      "type": "n8n-nodes-base.code",
      "position": [
        -1280,
        -240
      ],
      "parameters": {
        "jsCode": "// Capture error information\nconst error = $input.item.json;\n\nreturn {\n  json: {\n    errorTime: new Date().toISOString(),\n    errorMessage: error.message || 'Unknown error',\n    errorNode: error.node?.name || 'Unknown',\n    workflowName: 'Calendly Booking Automation',\n    severity: 'HIGH'\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "4de6021c-e37e-4de2-80df-0549518e2840",
      "name": "Slack - Error Alert1",
      "type": "n8n-nodes-base.slack",
      "position": [
        -960,
        -240
      ],
      "parameters": {
        "text": ":rotating_light: *Workflow Error*",
        "otherOptions": {
          "includeLinkToWorkflow": true
        }
      },
      "typeVersion": 2
    },
    {
      "id": "2473c798-26a5-4e26-9728-2ef01143b431",
      "name": "Overview1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1792,
        -1120
      ],
      "parameters": {
        "color": 2,
        "width": 420,
        "height": 560,
        "content": "## Automate Calendly bookings with Gmail, Google Calendar, Sheets and Slack\n\nSyncs Calendly events to your calendar, logs to Sheets, sends confirmations, and alerts your team.\n\n### How it works\n\n1. **Receive** - Webhook captures Calendly events instantly\n2. **Route** - Detects event type: new booking, cancellation, or reschedule\n3. **Log** - Records all events to Google Sheets\n4. **Sync** - Creates/updates Google Calendar events\n5. **Notify** - Sends Slack alerts to your team\n6. **Confirm** - Emails attendees with booking details\n\n### Setup steps\n\n1. **Calendly:** Create webhook pointing to this workflow URL\n2. **Connect:** Gmail, Google Calendar, Sheets, Slack\n3. **Create Sheet:** Tab named \"Bookings\"\n4. **Update IDs:** Replace YOUR_DOCUMENT_ID\n5. **Slack:** Configure #bookings and #errors channels\n6. **Test:** Create a test booking in Calendly"
      },
      "typeVersion": 1
    },
    {
      "id": "f29d5156-ba0d-4f4e-b942-6cfe95e37e6e",
      "name": "Errors1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1312,
        -352
      ],
      "parameters": {
        "color": 7,
        "width": 720,
        "height": 232,
        "content": "## Error handling\n\nCatches errors and alerts #errors channel."
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "Event Router": {
      "main": [
        [
          {
            "node": "Log to Google Sheets",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Log Cancellation",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Log Reschedule",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Error1": {
      "main": [
        [
          {
            "node": "Slack - Error Alert1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Log Reschedule": {
      "main": [
        [
          {
            "node": "Slack - Rescheduled",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Calendly Webhook": {
      "main": [
        [
          {
            "node": "Parse Calendly Event",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Log Cancellation": {
      "main": [
        [
          {
            "node": "Slack - Cancellation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Slack - New Booking": {
      "main": [
        [
          {
            "node": "Prepare Confirmation Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Slack - Rescheduled": {
      "main": [
        [
          {
            "node": "Prepare Reschedule Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Log to Google Sheets": {
      "main": [
        [
          {
            "node": "Create Calendar Event",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Calendly Event": {
      "main": [
        [
          {
            "node": "Event Router",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Slack - Cancellation": {
      "main": [
        [
          {
            "node": "Prepare Cancellation Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create Calendar Event": {
      "main": [
        [
          {
            "node": "Slack - New Booking",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Reschedule Email": {
      "main": [
        [
          {
            "node": "Done - Reschedule",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Cancellation Email": {
      "main": [
        [
          {
            "node": "Done - Cancellation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Confirmation Email": {
      "main": [
        [
          {
            "node": "Done - Confirmation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Reschedule Email": {
      "main": [
        [
          {
            "node": "Send Reschedule Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Cancellation Email": {
      "main": [
        [
          {
            "node": "Send Cancellation Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Confirmation Email": {
      "main": [
        [
          {
            "node": "Send Confirmation Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}