{
  "id": "8sVx88tgELHkbDsh",
  "meta": {
    "builderVariant": "mcp",
    "aiBuilderAssisted": true,
    "templateCredsSetupCompleted": true
  },
  "name": "Waitlist Auto-Fill on Cancellation",
  "tags": [],
  "nodes": [
    {
      "id": "4967a398-9572-43c9-b2ed-8d568bd6e13d",
      "name": "Appointment Cancelled Trigger",
      "type": "n8n-nodes-base.googleSheetsTrigger",
      "maxTries": 3,
      "position": [
        144,
        -128
      ],
      "parameters": {
        "event": "rowUpdate",
        "options": {},
        "pollTimes": {
          "item": [
            {
              "mode": "everyX",
              "unit": "minutes",
              "value": 5
            }
          ]
        },
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": ""
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": ""
        }
      },
      "credentials": {
        "googleSheetsTriggerOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "retryOnFail": true,
      "typeVersion": 1,
      "waitBetweenTries": 1000
    },
    {
      "id": "acde8b74-882a-4b69-bf42-def4c9314a7d",
      "name": "Mark Waitlist Processing Started",
      "type": "n8n-nodes-base.googleSheets",
      "maxTries": 3,
      "position": [
        704,
        -128
      ],
      "parameters": {
        "columns": {
          "value": {
            "AppointmentID": "={{ $json.AppointmentID }}",
            "WaitlistProcessed": "Yes"
          },
          "schema": [
            {
              "id": "AppointmentID",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "AppointmentID",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "PatientName",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "PatientName",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Phone",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Phone",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "ServiceType",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "ServiceType",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Provider",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Provider",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Date",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Time",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Time",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Status",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "WaitlistProcessed",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "WaitlistProcessed",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "row_number",
              "type": "number",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "row_number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "AppointmentID"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "update",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": ""
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": ""
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "retryOnFail": true,
      "typeVersion": 4.7,
      "waitBetweenTries": 1000
    },
    {
      "id": "d92a216f-ff43-453a-b16e-3233e140b9e3",
      "name": "Get Waiting Candidates",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        912,
        -128
      ],
      "parameters": {
        "options": {},
        "filtersUI": {
          "values": [
            {
              "lookupValue": "Waiting",
              "lookupColumn": "Status"
            },
            {
              "lookupValue": "={{ $('Appointment Cancelled Trigger').item.json.ServiceType }}",
              "lookupColumn": "ServiceType"
            }
          ]
        },
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": ""
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": ""
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "retryOnFail": true,
      "typeVersion": 4.7
    },
    {
      "id": "331e424f-7151-4342-a260-971e723ae30b",
      "name": "Mark Slot Unfilled",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1360,
        112
      ],
      "parameters": {
        "columns": {
          "value": {
            "Status": "Cancelled - Unfilled",
            "AppointmentID": "={{ $('Appointment Cancelled Trigger').item.json.AppointmentID }}"
          },
          "schema": [
            {
              "id": "AppointmentID",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "AppointmentID",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "PatientName",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "PatientName",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Phone",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Phone",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "ServiceType",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "ServiceType",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Provider",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Provider",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Date",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Time",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Time",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Status",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "WaitlistProcessed",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "WaitlistProcessed",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "row_number",
              "type": "number",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "row_number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "AppointmentID"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "update",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": ""
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": ""
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "retryOnFail": true,
      "typeVersion": 4.7
    },
    {
      "id": "cc3a7eee-f952-4841-b5d4-1b5b39861f97",
      "name": "Notify Owner - No Fill",
      "type": "n8n-nodes-base.twilio",
      "position": [
        1616,
        112
      ],
      "parameters": {
        "to": "YOUR_OWNER_PHONE_NUMBER",
        "from": "YOUR_TWILIO_FROM_NUMBER",
        "message": "=No one on the waitlist confirmed the open {{ $('Appointment Cancelled Trigger').item.json.ServiceType }} slot on {{ $('Format Date & Time').item.json.Date }}. It's still open.",
        "options": {}
      },
      "credentials": {
        "twilioApi": {
          "name": "<your credential>"
        }
      },
      "retryOnFail": true,
      "typeVersion": 1
    },
    {
      "id": "38ec2ca4-e9b1-4dd5-897e-a26e52d97e2f",
      "name": "Mark Candidate Offered",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1360,
        -256
      ],
      "parameters": {
        "columns": {
          "value": {
            "Status": "Offered",
            "WaitlistID": "={{ $json.WaitlistID }}"
          },
          "schema": [
            {
              "id": "WaitlistID",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "WaitlistID",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Name",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Phone",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Phone",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "ServiceType",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "ServiceType",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "AddedAt",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "AddedAt",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Status",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "row_number",
              "type": "number",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "row_number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "WaitlistID"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "update",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": ""
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": ""
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "retryOnFail": true,
      "typeVersion": 4.7
    },
    {
      "id": "f4253a0d-5231-4149-94aa-9b1e25a3fe22",
      "name": "Send Waitlist Offer",
      "type": "n8n-nodes-base.twilio",
      "position": [
        1552,
        -256
      ],
      "parameters": {
        "to": "={{ $('Loop Over Waitlist Candidates').item.json.Phone }}",
        "from": "YOUR_TWILIO_FROM_NUMBER",
        "message": "=Hi {{ $('Loop Over Waitlist Candidates').item.json.Name }}! A {{ $('Appointment Cancelled Trigger').item.json.ServiceType }} slot opened on {{ $('Format Date & Time').item.json.Date }} at {{ $('Format Date & Time').item.json.Time }}. Tap to confirm within 20 min: {{ $execution.resumeUrl }}",
        "options": {}
      },
      "credentials": {
        "twilioApi": {
          "name": "<your credential>"
        }
      },
      "retryOnFail": true,
      "typeVersion": 1
    },
    {
      "id": "6af9574a-a409-461c-93d2-1a8f23e275ac",
      "name": "Wait For Confirmation",
      "type": "n8n-nodes-base.wait",
      "position": [
        1760,
        -256
      ],
      "parameters": {
        "resume": "webhook",
        "options": {},
        "resumeUnit": "minutes",
        "resumeAmount": 20,
        "limitWaitTime": true
      },
      "retryOnFail": true,
      "typeVersion": 1.1
    },
    {
      "id": "7d97f17b-7958-4a7a-8467-8b65190fed96",
      "name": "Candidate Confirmed?",
      "type": "n8n-nodes-base.if",
      "position": [
        1952,
        -256
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "07e3700b-39e8-44c1-8f3c-34dd32238c82",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.query ? \"confirmed\" : \"timeout\" }}",
              "rightValue": "confirmed"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "ae81862e-2341-49b3-8baf-9deef2e06a7e",
      "name": "Book Appointment in Calendar",
      "type": "n8n-nodes-base.googleCalendar",
      "position": [
        2416,
        -400
      ],
      "parameters": {
        "end": "={{ $('Format Date & Time').item.json.EndDate }}T{{ $('Format Date & Time').item.json.EndTime }}",
        "start": "={{ $('Format Date & Time').item.json.Date }}T{{ $('Format Date & Time').item.json.Time }}",
        "calendar": {
          "__rl": true,
          "mode": "list",
          "value": ""
        },
        "additionalFields": {
          "summary": "={{ $('Appointment Cancelled Trigger').item.json.ServiceType }} - {{ $('Loop Over Waitlist Candidates').item.json.Name }}",
          "description": "=Waitlist auto-fill booking. Phone: {{ $('Loop Over Waitlist Candidates').item.json.Phone }}",
          "sendUpdates": "none"
        }
      },
      "credentials": {
        "googleCalendarOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "retryOnFail": true,
      "typeVersion": 1.3
    },
    {
      "id": "786286f3-06a6-47ef-b181-8b6487768c16",
      "name": "Add Booked Appointment Row",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2592,
        -400
      ],
      "parameters": {
        "columns": {
          "value": {
            "Date": "={{ $('Format Date & Time').item.json.Date }}",
            "Time": "={{ $('Format Date & Time').item.json.Time }}",
            "Phone": "={{ $('Get Waiting Candidates').item.json.Phone }}",
            "Status": "Filled - Waitlist",
            "Provider": "={{ $('Appointment Cancelled Trigger').item.json.Provider }}",
            "PatientName": "={{ $('Get Waiting Candidates').item.json.Name }}",
            "ServiceType": "={{ $('Get Waiting Candidates').item.json.ServiceType }}",
            "AppointmentID": "={{ $('Mark Waitlist Processing Started').item.json.AppointmentID }}-{{ $('Get Waiting Candidates').item.json.WaitlistID }}",
            "WaitlistProcessed": "No"
          },
          "schema": [
            {
              "id": "AppointmentID",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "AppointmentID",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "PatientName",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "PatientName",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Phone",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Phone",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "ServiceType",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "ServiceType",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Provider",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Provider",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Date",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Time",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Time",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Status",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "WaitlistProcessed",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "WaitlistProcessed",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {
          "useAppend": true
        },
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": ""
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": ""
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "retryOnFail": true,
      "typeVersion": 4.7
    },
    {
      "id": "cfb620d9-2d0d-40cb-96d7-7cf69684af33",
      "name": "Update Waitlist - Booked",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2784,
        -400
      ],
      "parameters": {
        "columns": {
          "value": {
            "Status": "Booked",
            "WaitlistID": "={{ $('Get Waiting Candidates').item.json.WaitlistID }}"
          },
          "schema": [
            {
              "id": "WaitlistID",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "WaitlistID",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Name",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Phone",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Phone",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "ServiceType",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "ServiceType",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "AddedAt",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "AddedAt",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Status",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "row_number",
              "type": "number",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "row_number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "WaitlistID"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "update",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": ""
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": ""
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "retryOnFail": true,
      "typeVersion": 4.7
    },
    {
      "id": "f8eaa9e0-ebc6-47c4-ab3a-1a3e88582c49",
      "name": "Send Booking Confirmation",
      "type": "n8n-nodes-base.twilio",
      "position": [
        2960,
        -400
      ],
      "parameters": {
        "to": "={{ $('Loop Over Waitlist Candidates').item.json.Phone }}",
        "from": "YOUR_TWILIO_FROM_NUMBER",
        "message": "=You're confirmed! {{ $('Appointment Cancelled Trigger').item.json.ServiceType }} on {{ $('Format Date & Time').item.json.Date }} at {{ $('Format Date & Time').item.json.Time }}. See you then!",
        "options": {}
      },
      "credentials": {
        "twilioApi": {
          "name": "<your credential>"
        }
      },
      "retryOnFail": true,
      "typeVersion": 1
    },
    {
      "id": "571e9b28-2b2a-4828-9365-30df65cc5312",
      "name": "Mark Candidate Expired",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2160,
        -128
      ],
      "parameters": {
        "columns": {
          "value": {
            "Status": "Expired",
            "WaitlistID": "={{ $('Get Waiting Candidates').item.json.WaitlistID }}"
          },
          "schema": [
            {
              "id": "WaitlistID",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "WaitlistID",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Name",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Phone",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Phone",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "ServiceType",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "ServiceType",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "AddedAt",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "AddedAt",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Status",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "row_number",
              "type": "number",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "row_number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "WaitlistID"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "update",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": ""
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": ""
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "retryOnFail": true,
      "typeVersion": 4.7
    },
    {
      "id": "818a366f-1e97-4f2a-8479-2983184cef3d",
      "name": "Loop Over Waitlist Candidates",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        1120,
        -128
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "ebf82576-5aa3-4f09-a2dd-81450a766d57",
      "name": "Cancelled & Not Yet Offered?",
      "type": "n8n-nodes-base.filter",
      "position": [
        512,
        -128
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "c116d30f-207a-4892-9758-ea4ed35d966e",
              "operator": {
                "name": "filter.operator.equals",
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.Status }}",
              "rightValue": "Cancelled"
            },
            {
              "id": "2e234015-36bd-40a6-9876-023a6b6bc49d",
              "operator": {
                "type": "string",
                "operation": "notEquals"
              },
              "leftValue": "={{ $json.WaitlistProcessed }}",
              "rightValue": "Yes"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "22145734-ffd3-4cba-9eef-b91aed4d9cd4",
      "name": "Format Date & Time",
      "type": "n8n-nodes-base.code",
      "position": [
        336,
        -128
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "const item = $input.item;\nconst serialDate = item.json.Date;\nconst serialTime = item.json.Time;\n\n// Google Sheets stores Date/Time cells as serial numbers (days since 1899-12-30).\nconst epoch = Date.UTC(1899, 11, 30);\nconst startMs = epoch + (serialDate + serialTime) * 86400000;\n\nconst APPOINTMENT_DURATION_MINUTES = 30;\nconst endMs = startMs + APPOINTMENT_DURATION_MINUTES * 60000;\n\nconst startDateObj = new Date(startMs);\nconst endDateObj = new Date(endMs);\n\nitem.json.Date = startDateObj.toISOString().slice(0, 10);\nitem.json.Time = startDateObj.toISOString().slice(11, 16);\nitem.json.EndDate = endDateObj.toISOString().slice(0, 10);\nitem.json.EndTime = endDateObj.toISOString().slice(11, 16);\n\nreturn item;"
      },
      "typeVersion": 2
    },
    {
      "id": "0f01da54-08b5-47e0-ba87-6203552b33f9",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2336,
        -176
      ],
      "parameters": {
        "color": 4,
        "width": 880,
        "height": 720,
        "content": "# \ud83c\udfa5 Video Demo\n\n## See the complete workflow in action:\n\n@[youtube](rAbg-GW0NwU)"
      },
      "typeVersion": 1
    },
    {
      "id": "e9f02100-5809-4682-9815-32964d322f4d",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        80,
        -304
      ],
      "parameters": {
        "color": 7,
        "width": 560,
        "height": 352,
        "content": "## Detect valid cancellation\n\nStarts when the appointments sheet reports a cancellation, formats the slot date and time, and filters out records that are not eligible for a waitlist offer."
      },
      "typeVersion": 1
    },
    {
      "id": "ff09ec71-3e93-40e8-b80a-66b9cc98d8d9",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        656,
        -304
      ],
      "parameters": {
        "color": 7,
        "width": 608,
        "height": 352,
        "content": "## Prepare waitlist search\n\nMarks the cancelled slot as being processed, retrieves eligible waiting candidates from Google Sheets, and starts looping through them one at a time."
      },
      "typeVersion": 1
    },
    {
      "id": "c71de6d8-cc19-4470-a883-2e84e6b28a6b",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1328,
        -64
      ],
      "parameters": {
        "color": 7,
        "width": 432,
        "height": 352,
        "content": "## Handle no available fill\n\nRuns when the loop exhausts candidates without a booking, updates the slot as unfilled, and sends a Twilio notification to the owner."
      },
      "typeVersion": 1
    },
    {
      "id": "79eb4c2f-c5b3-4eb5-be51-2ef4da1f00f2",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1312,
        -400
      ],
      "parameters": {
        "color": 7,
        "width": 592,
        "height": 320,
        "content": "## Send candidate offer\n\nMarks the current waitlist candidate as offered, sends the open-slot offer by Twilio, and pauses while waiting for the candidate to respond."
      },
      "typeVersion": 1
    },
    {
      "id": "80d1614e-cab3-45ef-9cc5-b45214c106a1",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1920,
        -496
      ],
      "parameters": {
        "color": 7,
        "width": 400,
        "height": 528,
        "content": "## Evaluate candidate reply\n\nChecks whether the candidate confirmed the offer. If not confirmed in time, the candidate is marked expired and routed back to the waitlist loop for the next person."
      },
      "typeVersion": 1
    },
    {
      "id": "7cf8e5cf-ee7b-4800-972e-8579200987ec",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2336,
        -576
      ],
      "parameters": {
        "color": 7,
        "width": 368,
        "height": 352,
        "content": "## Create confirmed booking\n\nFor a confirming candidate, creates the appointment in Google Calendar and writes the booked appointment details back into Google Sheets."
      },
      "typeVersion": 1
    },
    {
      "id": "e548b9db-96b9-40b0-84fd-ebc2a1e4899e",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2720,
        -576
      ],
      "parameters": {
        "color": 7,
        "width": 368,
        "height": 368,
        "content": "## Finalize booked candidate\n\nUpdates the waitlist entry to booked and sends the candidate a Twilio booking confirmation message."
      },
      "typeVersion": 1
    },
    {
      "id": "c5b8b1a7-de05-4c7c-9a4e-a4116ad7151a",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -496,
        -528
      ],
      "parameters": {
        "width": 480,
        "height": 896,
        "content": "## Waitlist Auto-Fill on Cancellation\n\n### How it works\n\nThis workflow monitors a Google Sheet for cancelled appointments, validates that the slot has not already been offered, and prepares it for waitlist processing. It retrieves waiting candidates, offers the open slot one at a time via Twilio, waits for a reply, and either books the first confirming candidate or continues through the waitlist. If no one accepts, it marks the slot as unfilled and notifies the owner.\n\n### Setup steps\n\n- Connect Google Sheets credentials for the cancellation source sheet, waitlist sheet, and booked appointments sheet used by the workflow.\n- Connect Google Calendar credentials and select the calendar where replacement appointments should be created.\n- Connect Twilio credentials and configure the sender phone number plus recipient phone fields for candidates and owner notifications.\n- Verify the sheet columns used for appointment status, offered/processing flags, candidate contact details, appointment date/time, and waitlist status match the node mappings.\n- Configure the Wait node duration and confirmation-detection logic so candidate replies are evaluated within the intended response window.\n\n### Customization\n\nAdjust the waitlist ordering rules, SMS message templates, response timeout, and no-fill owner notification to match the business policy for filling cancelled appointments."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "timezone": "Asia/Kolkata",
    "binaryMode": "separate",
    "callerPolicy": "workflowsFromSameOwner",
    "timeSavedMode": "fixed",
    "availableInMCP": true,
    "executionOrder": "v1"
  },
  "versionId": "ff7c1edf-e931-43c6-a78f-0ff6444e089b",
  "nodeGroups": [],
  "connections": {
    "Format Date & Time": {
      "main": [
        [
          {
            "node": "Cancelled & Not Yet Offered?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Mark Slot Unfilled": {
      "main": [
        [
          {
            "node": "Notify Owner - No Fill",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Waitlist Offer": {
      "main": [
        [
          {
            "node": "Wait For Confirmation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Candidate Confirmed?": {
      "main": [
        [
          {
            "node": "Book Appointment in Calendar",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Mark Candidate Expired",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait For Confirmation": {
      "main": [
        [
          {
            "node": "Candidate Confirmed?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Waiting Candidates": {
      "main": [
        [
          {
            "node": "Loop Over Waitlist Candidates",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Mark Candidate Expired": {
      "main": [
        [
          {
            "node": "Loop Over Waitlist Candidates",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Mark Candidate Offered": {
      "main": [
        [
          {
            "node": "Send Waitlist Offer",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update Waitlist - Booked": {
      "main": [
        [
          {
            "node": "Send Booking Confirmation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Add Booked Appointment Row": {
      "main": [
        [
          {
            "node": "Update Waitlist - Booked",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Book Appointment in Calendar": {
      "main": [
        [
          {
            "node": "Add Booked Appointment Row",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Cancelled & Not Yet Offered?": {
      "main": [
        [
          {
            "node": "Mark Waitlist Processing Started",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Appointment Cancelled Trigger": {
      "main": [
        [
          {
            "node": "Format Date & Time",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Waitlist Candidates": {
      "main": [
        [
          {
            "node": "Mark Slot Unfilled",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Mark Candidate Offered",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Mark Waitlist Processing Started": {
      "main": [
        [
          {
            "node": "Get Waiting Candidates",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}