{
  "id": "r3Lx2TdP4752qrLM",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Leads to Instant Outreach",
  "tags": [],
  "nodes": [
    {
      "id": "d7501d1b-8898-45fd-a608-e0f78026b333",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1120,
        -368
      ],
      "parameters": {
        "width": 480,
        "height": 848,
        "content": "## Leads to Instant Outreach\n\n### How it works\n\n1. The workflow triggers when a new lead is captured via Facebook Lead Ads.\n2. It queries Google Sheets to check if the lead's information is already logged.\n3. Depending on the condition, it either creates a new database entry or proceeds to evaluation.\n4. Data is formatted and specialized Cal.com autofill parameters are generated.\n5. The lead is sent a WhatsApp message containing their personalized booking details.\n6. The state is updated in Redis and the finalized status is written back to the Google Sheet.\n\n### Setup steps\n\n- [ ] Connect and authenticate your Facebook Lead Ads account\n- [ ] Link your Google account and select the correct spreadsheet and worksheet in the Google Sheets nodes\n- [ ] Set up your WhatsApp API credentials to enable message sending\n- [ ] Provide the appropriate connection string and credentials for your Redis instance\n\n### Customization\n\nYou can modify the Edit Fields node to include additional lead data in the WhatsApp message or the Cal.com parameters."
      },
      "typeVersion": 1
    },
    {
      "id": "9f70b6d0-c53e-4ab4-8170-79025f68e53c",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -560,
        -240
      ],
      "parameters": {
        "color": 7,
        "width": 608,
        "height": 304,
        "content": "## Trigger and check existing lead\n\nReceives new leads from Facebook and checks Google Sheets to see if they already exist in the database."
      },
      "typeVersion": 1
    },
    {
      "id": "910f9837-0420-4880-a1a9-621ed3d98f44",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        96,
        -368
      ],
      "parameters": {
        "color": 7,
        "width": 288,
        "height": 560,
        "content": "## Handle new or existing lead\n\nUses conditional logic to either append a new row for new leads or route existing leads accordingly."
      },
      "typeVersion": 1
    },
    {
      "id": "72425022-a370-4cc1-b609-14e794732c6e",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        576,
        -176
      ],
      "parameters": {
        "color": 7,
        "width": 416,
        "height": 304,
        "content": "## Format booking parameters\n\nPrepares the lead's data and injects autofill parameters for a Cal.com booking link."
      },
      "typeVersion": 1
    },
    {
      "id": "bcd2150e-b58f-45ec-88e7-af1fb4813644",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1040,
        -176
      ],
      "parameters": {
        "color": 7,
        "width": 608,
        "height": 304,
        "content": "## Send message and save state\n\nDispatches a WhatsApp message to the lead, caches the event in Redis, and logs the final status back in Google Sheets."
      },
      "typeVersion": 1
    },
    {
      "id": "117c50ea-41cf-4811-9c82-bdddab1f0ed8",
      "name": "When Facebook Lead Received",
      "type": "n8n-nodes-base.facebookLeadAdsTrigger",
      "position": [
        -512,
        -112
      ],
      "parameters": {
        "form": {
          "__rl": true,
          "mode": "id",
          "value": "="
        },
        "page": {
          "__rl": true,
          "mode": "id",
          "value": "="
        },
        "options": {}
      },
      "credentials": {
        "facebookLeadAdsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "de416da0-999f-4d99-9ea4-c06d2971b034",
      "name": "Upsert Lead in Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        192,
        -160
      ],
      "parameters": {
        "columns": {
          "value": {
            "dnd": "false",
            "email": "={{ $('When Facebook Lead Received').item.json.field_data[1].values[0] }}",
            "phone": "={{ $('When Facebook Lead Received').item.json.field_data[2].values[0].replace('+', '') }}",
            "full name": "={{ $('When Facebook Lead Received').item.json.field_data[0].values[0] }}",
            "contacted?": "false",
            "Property Name": "={{ $('When Facebook Lead Received').item.json.field_data[3].values[0] }}"
          },
          "schema": [
            {
              "id": "full name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "full name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "phone",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "phone",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "email",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "email",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Property Name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Property Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "contacted?",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "contacted?",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "dnd",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "dnd",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "phone"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "appendOrUpdate",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1lKiWyaXfSVTQ6azjWbVg4sFc6owXRdIBWYNd7tnWxaY/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1lKiWyaXfSVTQ6azjWbVg4sFc6owXRdIBWYNd7tnWxaY",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1lKiWyaXfSVTQ6azjWbVg4sFc6owXRdIBWYNd7tnWxaY/edit?usp=drivesdk",
          "cachedResultName": "Facebook Leads"
        },
        "authentication": "serviceAccount"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "61d2818e-4f82-4f6a-8252-558bbcc54e64",
      "name": "Fetch Lead from Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -304,
        -112
      ],
      "parameters": {
        "options": {},
        "filtersUI": {
          "values": [
            {
              "lookupValue": "={{ $json.field_data[2].values[0].replace('+', '') }}",
              "lookupColumn": "phone"
            }
          ]
        },
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1lKiWyaXfSVTQ6azjWbVg4sFc6owXRdIBWYNd7tnWxaY/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1lKiWyaXfSVTQ6azjWbVg4sFc6owXRdIBWYNd7tnWxaY",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1lKiWyaXfSVTQ6azjWbVg4sFc6owXRdIBWYNd7tnWxaY/edit?usp=drivesdk",
          "cachedResultName": "Facebook Leads"
        },
        "authentication": "serviceAccount"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7,
      "alwaysOutputData": true
    },
    {
      "id": "9062a660-e273-428a-ad6d-74bc5d97bd49",
      "name": "Check If Row Exists",
      "type": "n8n-nodes-base.if",
      "position": [
        -96,
        -112
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "b47f1ea9-b27f-4e55-beaa-56194504246a",
              "operator": {
                "type": "number",
                "operation": "empty",
                "singleValue": true
              },
              "leftValue": "={{ $json.row_number }}",
              "rightValue": 0
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "d9990d60-46da-4220-830b-26e185f61601",
      "name": "Check If Contacted",
      "type": "n8n-nodes-base.if",
      "position": [
        208,
        32
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "68e557ba-1f59-4e82-ad0b-4cfc958705ca",
              "operator": {
                "type": "boolean",
                "operation": "false",
                "singleValue": true
              },
              "leftValue": "={{ $json['contacted?'] }}",
              "rightValue": ""
            },
            {
              "id": "61f9724e-a4c6-4a7b-a1e1-1749a1f6ab68",
              "operator": {
                "type": "boolean",
                "operation": "false",
                "singleValue": true
              },
              "leftValue": "={{ $json.dnd }}",
              "rightValue": false
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "12722dc1-5608-47f6-a68e-f5d3dbc3c2bc",
      "name": "Send WhatsApp Message",
      "type": "n8n-nodes-base.whatsApp",
      "position": [
        1088,
        -48
      ],
      "parameters": {
        "textBody": "=Hi {{ $json.lead_name }}, thank you for your interest in the {{ $json.lead_property }}! \ud83c\udfe1\n\nWould you like to schedule a viewing or a quick chat? You can easily pick a time that works perfectly for you by tapping the link below:\n\n\ud83d\udc49 {{ $json.whatsapp_ready_url }}\n\nLet me know if you have any questions!",
        "operation": "send",
        "phoneNumberId": "1083481144853090",
        "additionalFields": {},
        "recipientPhoneNumber": "={{ $('When Facebook Lead Received').item.json.field_data[2].values[0] }}"
      },
      "credentials": {
        "whatsAppApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "cc1380f2-7c53-4ba6-9258-b1d2766f4a5e",
      "name": "Save Session to Redis",
      "type": "n8n-nodes-base.redis",
      "position": [
        1296,
        -48
      ],
      "parameters": {
        "list": "=session:{{ $('When Facebook Lead Received').item.json.field_data[2].values[0].replace('+', '') }}",
        "operation": "push",
        "messageData": "=[\n  {\n    \"type\": \"ai\",\n    \"data\": {\n      \"content\": \"Hi {{ $('Add Calcom Params').item.json.lead_name }}, thank you for your interest in the {{ $('Add Calcom Params').item.json.lead_property }}! Would you like to schedule a viewing or a quick chat? You can easily pick a time that works perfectly for you by tapping the link below: {{ $('Add Calcom Params').item.json.whatsapp_ready_url }}\"\n    }\n  }\n]"
      },
      "credentials": {
        "redis": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "5c456a62-5820-46e1-a433-a3624095276c",
      "name": "Mark Contacted in Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1504,
        -48
      ],
      "parameters": {
        "columns": {
          "value": {
            "phone": "={{ $('When Facebook Lead Received').item.json.field_data[2].values[0].replace('+', '') }}",
            "contacted?": "true"
          },
          "schema": [
            {
              "id": "full name",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "full name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "phone",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "phone",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "email",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "email",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Property Name",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Property Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "contacted?",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "contacted?",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "dnd",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "dnd",
              "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": [
            "phone"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "update",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1lKiWyaXfSVTQ6azjWbVg4sFc6owXRdIBWYNd7tnWxaY/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1lKiWyaXfSVTQ6azjWbVg4sFc6owXRdIBWYNd7tnWxaY",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1lKiWyaXfSVTQ6azjWbVg4sFc6owXRdIBWYNd7tnWxaY/edit?usp=drivesdk",
          "cachedResultName": "Facebook Leads"
        },
        "authentication": "serviceAccount"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "86bffc8d-7a6f-48b6-a4fd-c440fcd39d8e",
      "name": "Set Address Fields",
      "type": "n8n-nodes-base.set",
      "position": [
        624,
        -48
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "5986aa9b-f408-4dbb-bfec-344b8217f462",
              "name": "NY street, Studio Appartment",
              "type": "string",
              "value": "https://cal.com/iam-v5192/nystudioappartment"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "5a1cae28-45a0-4a6d-bd7c-36750312fd0f",
      "name": "Add Calcom Params",
      "type": "n8n-nodes-base.code",
      "position": [
        848,
        -48
      ],
      "parameters": {
        "jsCode": "// 1. Grab the incoming data from your 'Edit Fields' node\nconst item = $input.first().json;\n\n// 2. Pull the raw lead data from the Facebook Trigger\nconst fbData = $('When Facebook Lead Received').first().json.field_data;\nconst fullName = fbData.find(f => f.name === 'full_name')?.values[0] || '';\nconst email = fbData.find(f => f.name === 'email')?.values[0] || '';\nconst phone = fbData.find(f => f.name === 'phone_number')?.values[0] || '';\nconst propertyName = fbData.find(f => f.name === 'Property Name')?.values[0] || '';\n\n// 3. Dynamically grab the base link you created in the 'Edit Fields' node \nconst baseLink = item[propertyName];\n\n// 4. Construct the autofill parameters manually using encodeURIComponent (safe for n8n sandbox)\nconst paramsObj = {\n  name: fullName,\n  email: email,\n  notes: `Phone: ${phone}`\n};\n\nconst queryString = Object.keys(paramsObj)\n  .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(paramsObj[key])}`)\n  .join('&');\n\n// 5. Stitch them together\nconst finalBookingUrl = baseLink ? `${baseLink}?${queryString}` : 'URL_NOT_FOUND';\n\n// 6. Output everything so it's ready for WhatsApp\nreturn {\n  json: {\n    ...item,\n    lead_name: fullName,\n    lead_property: propertyName,\n    whatsapp_ready_url: finalBookingUrl\n  }\n};"
      },
      "typeVersion": 2
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "availableInMCP": false,
    "executionOrder": "v1"
  },
  "versionId": "1aeef405-1a6d-439b-afb5-9becdd6a368a",
  "nodeGroups": [],
  "connections": {
    "Add Calcom Params": {
      "main": [
        [
          {
            "node": "Send WhatsApp Message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check If Contacted": {
      "main": [
        [
          {
            "node": "Set Address Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Address Fields": {
      "main": [
        [
          {
            "node": "Add Calcom Params",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check If Row Exists": {
      "main": [
        [
          {
            "node": "Upsert Lead in Sheets",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Check If Contacted",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Save Session to Redis": {
      "main": [
        [
          {
            "node": "Mark Contacted in Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send WhatsApp Message": {
      "main": [
        [
          {
            "node": "Save Session to Redis",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upsert Lead in Sheets": {
      "main": [
        [
          {
            "node": "Set Address Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Lead from Sheets": {
      "main": [
        [
          {
            "node": "Check If Row Exists",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When Facebook Lead Received": {
      "main": [
        [
          {
            "node": "Fetch Lead from Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}