{
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "0cc24318-7afd-4185-82d0-8ad18aee3d27",
      "name": "New Event Trigger",
      "type": "n8n-nodes-base.googleCalendarTrigger",
      "position": [
        -2608,
        -608
      ],
      "parameters": {
        "options": {},
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        },
        "triggerOn": "eventCreated",
        "calendarId": {
          "__rl": true,
          "mode": "list",
          "value": "primary"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "2e7415e5-98bf-48c9-b221-b88bcd420653",
      "name": "Updated Event Trigger",
      "type": "n8n-nodes-base.googleCalendarTrigger",
      "position": [
        -2608,
        -400
      ],
      "parameters": {
        "options": {},
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        },
        "triggerOn": "eventUpdated",
        "calendarId": {
          "__rl": true,
          "mode": "list",
          "value": "primary"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "a55feb7c-f8ce-4e25-aa7c-6e83acc73081",
      "name": "Daily Summary Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -2608,
        96
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "0 8 * * *"
            }
          ]
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "f4b8ba3b-55eb-4145-80b0-c83871d61d5b",
      "name": "Process Event",
      "type": "n8n-nodes-base.code",
      "position": [
        -2304,
        -496
      ],
      "parameters": {
        "jsCode": "const event = $json;\n\n// Basic data\nconst eventId = event.id || '';\nconst summary = event.summary || 'Untitled';\nconst description = event.description || '';\nconst status = event.status || 'confirmed';\nconst creator = event.creator?.email || '';\nconst organizer = event.organizer?.email || '';\n\n// Attendees\nconst attendees = event.attendees || [];\nconst attendeeCount = attendees.length;\nconst attendeeEmails = attendees.map(a => a.email).join(', ');\nconst acceptedCount = attendees.filter(a => a.responseStatus === 'accepted').length;\nconst declinedCount = attendees.filter(a => a.responseStatus === 'declined').length;\nconst pendingCount = attendees.filter(a => a.responseStatus === 'needsAction' || a.responseStatus === 'tentative').length;\n\n// Dates\nconst startDateTime = event.start?.dateTime || event.start?.date;\nconst endDateTime = event.end?.dateTime || event.end?.date;\nconst isAllDay = !event.start?.dateTime;\n\n// Format dates\nlet formattedDate = '';\nlet startTime = '';\nlet endTime = '';\nlet dayOfWeek = '';\n\nif (startDateTime) {\n  const startDate = new Date(startDateTime);\n  formattedDate = startDate.toLocaleDateString('en-US', {\n    year: 'numeric',\n    month: '2-digit',\n    day: '2-digit'\n  });\n  dayOfWeek = startDate.toLocaleDateString('en-US', { weekday: 'long' });\n  startTime = isAllDay ? 'All day' : startDate.toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' });\n  if (endDateTime && !isAllDay) {\n    endTime = new Date(endDateTime).toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' });\n  }\n}\n\n// Calculate duration in minutes\nlet durationMinutes = 60;\nlet durationText = '1 hour';\nif (startDateTime && endDateTime && !isAllDay) {\n  const start = new Date(startDateTime);\n  const end = new Date(endDateTime);\n  durationMinutes = Math.round((end - start) / (1000 * 60));\n  if (durationMinutes < 60) {\n    durationText = `${durationMinutes} min`;\n  } else if (durationMinutes === 60) {\n    durationText = '1 hour';\n  } else {\n    const hours = Math.floor(durationMinutes / 60);\n    const mins = durationMinutes % 60;\n    durationText = mins > 0 ? `${hours}h ${mins}m` : `${hours} hours`;\n  }\n}\n\n// Detect video call platform\nlet platform = 'In-person';\nlet meetingLink = '';\nlet location = event.location || '';\n\nif (event.hangoutLink) {\n  platform = 'Google Meet';\n  meetingLink = event.hangoutLink;\n} else if (event.conferenceData?.entryPoints) {\n  const videoEntry = event.conferenceData.entryPoints.find(e => e.entryPointType === 'video');\n  if (videoEntry) {\n    meetingLink = videoEntry.uri;\n    if (meetingLink.includes('zoom.us')) platform = 'Zoom';\n    else if (meetingLink.includes('teams.microsoft')) platform = 'Teams';\n    else platform = 'Google Meet';\n  }\n} else if (location) {\n  if (location.includes('zoom.us')) {\n    platform = 'Zoom';\n    meetingLink = location;\n  } else if (location.includes('teams.microsoft')) {\n    platform = 'Teams';\n    meetingLink = location;\n  } else if (location.includes('meet.google')) {\n    platform = 'Google Meet';\n    meetingLink = location;\n  }\n}\n\n// Categorize event type\nlet category = 'General';\nconst titleLower = summary.toLowerCase();\nif (titleLower.includes('meeting') || titleLower.includes('call') || titleLower.includes('sync')) {\n  category = 'Meeting';\n} else if (titleLower.includes('1:1') || titleLower.includes('one on one') || titleLower.includes('1-on-1')) {\n  category = '1:1';\n} else if (titleLower.includes('interview')) {\n  category = 'Interview';\n} else if (titleLower.includes('lunch') || titleLower.includes('coffee') || titleLower.includes('social')) {\n  category = 'Social';\n} else if (titleLower.includes('demo') || titleLower.includes('presentation')) {\n  category = 'Demo';\n} else if (titleLower.includes('focus') || titleLower.includes('deep work') || titleLower.includes('blocked')) {\n  category = 'Focus Time';\n}\n\n// Event status\nconst isCancelled = status === 'cancelled';\nlet statusText = 'Confirmed';\nif (isCancelled) statusText = 'Canceled';\nelse if (status === 'tentative') statusText = 'Tentative';\n\n// Detect if recurring\nconst isRecurring = !!event.recurringEventId;\n\nreturn {\n  json: {\n    // IDs\n    eventId: eventId,\n    recurringEventId: event.recurringEventId || '',\n    \n    // Basic info\n    title: summary,\n    description: description,\n    category: category,\n    \n    // Dates and time\n    date: formattedDate,\n    dayOfWeek: dayOfWeek,\n    startTime: startTime,\n    endTime: endTime,\n    durationMinutes: durationMinutes,\n    durationText: durationText,\n    allDay: isAllDay ? 'Yes' : 'No',\n    isRecurring: isRecurring ? 'Yes' : 'No',\n    \n    // Location\n    platform: platform,\n    meetingLink: meetingLink,\n    location: location,\n    \n    // Attendees\n    organizer: organizer,\n    creator: creator,\n    attendeeCount: attendeeCount,\n    attendees: attendeeEmails,\n    accepted: acceptedCount,\n    declined: declinedCount,\n    pending: pendingCount,\n    \n    // Status\n    status: statusText,\n    cancelled: isCancelled,\n    \n    // Metadata\n    syncedAt: new Date().toISOString(),\n    syncedAtFormatted: new Date().toLocaleString('en-US')\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "198eb6e3-6947-4d93-94c8-d331866066f2",
      "name": "Is Canceled?",
      "type": "n8n-nodes-base.if",
      "position": [
        -2064,
        -496
      ],
      "parameters": {
        "conditions": {
          "boolean": [
            {
              "value1": "={{ $json.cancelled }}",
              "value2": true
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "ca7dc61a-f224-4302-988e-a8b0d5bce949",
      "name": "Log Event",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -1760,
        -608
      ],
      "parameters": {
        "columns": {
          "value": {
            "ID": "={{ $json.eventId }}",
            "Day": "={{ $json.dayOfWeek }}",
            "Date": "={{ $json.date }}",
            "Title": "={{ $json.title }}",
            "Status": "={{ $json.status }}",
            "Category": "={{ $json.category }}",
            "Duration": "={{ $json.durationText }}",
            "End Time": "={{ $json.endTime }}",
            "Platform": "={{ $json.platform }}",
            "Attendees": "={{ $json.attendeeCount }}",
            "Synced At": "={{ $json.syncedAtFormatted }}",
            "Start Time": "={{ $json.startTime }}",
            "Meeting Link": "={{ $json.meetingLink }}"
          },
          "mappingMode": "defineBelow"
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "Events"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_DOCUMENT_ID"
        }
      },
      "typeVersion": 4
    },
    {
      "id": "392f3ba6-9c24-437e-9b20-2cf184318c7d",
      "name": "Log Cancellation",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -1760,
        -400
      ],
      "parameters": {
        "columns": {
          "value": {
            "ID": "={{ $json.eventId }}",
            "Title": "={{ $json.title }}",
            "Canceled At": "={{ $json.syncedAtFormatted }}",
            "Original Date": "={{ $json.date }}",
            "Original Time": "={{ $json.startTime }}",
            "Affected Attendees": "={{ $json.attendeeCount }}"
          },
          "mappingMode": "defineBelow"
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "Cancellations"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_DOCUMENT_ID"
        }
      },
      "typeVersion": 4
    },
    {
      "id": "3a608d14-fb51-4ec6-abdf-4e76fe80fc66",
      "name": "Slack - New Event",
      "type": "n8n-nodes-base.slack",
      "position": [
        -1520,
        -608
      ],
      "parameters": {
        "text": ":calendar: *New calendar event*",
        "otherOptions": {
          "includeLinkToWorkflow": false
        }
      },
      "typeVersion": 2
    },
    {
      "id": "c3e63763-51b1-4113-9424-16bebbd9da93",
      "name": "Slack - Cancellation",
      "type": "n8n-nodes-base.slack",
      "position": [
        -1520,
        -400
      ],
      "parameters": {
        "text": ":x: *Event canceled*",
        "otherOptions": {
          "includeLinkToWorkflow": false
        }
      },
      "typeVersion": 2
    },
    {
      "id": "0718fe64-ce83-4344-a2b7-e7d618825590",
      "name": "Has Attendees?",
      "type": "n8n-nodes-base.if",
      "position": [
        -1264,
        -608
      ],
      "parameters": {
        "conditions": {
          "number": [
            {
              "value1": "={{ $('Process Event').item.json.attendeeCount }}",
              "operation": "larger"
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "e5009348-bc88-4675-90e4-a37a916f8052",
      "name": "Prepare Confirmation Email",
      "type": "n8n-nodes-base.code",
      "position": [
        -960,
        -624
      ],
      "parameters": {
        "jsCode": "const data = $('Process Event').first().json;\n\n// Config\nconst CONFIG = {\n  companyName: 'Your Company',\n  primaryColor: '#4f46e5'\n};\n\nconst emailHtml = `\n<!DOCTYPE html>\n<html>\n<head><meta charset=\"UTF-8\"></head>\n<body style=\"margin:0;padding:0;font-family:'Segoe UI',Arial,sans-serif;background:#f4f7fa;\">\n  <table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"background:#f4f7fa;padding:40px 20px;\">\n    <tr><td align=\"center\">\n      <table width=\"600\" cellpadding=\"0\" cellspacing=\"0\" style=\"background:#fff;border-radius:12px;box-shadow:0 4px 6px rgba(0,0,0,0.1);\">\n        <tr><td style=\"background:${CONFIG.primaryColor};padding:30px;text-align:center;border-radius:12px 12px 0 0;\">\n          <h1 style=\"margin:0;color:#fff;font-size:24px;\">Event Scheduled</h1>\n        </td></tr>\n        <tr><td style=\"padding:30px;\">\n          <h2 style=\"margin:0 0 20px;color:#2d3748;\">${data.title}</h2>\n          \n          <div style=\"background:#f0f4ff;border-radius:8px;padding:20px;margin:20px 0;border-left:4px solid ${CONFIG.primaryColor};\">\n            <p style=\"margin:0 0 10px;color:#4338ca;font-size:16px;\">${data.dayOfWeek} ${data.date}</p>\n            <p style=\"margin:0 0 10px;color:#4338ca;font-size:16px;\">${data.startTime} - ${data.endTime} (${data.durationText})</p>\n            <p style=\"margin:0;color:#4338ca;font-size:16px;\">${data.platform}</p>\n          </div>\n          \n          ${data.meetingLink ? `<div style=\"text-align:center;margin:25px 0;\"><a href=\"${data.meetingLink}\" style=\"display:inline-block;background:${CONFIG.primaryColor};color:#fff;text-decoration:none;padding:15px 40px;border-radius:8px;font-size:16px;font-weight:600;\">Join Meeting</a></div>` : ''}\n          \n          ${data.description ? `<div style=\"border-top:1px solid #e2e8f0;padding-top:20px;margin-top:20px;\"><p style=\"color:#718096;font-size:14px;line-height:1.6;margin:0;\"><strong>Description:</strong><br>${data.description}</p></div>` : ''}\n        </td></tr>\n        <tr><td style=\"background:#f7fafc;padding:20px;text-align:center;border-top:1px solid #e2e8f0;border-radius:0 0 12px 12px;\">\n          <p style=\"margin:0;color:#718096;font-size:12px;\">${new Date().getFullYear()} ${CONFIG.companyName}</p>\n        </td></tr>\n      </table>\n    </td></tr>\n  </table>\n</body>\n</html>\n`;\n\nreturn {\n  json: {\n    to: data.attendees,\n    subject: `Event: ${data.title} - ${data.date} ${data.startTime}`,\n    htmlContent: emailHtml\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "7c7bc8dd-205f-470c-89cd-24978427af49",
      "name": "Send Email",
      "type": "n8n-nodes-base.gmail",
      "position": [
        -720,
        -624
      ],
      "parameters": {
        "sendTo": "={{ $json.to }}",
        "message": "={{ $json.htmlContent }}",
        "options": {
          "appendAttribution": false
        },
        "subject": "={{ $json.subject }}"
      },
      "typeVersion": 2
    },
    {
      "id": "d1b987ce-4146-4193-a9ab-c441b1b3419d",
      "name": "Get Today Events",
      "type": "n8n-nodes-base.googleCalendar",
      "position": [
        -2320,
        96
      ],
      "parameters": {
        "options": {
          "timeMax": "={{ $now.endOf('day').toISO() }}",
          "timeMin": "={{ $now.startOf('day').toISO() }}"
        },
        "calendar": {
          "__rl": true,
          "mode": "list",
          "value": "primary"
        },
        "operation": "getAll"
      },
      "typeVersion": 1.2
    },
    {
      "id": "cef60c0c-d3ca-4729-8c19-0089f03f06ad",
      "name": "Calculate Statistics",
      "type": "n8n-nodes-base.code",
      "position": [
        -2080,
        96
      ],
      "parameters": {
        "jsCode": "const events = $input.all();\nconst today = new Date().toLocaleDateString('en-US', {\n  weekday: 'long',\n  year: 'numeric',\n  month: 'long',\n  day: 'numeric'\n});\n\n// Filter non-canceled events\nconst activeEvents = events.filter(e => e.json.status !== 'cancelled');\n\n// Calculate total meeting time\nlet totalMinutes = 0;\nlet virtualMeetings = 0;\nlet inPersonMeetings = 0;\n\nconst eventList = activeEvents.map(e => {\n  const event = e.json;\n  const start = new Date(event.start?.dateTime || event.start?.date);\n  const end = new Date(event.end?.dateTime || event.end?.date);\n  const duration = Math.round((end - start) / (1000 * 60));\n  \n  if (!event.start?.date) { // Don't count all-day events\n    totalMinutes += duration;\n  }\n  \n  const hasVideoCall = event.hangoutLink || event.conferenceData?.entryPoints?.length > 0;\n  if (hasVideoCall) virtualMeetings++;\n  else inPersonMeetings++;\n  \n  const time = event.start?.dateTime \n    ? new Date(event.start.dateTime).toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' })\n    : 'All day';\n  \n  return `- ${time} - ${event.summary || 'Untitled'}`;\n}).join('\\n');\n\n// Format total time\nconst hours = Math.floor(totalMinutes / 60);\nconst minutes = totalMinutes % 60;\nconst formattedTime = hours > 0 \n  ? `${hours}h ${minutes}m` \n  : `${minutes} minutes`;\n\n// Calculate % of day in meetings (8 work hours = 480 min)\nconst busyPercent = Math.round((totalMinutes / 480) * 100);\n\nlet dayStatus = 'Light day';\nif (busyPercent > 75) dayStatus = 'Very busy day';\nelse if (busyPercent > 50) dayStatus = 'Busy day';\nelse if (busyPercent > 25) dayStatus = 'Moderate day';\n\nreturn {\n  json: {\n    date: today,\n    totalEvents: activeEvents.length,\n    meetingTime: formattedTime,\n    totalMinutes: totalMinutes,\n    busyPercent: `${busyPercent}%`,\n    dayStatus: dayStatus,\n    virtualMeetings: virtualMeetings,\n    inPersonMeetings: inPersonMeetings,\n    eventList: eventList || 'No events scheduled',\n    generatedAt: new Date().toLocaleTimeString('en-US')\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "6c631cca-a4de-412d-9bd5-c8b2e111a82f",
      "name": "Slack - Daily Summary",
      "type": "n8n-nodes-base.slack",
      "position": [
        -1808,
        96
      ],
      "parameters": {
        "text": ":chart_with_upwards_trend: *Daily Summary*",
        "otherOptions": {
          "includeLinkToWorkflow": false
        }
      },
      "typeVersion": 2
    },
    {
      "id": "1c5e480f-0076-4007-bd82-96ee29af4b81",
      "name": "Log Statistics",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -1568,
        96
      ],
      "parameters": {
        "columns": {
          "value": {
            "Date": "={{ $json.date }}",
            "Busy %": "={{ $json.busyPercent }}",
            "Status": "={{ $json.dayStatus }}",
            "Minutes": "={{ $json.totalMinutes }}",
            "Virtual": "={{ $json.virtualMeetings }}",
            "In-Person": "={{ $json.inPersonMeetings }}",
            "Meeting Time": "={{ $json.meetingTime }}",
            "Total Events": "={{ $json.totalEvents }}"
          },
          "mappingMode": "defineBelow"
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "Statistics"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_DOCUMENT_ID"
        }
      },
      "typeVersion": 4
    },
    {
      "id": "dcaf1c9c-34a3-4f8f-a561-5fab20a2fe0a",
      "name": "Error Trigger",
      "type": "n8n-nodes-base.errorTrigger",
      "position": [
        -2624,
        448
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "78e60ff2-7e8c-429d-b6eb-745e3e26475f",
      "name": "Format Error",
      "type": "n8n-nodes-base.code",
      "position": [
        -2336,
        448
      ],
      "parameters": {
        "jsCode": "const error = $input.item.json;\nreturn {\n  json: {\n    errorTime: new Date().toISOString(),\n    errorMessage: error.message || 'Unknown error',\n    errorNode: error.node?.name || 'Unknown',\n    workflow: 'Google Calendar Sync'\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "5a965d16-af8a-4157-969e-ccec56c5238b",
      "name": "Slack - Error Alert",
      "type": "n8n-nodes-base.slack",
      "position": [
        -2096,
        448
      ],
      "parameters": {
        "text": ":rotating_light: *Workflow Error*",
        "otherOptions": {
          "includeLinkToWorkflow": true
        }
      },
      "typeVersion": 2
    },
    {
      "id": "bf7ba5a8-8aab-469f-8586-631894568ace",
      "name": "Done - Event",
      "type": "n8n-nodes-base.noOp",
      "position": [
        -960,
        -416
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "422125df-5c53-4b3d-83e1-d86f28937e9b",
      "name": "Done - Cancellation",
      "type": "n8n-nodes-base.noOp",
      "position": [
        -1264,
        -400
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "345927ff-e680-4c43-a47c-23217bf9bf93",
      "name": "Done - Summary",
      "type": "n8n-nodes-base.noOp",
      "position": [
        -1312,
        96
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "e604476b-4bfd-442c-be19-f91f79eaab5f",
      "name": "Overview",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -3200,
        -816
      ],
      "parameters": {
        "color": 2,
        "width": 440,
        "height": 664,
        "content": "## Sync Google Calendar events to Sheets with Slack notifications\n\nAutomatically track all calendar events, log them to Google Sheets, and send Slack notifications.\n\n### How it works\n\n1. **Monitor** - Watches calendar for new and updated events\n2. **Process** - Extracts title, date, time, attendees, platform\n3. **Categorize** - Auto-tags: Meeting, 1:1, Interview, Demo, Focus\n4. **Log** - Saves all events to Google Sheets\n5. **Alert** - Slack notifications for changes and cancellations\n6. **Report** - Daily 8 AM summary with stats\n\n### Setup steps\n\n1. Connect Google Calendar, Google Sheets, Slack, Gmail\n2. Create Sheet with tab named \"Events\"\n3. Replace YOUR_DOCUMENT_ID in Sheets nodes\n4. Configure Slack channels: #calendar and #errors\n5. Test by creating a calendar event"
      },
      "typeVersion": 1
    },
    {
      "id": "3f3e0e22-b5f1-43c5-a860-a0f2b696d4a8",
      "name": "Step 1 Calendar Triggers",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2624,
        -816
      ],
      "parameters": {
        "color": 5,
        "width": 280,
        "height": 650,
        "content": "## Step 1: Calendar Triggers\n\n**What happens here:**\n- New event trigger\n- Updated event trigger\n- Monitors your calendar"
      },
      "typeVersion": 1
    },
    {
      "id": "bb40d8be-7657-4750-82a8-97f2762fe561",
      "name": "Step 2 Event Processing",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2320,
        -816
      ],
      "parameters": {
        "color": 7,
        "width": 520,
        "height": 650,
        "content": "## Step 2: Event Processing\n\n**What happens here:**\n- Extract event details\n- Check if cancelled\n- Route accordingly"
      },
      "typeVersion": 1
    },
    {
      "id": "f5edd03e-cd96-4779-a57a-9c54bf581722",
      "name": "Step 3 Logging",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1776,
        -816
      ],
      "parameters": {
        "color": 6,
        "width": 696,
        "height": 650,
        "content": "## Step 3: Logging & Alerts\n\n**What happens here:**\n- Log to Sheets\n- Slack notifications\n- Track changes"
      },
      "typeVersion": 1
    },
    {
      "id": "a931e3ec-4411-4e27-914d-fdcb229585dc",
      "name": "Step 4 Email",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1024,
        -816
      ],
      "parameters": {
        "color": 5,
        "width": 520,
        "height": 650,
        "content": "## Step 4: Confirmation Email\n\n**What happens here:**\n- Prepare email\n- Send to attendees\n- Confirmation flow"
      },
      "typeVersion": 1
    },
    {
      "id": "87d6cbad-0be6-4ea5-a94f-9c7e8adfcef9",
      "name": "Step 5 Daily Summary",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2656,
        -96
      ],
      "parameters": {
        "color": 7,
        "width": 1540,
        "height": 352,
        "content": "## Step 5: Daily Summary\n\n**What happens here:**\n- 8 AM trigger\n- Calculate statistics\n- Slack report"
      },
      "typeVersion": 1
    },
    {
      "id": "b9f3c06d-220f-44ea-8200-fcd231b4a142",
      "name": "Step 6 Error Handling",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2656,
        288
      ],
      "parameters": {
        "color": 6,
        "width": 1552,
        "height": 320,
        "content": "## Step 6: Error Handling\n\n**What happens here:**\n- Catch errors\n- Format details\n- Alert #errors"
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "Log Event": {
      "main": [
        [
          {
            "node": "Slack - New Event",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Email": {
      "main": [
        [
          {
            "node": "Done - Event",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Error": {
      "main": [
        [
          {
            "node": "Slack - Error Alert",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Is Canceled?": {
      "main": [
        [
          {
            "node": "Log Cancellation",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Log Event",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Error Trigger": {
      "main": [
        [
          {
            "node": "Format Error",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Process Event": {
      "main": [
        [
          {
            "node": "Is Canceled?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Has Attendees?": {
      "main": [
        [
          {
            "node": "Prepare Confirmation Email",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Done - Event",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Log Statistics": {
      "main": [
        [
          {
            "node": "Done - Summary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Today Events": {
      "main": [
        [
          {
            "node": "Calculate Statistics",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Log Cancellation": {
      "main": [
        [
          {
            "node": "Slack - Cancellation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "New Event Trigger": {
      "main": [
        [
          {
            "node": "Process Event",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Slack - New Event": {
      "main": [
        [
          {
            "node": "Has Attendees?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Calculate Statistics": {
      "main": [
        [
          {
            "node": "Slack - Daily Summary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Slack - Cancellation": {
      "main": [
        [
          {
            "node": "Done - Cancellation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Daily Summary Trigger": {
      "main": [
        [
          {
            "node": "Get Today Events",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Slack - Daily Summary": {
      "main": [
        [
          {
            "node": "Log Statistics",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Updated Event Trigger": {
      "main": [
        [
          {
            "node": "Process Event",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Confirmation Email": {
      "main": [
        [
          {
            "node": "Send Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}