{
  "id": "ZXu9x8swL0SiSX6C",
  "name": "AI-Powered Outreach & Follow-Up Automation (GPT-4o + Gmail + Google Sheets)",
  "tags": [],
  "nodes": [
    {
      "id": "0d069126-2ec1-43ac-8122-8d444f20c43b",
      "name": "When clicking \u2018Execute workflow\u2019",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        -1232,
        304
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "461208fc-76f3-4882-a743-ca623b2ca29b",
      "name": "Configure GPT-4o Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatAzureOpenAi",
      "position": [
        -16,
        832
      ],
      "parameters": {
        "model": "gpt-4o",
        "options": {}
      },
      "credentials": {
        "azureOpenAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "a7137b17-4d59-4ce1-857c-03e15e590f70",
      "name": "Retrieve Lead Records from Google Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -944,
        304
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 46113423,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/17rcNd_ZpUQLm0uWEVbD-NY6GyFUkrD4BglvawlyBygM/edit#gid=46113423",
          "cachedResultName": "outreach automation"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "17rcNd_ZpUQLm0uWEVbD-NY6GyFUkrD4BglvawlyBygM",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/17rcNd_ZpUQLm0uWEVbD-NY6GyFUkrD4BglvawlyBygM/edit?usp=drivesdk",
          "cachedResultName": "sample_leads_50"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4
    },
    {
      "id": "35a5d947-361f-40a9-9d57-efe5a2d462db",
      "name": "Validate Lead Data Payload",
      "type": "n8n-nodes-base.if",
      "position": [
        -688,
        304
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "e2adb005-2b3c-4d1e-8445-442df1fe925a",
              "operator": {
                "type": "string",
                "operation": "notEmpty",
                "singleValue": true
              },
              "leftValue": "=/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test({{ $json.Email }})",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "f7aaf899-8eec-4178-bc3e-88985592be72",
      "name": "Filter for Booked Leads",
      "type": "n8n-nodes-base.if",
      "position": [
        -400,
        304
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "b7913fcd-b70c-47fd-a926-d09a0086b40e",
              "operator": {
                "name": "filter.operator.equals",
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json[\"Booking Status\"] }}",
              "rightValue": "BOOKED"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "35b45b6e-c542-49f7-aead-01c561647444",
      "name": "Generate Personalized Outreach Email (AI)",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        0,
        320
      ],
      "parameters": {
        "text": "=Generate a personalized outreach email in HTML format for this lead:\n\nCompany Name: {{ $json[\"Company Name\"] }}\nContact Person: {{ $json[\"Contact Person\"] }}\nJob Title: {{ $json[\"Job Title\"] }}\nIndustry: {{ $json[\"Industry\"] }}\nLocation: {{ $json[\"Location\"] }}\nLead Source: {{ $json[\"Lead Source\"] }}\nBooking Status: {{ $json[\"Booking Status\"] }}\n\nThe goal is to re-engage them and encourage a meeting booking.\nMention their company or industry naturally, and make it sound warm and specific.\nKeep it clean and mobile-friendly HTML (no styles or colors).\n",
        "options": {
          "systemMessage": "=You are an AI sales assistant that writes short, friendly, and professional B2B outreach emails in HTML format. \nEach email should be under 150 words and formatted using <p>, <b>, and <br> tags. \nAlways output both the Subject and the Email Body separately. \nDo not include <html> or <body> tags. \nThe tone should be polite, conversational, and slightly persuasive. \nEnd with a clear call to action (like booking a meeting) and sign off as \u201cSaurabh Garg, Sales Team.\u201d\nReturn your answer in JSON format with two keys:\n{\n  \"subject\": \"...\",\n  \"body_html\": \"...\"\n}\n"
        },
        "promptType": "define"
      },
      "typeVersion": 2.1
    },
    {
      "id": "eb74688d-5d4b-4a8f-ba88-03111715fb52",
      "name": "Parse AI Email Output (JavaScript)",
      "type": "n8n-nodes-base.code",
      "position": [
        448,
        320
      ],
      "parameters": {
        "jsCode": "// Loop through AI results and clean up JSON output\nreturn items.map(item => {\n  let raw = item.json.output || '';\n  \n  // Remove code block markers like ```json or ```\n  raw = raw.replace(/```json|```/g, '').trim();\n\n  // Parse JSON safely\n  let parsed;\n  try {\n    parsed = JSON.parse(raw);\n  } catch (e) {\n    parsed = { subject: \"No Subject\", body_html: \"Error parsing AI output.\" };\n  }\n\n  return { json: parsed };\n});\n"
      },
      "typeVersion": 2
    },
    {
      "id": "5e6c825b-1739-411b-b7b5-291937596a9f",
      "name": "Send Initial Outreach Email via Gmail",
      "type": "n8n-nodes-base.gmail",
      "position": [
        768,
        320
      ],
      "parameters": {
        "sendTo": "={{ $('Retrieve Lead Records from Google Sheets').item.json.Email }}",
        "message": "={{ $json.body_html }}",
        "options": {},
        "subject": "={{ $json.subject }}"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "540211f0-f006-4845-8fed-02d41d9fc634",
      "name": "Wait Before Thread Check (24 hr)",
      "type": "n8n-nodes-base.wait",
      "position": [
        1040,
        320
      ],
      "parameters": {
        "amount": 24
      },
      "typeVersion": 1
    },
    {
      "id": "537915a6-88d4-4353-b5f7-d0c2424119ce",
      "name": "Fetch Sent Email Thread from Gmail",
      "type": "n8n-nodes-base.gmail",
      "position": [
        1312,
        320
      ],
      "parameters": {
        "options": {},
        "resource": "thread",
        "threadId": "={{ $('Send Initial Outreach Email via Gmail').item.json.threadId }}",
        "operation": "get"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "80bbd250-f9ab-46de-9ad6-b3ab8e7f3233",
      "name": "Check for Client Reply (If Condition)",
      "type": "n8n-nodes-base.if",
      "position": [
        1568,
        320
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "4a6d1310-29be-4559-8bea-afe8fe0f0f30",
              "operator": {
                "type": "string",
                "operation": "contains"
              },
              "leftValue": "={{$json[\"messages\"][1][\"snippet\"]}}",
              "rightValue": "Yes"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "5366521f-fc42-4907-9e1e-29994458578c",
      "name": "Extract Reply Details (JavaScript)",
      "type": "n8n-nodes-base.code",
      "position": [
        1920,
        48
      ],
      "parameters": {
        "jsCode": "// Loop through all email threads where reply = true\nreturn items.map(item => {\n  const data = item.json;\n\n  // Extract the reply message (second email in thread)\n  const reply = data.messages?.[1];\n  const original = data.messages?.[0];\n\n  // Clean the reply text (remove quoted text from Gmail)\n  let clientMessage = reply?.snippet || \"\";\n  clientMessage = clientMessage.split(\"On Wed\")[0].trim(); // basic cleanup example\n\n  // Prepare clean structured output\n  return {\n    json: {\n      Email: reply?.From?.match(/<(.+?)>/)?.[1] || reply?.From || \"\",\n      ContactPerson: reply?.From?.split(\"<\")[0].trim() || \"\",\n      ThreadID: reply?.threadId || data.id || \"\",\n      Subject: reply?.Subject || original?.Subject || \"\",\n      ClientMessage: clientMessage,\n      BookingStatus: \"BOOKED\",\n      LastUpdated: new Date().toISOString()\n    }\n  };\n});\n"
      },
      "typeVersion": 2
    },
    {
      "id": "dfc24134-8604-47d3-8932-41df52d14620",
      "name": "Update Lead Record \u2013 Booked (Google Sheets)",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2224,
        48
      ],
      "parameters": {
        "columns": {
          "value": {
            "Email": "={{ $json.Email }}",
            "ThreadID": "={{ $json.ThreadID }}",
            "LastUpdated": "={{ $json.LastUpdated }}",
            "ClientMessage": "={{ $json.ClientMessage }}",
            "Booking Status": "={{ $json.BookingStatus }}"
          },
          "schema": [
            {
              "id": "Company Name",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Company Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Contact Person",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Contact Person",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Job Title",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Job Title",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Email",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Email",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Phone",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Phone",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Industry",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Industry",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Location",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Location",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Lead Source",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Lead Source",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Booking Status",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Booking Status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "ClientMessage",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "ClientMessage",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "LastUpdated",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "LastUpdated",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "ThreadID",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "ThreadID",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "Email"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "appendOrUpdate",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 46113423,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/17rcNd_ZpUQLm0uWEVbD-NY6GyFUkrD4BglvawlyBygM/edit#gid=46113423",
          "cachedResultName": "outreach automation"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "17rcNd_ZpUQLm0uWEVbD-NY6GyFUkrD4BglvawlyBygM",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/17rcNd_ZpUQLm0uWEVbD-NY6GyFUkrD4BglvawlyBygM/edit?usp=drivesdk",
          "cachedResultName": "sample_leads_50"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.6
    },
    {
      "id": "bf3a2ee4-1bbc-445e-8c3f-2119dd16e95d",
      "name": "Wait Before Second Thread Check (24 hr)",
      "type": "n8n-nodes-base.wait",
      "position": [
        2224,
        544
      ],
      "parameters": {
        "unit": "seconds",
        "amount": 24
      },
      "typeVersion": 1
    },
    {
      "id": "6ac3e8ce-2dac-4953-97d2-3221e3d5be82",
      "name": "Send Second Follow-Up Email via Gmail",
      "type": "n8n-nodes-base.gmail",
      "position": [
        1888,
        544
      ],
      "parameters": {
        "sendTo": "={{ $json.messages[0].To }}",
        "message": "=<p>Hi {{ $json[\"Contact Person\"] || \"there\" }},</p>\n\n<p>I wanted to quickly follow up on my previous email.  \nI understand things can get busy, so just checking if you had a chance to review my message.</p>\n\n<p>I\u2019d love to schedule a short chat to explore how we could support <b> {{ $('Retrieve Lead Records from Google Sheets').item.json['Contact Person'] }}</b> in your upcoming initiatives.</p>\n\n<p>If now\u2019s not a good time, no worries \u2014 just let me know when it might be better for you.</p>\n\n<p>Best regards,<br>\n<b>Saurabh Garg</b><br>\nSales Team</p>\n",
        "options": {},
        "subject": "Still open to a quick chat."
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "7b8c0b58-0aba-4b63-b690-6efee3c35d52",
      "name": "Fetch Follow-Up Thread from Gmail",
      "type": "n8n-nodes-base.gmail",
      "position": [
        2512,
        544
      ],
      "parameters": {
        "options": {},
        "resource": "thread",
        "threadId": "={{ $json.threadId }}",
        "operation": "get"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "9b0df250-edcd-4963-a14d-7c332ca2ba78",
      "name": "Check for Second Reply (If Condition)",
      "type": "n8n-nodes-base.if",
      "position": [
        2784,
        544
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "4a6d1310-29be-4559-8bea-afe8fe0f0f30",
              "operator": {
                "type": "string",
                "operation": "contains"
              },
              "leftValue": "={{$json[\"messages\"][1][\"snippet\"]}}",
              "rightValue": "Yes"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "54350e4a-92e1-445e-aa9a-05ca7b2bc015",
      "name": "Update Lead Status to Declined (Set Node)",
      "type": "n8n-nodes-base.set",
      "position": [
        3200,
        800
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "eddf188b-c756-4cd3-b5ac-3bdbce3a3049",
              "name": "Booking Status",
              "type": "string",
              "value": "Declined"
            },
            {
              "id": "df707470-60d7-4024-a998-8b7ba3c93283",
              "name": "Email",
              "type": "string",
              "value": "={{ $json.messages[0].To }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "cb100856-ab8b-42d8-a899-8273a21d2498",
      "name": "Update Lead Record \u2013 Declined (Google Sheets)",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        3424,
        800
      ],
      "parameters": {
        "columns": {
          "value": {
            "Email": "={{ $json.Email }}",
            "Booking Status": "={{ $json[\"Booking Status\"] }}"
          },
          "schema": [
            {
              "id": "Company Name",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Company Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Contact Person",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Contact Person",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Job Title",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Job Title",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Email",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Email",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Phone",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Phone",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Industry",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Industry",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Location",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Location",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Lead Source",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Lead Source",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Booking Status",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Booking Status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "ClientMessage",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "ClientMessage",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "LastUpdated",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "LastUpdated",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "ThreadID",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "ThreadID",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "Email"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "appendOrUpdate",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 46113423,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/17rcNd_ZpUQLm0uWEVbD-NY6GyFUkrD4BglvawlyBygM/edit#gid=46113423",
          "cachedResultName": "outreach automation"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "17rcNd_ZpUQLm0uWEVbD-NY6GyFUkrD4BglvawlyBygM",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/17rcNd_ZpUQLm0uWEVbD-NY6GyFUkrD4BglvawlyBygM/edit?usp=drivesdk",
          "cachedResultName": "sample_leads_50"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.6
    },
    {
      "id": "392fd316-f1e0-4de5-aea6-5fb872b1c767",
      "name": "Update Lead Record \u2013 Replied (Google Sheets)",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        3440,
        240
      ],
      "parameters": {
        "columns": {
          "value": {
            "Email": "={{ $json.Email }}",
            "ThreadID": "={{ $json.ThreadID }}",
            "LastUpdated": "={{ $json.LastUpdated }}",
            "ClientMessage": "={{ $json.ClientMessage }}",
            "Booking Status": "={{ $json.BookingStatus }}"
          },
          "schema": [
            {
              "id": "Company Name",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Company Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Contact Person",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Contact Person",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Job Title",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Job Title",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Email",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Email",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Phone",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Phone",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Industry",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Industry",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Location",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Location",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Lead Source",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Lead Source",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Booking Status",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Booking Status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "ClientMessage",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "ClientMessage",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "LastUpdated",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "LastUpdated",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "ThreadID",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "ThreadID",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "Email"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "appendOrUpdate",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 46113423,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/17rcNd_ZpUQLm0uWEVbD-NY6GyFUkrD4BglvawlyBygM/edit#gid=46113423",
          "cachedResultName": "outreach automation"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "17rcNd_ZpUQLm0uWEVbD-NY6GyFUkrD4BglvawlyBygM",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/17rcNd_ZpUQLm0uWEVbD-NY6GyFUkrD4BglvawlyBygM/edit?usp=drivesdk",
          "cachedResultName": "sample_leads_50"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.6
    },
    {
      "id": "6da18860-30f8-476a-84fc-b10084fc6f4e",
      "name": "Extract Second Reply Details (JavaScript)",
      "type": "n8n-nodes-base.code",
      "position": [
        3168,
        240
      ],
      "parameters": {
        "jsCode": "// Loop through all email threads where reply = true\nreturn items.map(item => {\n  const data = item.json;\n\n  // Extract the reply message (second email in thread)\n  const reply = data.messages?.[1];\n  const original = data.messages?.[0];\n\n  // Clean the reply text (remove quoted text from Gmail)\n  let clientMessage = reply?.snippet || \"\";\n  clientMessage = clientMessage.split(\"On Wed\")[0].trim(); // basic cleanup example\n\n  // Prepare clean structured output\n  return {\n    json: {\n      Email: reply?.From?.match(/<(.+?)>/)?.[1] || reply?.From || \"\",\n      ContactPerson: reply?.From?.split(\"<\")[0].trim() || \"\",\n      ThreadID: reply?.threadId || data.id || \"\",\n      Subject: reply?.Subject || original?.Subject || \"\",\n      ClientMessage: clientMessage,\n      BookingStatus: \"BOOKED\",\n      LastUpdated: new Date().toISOString()\n    }\n  };\n});\n"
      },
      "typeVersion": 2
    },
    {
      "id": "3672ff59-f78b-42c3-b5d4-c311bd12bc09",
      "name": "Log Invalid Leads to Google Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -352,
        784
      ],
      "parameters": {
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "",
          "cachedResultUrl": "",
          "cachedResultName": ""
        },
        "documentId": {
          "__rl": true,
          "mode": "url",
          "value": ""
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.6
    },
    {
      "id": "fa1d3fb9-4316-473c-a98d-d86688288bc1",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2176,
        -592
      ],
      "parameters": {
        "width": 976,
        "height": 544,
        "content": "## \ud83e\udd16 AI-Powered Outreach & Follow-Up Automation (GPT-4o + Gmail + Google Sheets)\nAutomates personalized outreach, follow-ups, and lead status management directly from Google Sheets using GPT-4o and Gmail.\n\n### \ud83d\udd39 Core Workflow Summary\n1\ufe0f\u20e3 Fetches leads from Google Sheets  \n2\ufe0f\u20e3 Validates lead data and filters \u201cBOOKED\u201d prospects  \n3\ufe0f\u20e3 Generates personalized outreach emails using GPT-4o  \n4\ufe0f\u20e3 Sends emails via Gmail and monitors for replies  \n5\ufe0f\u20e3 If no reply \u2192 Sends automated follow-up  \n6\ufe0f\u20e3 Updates lead booking status automatically in Google Sheets\n\n### \ud83d\udd39 Tools & Integrations\n- Google Sheets \u2192 Lead database  \n- Azure OpenAI (GPT-4o) \u2192 Email personalization  \n- Gmail \u2192 Message delivery + reply tracking  \n- JavaScript \u2192 Data cleanup and formatting  \n- Wait nodes \u2192 Timing for recheck and follow-ups  \n\n### \ud83d\udd39 Use Case\nIdeal for sales teams handling cold/warm leads who need to automate email outreach, monitor engagement, and maintain clean CRM updates \u2014 all without manual effort.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "396639c9-7361-4452-9d84-3d979e7823fb",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1008,
        0
      ],
      "parameters": {
        "color": 7,
        "height": 512,
        "content": "## \ud83e\uddfe Retrieve Lead Records from Google Sheets  \nPulls all lead data from the specified Google Sheet (\u201csample_leads_50\u201d).  \nIncludes fields like company name, contact person, job title, industry, and booking status.  \nActs as the entry point for the outreach campaign.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "7c0917c7-bbb8-493c-b795-7d0cbef9de56",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -752,
        48
      ],
      "parameters": {
        "color": 7,
        "height": 448,
        "content": "## \ud83e\udde9 Validate Lead Data Payload  \nEnsures that each record has a valid email address format using regex.  \nIf valid \u2192 proceeds to filtering.  \nIf invalid \u2192 logs details to the \u201cInvalid Leads\u201d sheet.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "e4fd669c-4099-4fb2-ac1a-f8b50a0d957c",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -464,
        64
      ],
      "parameters": {
        "color": 7,
        "height": 432,
        "content": "## \ud83c\udfaf Filter for Booked Leads  \nSeparates leads based on the \u201cBooking Status\u201d column.  \nOnly unbooked or open leads proceed to email generation.  \nPrevents re-contacting leads already converted or declined.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "91004249-8604-423c-9173-1510532b4c32",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -80,
        576
      ],
      "parameters": {
        "color": 7,
        "height": 416,
        "content": "## \u2699\ufe0f Configure GPT-4o Model  \nLinks Azure OpenAI GPT-4o model for personalized email generation.  \nEnsures each message is contextually relevant, professional, and concise.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "36b8dd72-9f4a-4f7a-b42f-16b917b7a7f7",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -32,
        -16
      ],
      "parameters": {
        "color": 7,
        "width": 288,
        "height": 528,
        "content": "## \u2709\ufe0f Generate Personalized Outreach Email (AI)  \nGPT-4o creates customized outreach messages for each lead using name, industry, and lead source context.  \nOutput includes:\n- \u201csubject\u201d \u2192 catchy and relevant  \n- \u201cbody_html\u201d \u2192 mobile-friendly HTML with <p> and <b> tags  \nEnds with a polite CTA signed as \u201cSaurabh Garg, Sales Team.\u201d\n"
      },
      "typeVersion": 1
    },
    {
      "id": "48df91f8-b98d-47ca-9ae1-7b18883531ea",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        384,
        64
      ],
      "parameters": {
        "color": 7,
        "height": 432,
        "content": "## \ud83e\udde0 Parse AI Email Output (JavaScript)  \nCleans GPT-4o output by removing code blocks and parsing JSON safely.  \nEnsures valid `subject` and `body_html` fields before email dispatch.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "ea0c948b-46f5-4439-811f-b109d9f13b3a",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        704,
        64
      ],
      "parameters": {
        "color": 7,
        "height": 464,
        "content": "## \ud83d\udce4 Send Initial Outreach Email via Gmail  \nDelivers the AI-generated email to the lead\u2019s email address.  \nUses Gmail OAuth for secure delivery.  \nStores Gmail thread IDs for tracking replies.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "0d840272-78c6-4676-9e22-e80ed0c51c85",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        976,
        96
      ],
      "parameters": {
        "color": 7,
        "height": 432,
        "content": "## \u23f1\ufe0f Wait Before Thread Check  \nIntroduces a controlled delay (e.g., 24 hours) before checking if the lead has replied.  \nEnsures enough time for recipients to respond naturally.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "d4508106-1715-400b-a4c4-1ae422647747",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1232,
        144
      ],
      "parameters": {
        "color": 7,
        "width": 512,
        "height": 400,
        "content": "## \ud83e\udde9 Check for Client Reply  \nFetches Gmail thread data to see if a response was received.  \nIf the message contains any positive snippet or \u201cYes\u201d, marks lead as \u201cBOOKED.\u201d  \nIf not, moves to follow-up sequence.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "d4b7826a-4119-4638-989d-7ced0c23cfb9",
      "name": "Sticky Note10",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1856,
        -224
      ],
      "parameters": {
        "color": 7,
        "height": 464,
        "content": "## \ud83d\udcec Extract Reply Details (JavaScript)  \nParses client reply text and extracts useful data (email, message, thread ID).  \nSanitizes Gmail snippets by removing quoted text.  \nStores results for CRM update.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "cfb1aeb6-0030-45a8-aba9-8473abcbb64b",
      "name": "Sticky Note11",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2160,
        -256
      ],
      "parameters": {
        "color": 7,
        "height": 496,
        "content": "## \u2705 Update Lead Record \u2013 Booked (Google Sheets)  \nUpdates the lead record in the main sheet with \u201cBOOKED\u201d status, reply message, and timestamp.  \nMaintains real-time CRM hygiene.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "89803f2c-06ef-4ff5-aaab-37a21b4e3069",
      "name": "Sticky Note12",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1824,
        272
      ],
      "parameters": {
        "color": 7,
        "height": 480,
        "content": "## \ud83d\udd01 Send Second Follow-Up Email via Gmail  \nIf no reply after the first email, sends a polite follow-up after 24 hours.  \nTone remains professional and friendly, encouraging response without pressure.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "ef74ec33-bd55-4f50-baa8-7b8ee5b28953",
      "name": "Sticky Note13",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2160,
        304
      ],
      "parameters": {
        "color": 7,
        "width": 208,
        "height": 432,
        "content": "## \u23f1\ufe0f Wait Before Thread Check  \nIntroduces a controlled delay (e.g., 24 hours) before checking if the lead has replied.  \nEnsures enough time for recipients to respond naturally.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "1fc0aee3-436a-4048-a8c7-1961a47ffec4",
      "name": "Sticky Note14",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2432,
        336
      ],
      "parameters": {
        "color": 7,
        "height": 416,
        "content": "## \ud83d\udce8 Fetch Follow-Up Thread from Gmail  \nRetrieves the Gmail thread of the follow-up message to check if a new reply arrived.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "67182b47-ddba-47d2-be7c-ea3ad548d7a1",
      "name": "Sticky Note15",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2720,
        320
      ],
      "parameters": {
        "color": 7,
        "height": 432,
        "content": "## \ud83d\udd0d Check for Second Reply  \nInspects the follow-up thread for responses.  \nBranches into \u201cReply Found\u201d (update as BOOKED) or \u201cNo Reply\u201d (mark as Declined).\n"
      },
      "typeVersion": 1
    },
    {
      "id": "833511eb-4e42-484c-ad8a-8bf59814b5a2",
      "name": "Sticky Note16",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3088,
        608
      ],
      "parameters": {
        "color": 7,
        "width": 560,
        "height": 384,
        "content": "## \u274c Update Lead Record \u2013 Declined (Google Sheets)  \nIf no response after follow-up, updates status to \u201cDeclined.\u201d  \nPrevents repeated outreach and keeps CRM clean.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "99ffdfe2-e395-4004-acf7-3dfc51d5cfe6",
      "name": "Sticky Note17",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3104,
        0
      ],
      "parameters": {
        "color": 7,
        "height": 432,
        "content": "## \ud83e\uddfe Extract Second Reply Details (JavaScript)  \nHandles cases where the client replied to the follow-up instead of the first message.  \nParses, cleans, and prepares structured JSON data for CRM update.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "6570873f-5445-49cb-951d-9aa2014df10c",
      "name": "Sticky Note18",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3376,
        -32
      ],
      "parameters": {
        "color": 7,
        "height": 496,
        "content": "## \u2705 Update Lead Record \u2013 Booked (Google Sheets)  \nUpdates the lead record in the main sheet with \u201cBOOKED\u201d status, reply message, and timestamp.  \nMaintains real-time CRM hygiene.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "22fed90c-0601-421b-9079-3ca3652b1f9a",
      "name": "Sticky Note19",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -416,
        560
      ],
      "parameters": {
        "color": 7,
        "height": 464,
        "content": "## \u26a0\ufe0f Log Invalid Leads to Google Sheets  \nStores invalid or incomplete entries (missing emails, broken data) in a separate sheet.  \nUseful for data quality improvement.\n"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "cc9e6722-fa25-48dc-b8cc-9060afd4be2e",
  "connections": {
    "Configure GPT-4o Model": {
      "ai_languageModel": [
        [
          {
            "node": "Generate Personalized Outreach Email (AI)",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Filter for Booked Leads": {
      "main": [
        [],
        [
          {
            "node": "Generate Personalized Outreach Email (AI)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Validate Lead Data Payload": {
      "main": [
        [
          {
            "node": "Filter for Booked Leads",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Log Invalid Leads to Google Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait Before Thread Check (24 hr)": {
      "main": [
        [
          {
            "node": "Fetch Sent Email Thread from Gmail",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Follow-Up Thread from Gmail": {
      "main": [
        [
          {
            "node": "Check for Second Reply (If Condition)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Reply Details (JavaScript)": {
      "main": [
        [
          {
            "node": "Update Lead Record \u2013 Booked (Google Sheets)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Sent Email Thread from Gmail": {
      "main": [
        [
          {
            "node": "Check for Client Reply (If Condition)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse AI Email Output (JavaScript)": {
      "main": [
        [
          {
            "node": "Send Initial Outreach Email via Gmail",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When clicking \u2018Execute workflow\u2019": {
      "main": [
        [
          {
            "node": "Retrieve Lead Records from Google Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check for Client Reply (If Condition)": {
      "main": [
        [
          {
            "node": "Extract Reply Details (JavaScript)",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Send Second Follow-Up Email via Gmail",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check for Second Reply (If Condition)": {
      "main": [
        [
          {
            "node": "Extract Second Reply Details (JavaScript)",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Update Lead Status to Declined (Set Node)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Initial Outreach Email via Gmail": {
      "main": [
        [
          {
            "node": "Wait Before Thread Check (24 hr)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Second Follow-Up Email via Gmail": {
      "main": [
        [
          {
            "node": "Wait Before Second Thread Check (24 hr)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait Before Second Thread Check (24 hr)": {
      "main": [
        [
          {
            "node": "Fetch Follow-Up Thread from Gmail",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Retrieve Lead Records from Google Sheets": {
      "main": [
        [
          {
            "node": "Validate Lead Data Payload",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Second Reply Details (JavaScript)": {
      "main": [
        [
          {
            "node": "Update Lead Record \u2013 Replied (Google Sheets)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Personalized Outreach Email (AI)": {
      "main": [
        [
          {
            "node": "Parse AI Email Output (JavaScript)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update Lead Status to Declined (Set Node)": {
      "main": [
        [
          {
            "node": "Update Lead Record \u2013 Declined (Google Sheets)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}