{
  "id": "JzBm7zPFj4AURwU2",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Automated Outreach Emails with Gmail & Google Sheets Safety Controls",
  "tags": [
    {
      "id": "9fXLydrXFV9BUci9",
      "name": "JOB",
      "createdAt": "2025-12-15T14:02:22.458Z",
      "updatedAt": "2025-12-15T14:02:22.458Z"
    },
    {
      "id": "VI8W1vANQZgRV7M5",
      "name": "SHEETS",
      "createdAt": "2025-11-25T20:39:12.984Z",
      "updatedAt": "2025-11-25T20:39:12.984Z"
    },
    {
      "id": "vLLcwhiSm3lgtjpI",
      "name": "PORTFOLIO",
      "createdAt": "2025-10-30T14:01:29.686Z",
      "updatedAt": "2025-10-30T14:01:29.686Z"
    }
  ],
  "nodes": [
    {
      "id": "89b64ec1-ea43-4607-b45d-f5bdc31e4d89",
      "name": "Get Contacts with Emails",
      "type": "n8n-nodes-base.code",
      "position": [
        -2736,
        352
      ],
      "parameters": {
        "jsCode": "return items.filter(item => {\n  const email = item.json.EMAIL?.trim();\n  const status = item.json.status?.toLowerCase().trim();\n\n  const invalidStatuses = ['hot lead', 'unresponsive', 'spam', 'do not contact'];\n\n  return email && !invalidStatuses.includes(status);\n});\n"
      },
      "retryOnFail": true,
      "typeVersion": 2
    },
    {
      "id": "98cded50-307c-4c0b-860e-26e9344be990",
      "name": "Wait",
      "type": "n8n-nodes-base.wait",
      "position": [
        -528,
        -112
      ],
      "parameters": {
        "amount": "={{ Number($json.delay) / 1000 }}"
      },
      "retryOnFail": true,
      "typeVersion": 1.1
    },
    {
      "id": "b9c9ef0d-4459-4ed7-a32a-2ed884be31be",
      "name": "Initial Email NOT Sent?",
      "type": "n8n-nodes-base.if",
      "position": [
        -1104,
        240
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "2e82cac2-bf34-4184-926b-9e6a160a4bc9",
              "operator": {
                "type": "string",
                "operation": "empty",
                "singleValue": true
              },
              "leftValue": "={{ $json.STATUS }}",
              "rightValue": "SENT "
            }
          ]
        },
        "looseTypeValidation": true
      },
      "retryOnFail": true,
      "typeVersion": 2.2
    },
    {
      "id": "2ebd600b-a5b0-46e0-bc76-5e81c88a314c",
      "name": "Check Daily Email Counter",
      "type": "n8n-nodes-base.code",
      "position": [
        -208,
        -112
      ],
      "parameters": {
        "jsCode": "// === Daily Email Counter with Weekend Exclusion & Category Tracking ===\n\n// \u2705 1. Get today's date and day of week\nconst now = new Date();\nconst today = now.toISOString().split('T')[0];\nconst day = now.getDay(); // 0 = Sunday, 6 = Saturday\n\n// \u2705 2. Skip weekends automatically\nif (day === 0 || day === 6) {\n  console.log(\"\ud83d\udeab Weekend detected. Skipping all email sends today.\");\n  return []; // Stop workflow on weekends\n}\n\n// \u2705 3. Set your total daily Gmail quota\nconst totalLimit = 100;  // adjust if needed\n\n// \u2705 4. Access persistent storage (shared across all workflows)\nconst data = $getWorkflowStaticData('global');\n\n// \u2705 5. Reset if new day\nif (!data.sentCountDate || data.sentCountDate !== today) {\n  data.sentCountDate = today;\n  data.sentCount = 0;\n  data.breakdown = { initial: 0, retarget1: 0, retarget2: 0, reply: 0 };\n}\n\n// \u2705 6. Read email type passed from the Set node\nconst emailType = $json.emailType || 'unknown';\n\n// \u2705 7. Stop all if total daily quota is reached\nif (data.sentCount >= totalLimit) {\n  console.log(`\ud83d\udeab Daily Gmail quota reached (${data.sentCount}/${totalLimit}).`);\n  return [];\n}\n\n// \u2705 8. Define category-specific ratios (adjust to your liking)\nconst ratios = {\n  initial: 0.55,   // 55% for new hot leads\n  retarget1: 0.20, // 20% for first follow-up\n  retarget2: 0.15, // 15% for second follow-up\n  reply: 0.10,     // 10% for ongoing replies\n};\n\n// \u2705 9. Compute local quota per category\nconst localLimit = Math.floor(totalLimit * (ratios[emailType] || 0.25));\n\n// \u2705 10. Skip sending if that category is full\nif (data.breakdown[emailType] >= localLimit) {\n  console.log(`\u23f8 ${emailType} quota full (${localLimit} max).`);\n  return [];\n}\n\n// \u2705 11. Increment counters\ndata.sentCount += 1;\nif (!data.breakdown[emailType]) data.breakdown[emailType] = 0;\ndata.breakdown[emailType] += 1;\n\n// \u2705 12. Log updates\nconsole.log(`\ud83d\udce9 Sent #${data.sentCount}/${totalLimit} | Type: ${emailType}`);\nconsole.log(`\ud83d\udcca Breakdown: ${JSON.stringify(data.breakdown)}`);\n\n// \u2705 13. Allow sending to continue\nreturn items;"
      },
      "retryOnFail": true,
      "typeVersion": 2
    },
    {
      "id": "ec30e632-5d3b-4d8f-aa8b-a84f606d445c",
      "name": "Initial",
      "type": "n8n-nodes-base.set",
      "position": [
        -352,
        -112
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "010781bc-0f40-4e8a-9146-e8b202843b03",
              "name": "emailType",
              "type": "string",
              "value": "\"initial\""
            }
          ]
        },
        "includeOtherFields": true
      },
      "retryOnFail": true,
      "typeVersion": 3.4
    },
    {
      "id": "2e3376fb-07da-406e-802b-b767d67f35b1",
      "name": "Is SPAM?",
      "type": "n8n-nodes-base.if",
      "position": [
        -2000,
        336
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "2e82cac2-bf34-4184-926b-9e6a160a4bc9",
              "operator": {
                "type": "string",
                "operation": "contains"
              },
              "leftValue": "={{ $json.SPAM }}",
              "rightValue": "YES"
            }
          ]
        },
        "looseTypeValidation": true
      },
      "retryOnFail": true,
      "typeVersion": 2.2
    },
    {
      "id": "0d1f3a64-59f0-4d38-8a85-ead4b07acb75",
      "name": "Initial Email",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        -880,
        -128
      ],
      "parameters": {
        "options": {}
      },
      "retryOnFail": true,
      "typeVersion": 3
    },
    {
      "id": "3a392018-8b0c-4f68-959d-b5bb9bb69bae",
      "name": "Human wait time1",
      "type": "n8n-nodes-base.code",
      "position": [
        -688,
        -112
      ],
      "parameters": {
        "jsCode": "// Generate a random delay between 0 and 60 seconds (0\u20132 minutes)\nconst delay = Math.floor(Math.random() * 121); // random 0\u201360 seconds\n\n// Return delay in milliseconds so n8n understands\nreturn {\n  delay: delay * 1000\n};"
      },
      "retryOnFail": true,
      "typeVersion": 2
    },
    {
      "id": "8c66e9bc-d6a7-46d7-807d-a4c6c0a58a36",
      "name": "VALID EMAIL",
      "type": "n8n-nodes-base.code",
      "position": [
        -2512,
        352
      ],
      "parameters": {
        "jsCode": "// Full email cleanup + validation + precise block rules\nreturn items.map(item => {\n  let email = (item.json.EMAIL || \"\").trim().toLowerCase();\n  email = email.replace(/[.,]+$/, \"\"); // remove trailing dots/commas\n  item.json.EMAIL = email;\n\n  // Step 1: Strict syntax validation\n  const validEmail =\n    /^(?!.*\\.\\.)([a-zA-Z0-9._%+-]+)@([a-zA-Z0-9.-]+\\.[A-Za-z]{2,})$/;\n  const match = email.match(validEmail);\n  const domain = match ? match[2] : \"\";\n\n  // Step 2: Blocked full domains\n  const blockedDomains = [\n    \"coingecko.com\",\n    \"coinmarketcap.com\",\n    \"pinksale.finance\",\n    \"pump.fun\",\n    \"domain.com\",\n    \"mysite.com\",\n    \"facebook.com\",\n    \"instagram.com\",\n    \"linkedin.com\",\n    \"twitter.com\",\n    \"binance.com\",\n    \"mexc.com\",\n    \"tiktok.com\",\n  ];\n\n  // Step 3: Blocked partial or exact keyword matches\n  // \"@x.com\" specifically blocks real X (Twitter) addresses, not random \".x.com\" strings\n  const blockedKeywords = [\n    \"pumpfun\", // covers subdomains like \"team.pumpfun.io\"\n    \"@x.com\",  // only blocks if \"@x.com\" appears directly in email\n  ];\n\n  const isBlocked =\n    blockedDomains.includes(domain) ||\n    blockedKeywords.some(k => email.includes(k.toLowerCase()));\n\n  const isValidFormat = !!match;\n  const isValid = isValidFormat && !isBlocked;\n\n  // Step 4: Explanation fields\n  item.json.valid = isValid;\n  item.json.blocked = isBlocked;\n  item.json.reason = !isValidFormat\n    ? \"Invalid format\"\n    : isBlocked\n    ? \"Blocked keyword/domain\"\n    : \"Valid email\";\n\n  return item;\n});"
      },
      "retryOnFail": true,
      "typeVersion": 2
    },
    {
      "id": "46691763-e027-45cd-861d-1e285e0aa37f",
      "name": "VALID EMAIL?",
      "type": "n8n-nodes-base.if",
      "position": [
        -2288,
        352
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "4624283a-cb44-445c-a6f2-129fe51f7508",
              "operator": {
                "type": "boolean",
                "operation": "equals"
              },
              "leftValue": "={{ $json.valid }}",
              "rightValue": true
            }
          ]
        },
        "looseTypeValidation": true
      },
      "typeVersion": 2.2
    },
    {
      "id": "f4f8b2cc-9611-4830-93ce-b4ad24d02ff0",
      "name": "undelivered email?",
      "type": "n8n-nodes-base.if",
      "position": [
        -1504,
        432
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "3f1b5f23-fc22-45a3-820f-a9dbb78e44ec",
              "operator": {
                "type": "string",
                "operation": "startsWith"
              },
              "leftValue": "={{ $json[\"EMAIL VERIFIED\"] }}",
              "rightValue": "REACHABLE"
            }
          ]
        },
        "looseTypeValidation": true
      },
      "retryOnFail": true,
      "typeVersion": 2.2
    },
    {
      "id": "9c2c47fb-d6e3-41bd-bd84-e5ef17efb7f2",
      "name": "EMAIL VERIFICATION DONE?",
      "type": "n8n-nodes-base.if",
      "position": [
        -1664,
        592
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "d69349ac-3f32-4ecd-a3a6-15a78c65062b",
              "operator": {
                "type": "string",
                "operation": "notEmpty",
                "singleValue": true
              },
              "leftValue": "={{ $json['EMAIL VERIFIED'] }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "e9e78cba-c918-4265-bd78-b8c8311baac5",
      "name": "ONLY CHECK EMAIL NEEDED",
      "type": "n8n-nodes-base.filter",
      "position": [
        144,
        -112
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "f513ee99-602f-4bc8-8a99-3716f60a626a",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.EMAIL }}",
              "rightValue": "={{ $('Initial Email').item.json.EMAIL }}"
            }
          ]
        },
        "looseTypeValidation": true
      },
      "retryOnFail": true,
      "typeVersion": 2.2
    },
    {
      "id": "8ee0320f-c939-4a57-bb21-8cd25a6feeb7",
      "name": "9am Daily",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -3440,
        16
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "triggerAtHour": 9
            }
          ]
        }
      },
      "retryOnFail": true,
      "typeVersion": 1.2
    },
    {
      "id": "49ce39e0-731d-4ab3-bea8-99de19504bd7",
      "name": "SUBJECT LINES",
      "type": "n8n-nodes-base.code",
      "position": [
        384,
        -112
      ],
      "parameters": {
        "jsCode": "function pickRandom(arr) {\n  return arr[Math.floor(Math.random() * arr.length)];\n}\n\nreturn items.map(item => {\n  /* -------- SUBJECT LINES -------- */\n  const subjectPool = [\n    \"Quick question\",\n    \"Testing a new outreach workflow\",\n    \"Short introduction\",\n    \"Reaching out briefly\",\n    \"Exploring a quick connection\"\n  ];\n\n  /* -------- OPENING LINES -------- */\n  const openingLinePool = [\n    \"I hope you\u2019re having a great day.\",\n    \"Just a quick note to introduce myself.\",\n    \"I wanted to briefly reach out and say hello.\"\n  ];\n\n  /* -------- MAIN BODY (SALES / TEST) -------- */\n  const bodyPool = [\n    \"This is a short outreach message as part of testing a lightweight email automation workflow. No action is required \u2014 just validating delivery and formatting.\",\n    \"I\u2019m currently testing a simple outreach system designed for clean, low-volume communication. This message is part of that test.\",\n    \"This email is part of a small test to confirm that a new outreach workflow is working as expected.\"\n  ];\n\n  /* -------- CLOSING LINES -------- */\n  const closingLinePool = [\n    \"Thanks for your time.\",\n    \"Appreciate you reading this.\"\n  ];\n\n  /* -------- SIGNATURE -------- */\n  const senderName = item.json[\"Sender Name\"] || \"Your Name\";\n\n  const signature = `\n<p style=\"margin-top:14px;font-family:Arial,Helvetica,sans-serif;font-size:14px;\">\nYours sincerely,<br>\n<strong>${senderName}</strong>\n</p>\n`;\n\n  return {\n    json: {\n      ...item.json,\n      Subject: pickRandom(subjectPool),\n      Greeting: `Hi ${item.json.Name || \"there\"},`,\n      Opening: pickRandom(openingLinePool),\n      Body: pickRandom(bodyPool),\n      Closing: pickRandom(closingLinePool),\n      Signature: signature\n    }\n  };\n});\n"
      },
      "retryOnFail": true,
      "typeVersion": 2
    },
    {
      "id": "db293a22-876e-4c0c-83f4-8ed39a7ec855",
      "name": "Download file",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        832,
        -128
      ],
      "parameters": {
        "fileId": {
          "__rl": true,
          "mode": "url",
          "value": ""
        },
        "options": {},
        "operation": "download"
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "68833003-73d3-4b46-b63b-0cabbe06e0a5",
      "name": "EMAILS SHEET",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -3120,
        352
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1160858465,
          "cachedResultUrl": "",
          "cachedResultName": "PORTFOLIO"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1ua7aVmykESCwx6JBHBZHDmNyg7tmTkGnaL4WeoptHSE",
          "cachedResultUrl": "",
          "cachedResultName": "JOB"
        },
        "authentication": "serviceAccount"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "5a3f979e-0daf-4f6c-8c57-27729e7ffc8c",
      "name": "10 SECONDS WAIT",
      "type": "n8n-nodes-base.wait",
      "position": [
        -2944,
        352
      ],
      "parameters": {
        "amount": 10
      },
      "retryOnFail": true,
      "typeVersion": 1.1
    },
    {
      "id": "f736ceff-a4b3-4a36-bfe5-58817b091621",
      "name": "Initial Email NOT Sent? SECOND CHECK",
      "type": "n8n-nodes-base.if",
      "position": [
        624,
        -112
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "2e82cac2-bf34-4184-926b-9e6a160a4bc9",
              "operator": {
                "type": "string",
                "operation": "empty",
                "singleValue": true
              },
              "leftValue": "={{ $json.STATUS }}",
              "rightValue": "SENT "
            }
          ]
        },
        "looseTypeValidation": true
      },
      "retryOnFail": true,
      "typeVersion": 2.2
    },
    {
      "id": "b4be98a9-6680-4297-b4d3-991ae37280e6",
      "name": "UPDATE EMAIL SHEET",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1200,
        -48
      ],
      "parameters": {
        "columns": {
          "value": {
            "SENT": "={{ 'SENT \u2705' }}",
            "EMAIL": "={{ $('Initial Email NOT Sent? SECOND CHECK').item.json.EMAIL }}",
            "DATE SENT": "={{ new Date().toISOString().split('T')[0] }}"
          },
          "schema": [
            {
              "id": "EMAIL",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "EMAIL",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Name",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "EMAIL VERIFIED",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "EMAIL VERIFIED",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "EMAIL SMTP VERIFIED",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "EMAIL SMTP VERIFIED",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "EMAIL SUGGESTION",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "EMAIL SUGGESTION",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "EMAIL TYPE",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "EMAIL TYPE",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "SENT",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "SENT",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "DATE SENT",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "DATE SENT",
              "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": [
            "EMAIL"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "update",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1160858465,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1ua7aVmykESCwx6JBHBZHDmNyg7tmTkGnaL4WeoptHSE/edit#gid=1160858465",
          "cachedResultName": "PORTFOLIO"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1ua7aVmykESCwx6JBHBZHDmNyg7tmTkGnaL4WeoptHSE",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1ua7aVmykESCwx6JBHBZHDmNyg7tmTkGnaL4WeoptHSE/edit?usp=drivesdk",
          "cachedResultName": "JOB"
        },
        "authentication": "serviceAccount"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "cea79305-c6a0-442e-93f8-aab30b9efe2f",
      "name": "SEND INITIAL EMAIL",
      "type": "n8n-nodes-base.gmail",
      "maxTries": 2,
      "position": [
        976,
        -128
      ],
      "parameters": {
        "sendTo": "={{ $json.EMAIL }}",
        "message": "=Hi {{ $json.Name || \"there\" }},\n<br><br>\n{{ $json.Opening }}\n<br><br>\n{{ $json.Body }}\n<br><br>\n{{ $json.Closing }}\n\nKindly find attached a sample image.\n<br><br>\n{{ $json.Signature }}\n",
        "options": {
          "senderName": "=Your Name - Highlight",
          "attachmentsUi": {
            "attachmentsBinary": [
              {}
            ]
          },
          "appendAttribution": false
        },
        "subject": "={{ $('SUBJECT LINES').item.json.Subject }}"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "retryOnFail": true,
      "typeVersion": 2.1,
      "alwaysOutputData": false
    },
    {
      "id": "95bfba0d-9c27-4bdc-86f6-44a31a20a226",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -3824,
        -432
      ],
      "parameters": {
        "width": 640,
        "height": 1184,
        "content": "## \ud83d\udce7 AUTOMATED INITIAL COLD OUTREACH EMAILS WITH SAFETY CONTROLS\n\n## HOW?\n\nThis workflow automatically sends personalized emails to contacts\nstored in Google Sheets and NocoDB.\n\nIt includes email validation, spam filtering, daily send limits,\nhuman-like delays, and automatic status updates.\n\n## SETUP STEPS\n1. Connect Google Sheets\n2. Connect Gmail\n3. Connect NocoDB (optional)\n4. Review email limits before activating\n\n\n## GMAIL  PAYLOAD\nto: {{ $json.EMAIL }}\nsubject: {{ $('SUBJECT LINES').item.json.Subject }}\n\nHi {{ $json.Name || \"there\" }},\n<br><br>\n{{ $json.Opening }}\n<br><br>\n{{ $json.Body }}\n<br><br>\n{{ $json.Closing }}\n\nKindly find attached a sample image.\n<br><br>\n{{ $json.Signature }}\n\n\n\n\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "f0f07d57-2128-4d2b-9533-816d1fc0b8b1",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -3168,
        96
      ],
      "parameters": {
        "color": 7,
        "width": 576,
        "height": 656,
        "content": "## STEP 1:  Get Contats From Sheets\n\nThis step pulls contact records from Google Sheets.\n\n-->Only rows with email addresses are considered.\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "22ff2773-9a0d-4eea-8fa1-57a908e7b766",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2544,
        96
      ],
      "parameters": {
        "color": 7,
        "width": 416,
        "height": 656,
        "content": "## STEP 2:  Clean and Validate Emails\n\n\nThis step:\n\u2022 Fixes formatting issues\n\u2022 Blocks known bad domains\n\u2022 Rejects invalid email formats\n\u2022 Flags risky addresses\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "88d10059-24f5-454f-b4f7-f6c0de19d7d6",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2080,
        96
      ],
      "parameters": {
        "color": 7,
        "width": 336,
        "height": 656,
        "content": "## STEP 3: Spam Check\n\n\nThis step checks if a contact is marked as spam\n\n-->Spam records are skipped immediately to protect your email reputation.\n\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "16397514-e1b0-4acc-a9f3-b1844e4d71d3",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1712,
        96
      ],
      "parameters": {
        "color": 7,
        "width": 768,
        "height": 656,
        "content": "## STEP 4: Initial Email Status Check\n\nThis step checks if an initial email was already sent.\n\n-->If yes, the workflow skips the contact to avoid duplicate or accidental re-sending.\n\n\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "2a808f7c-9015-4c30-9c32-65fbef9dab08",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -384,
        -416
      ],
      "parameters": {
        "color": 7,
        "width": 304,
        "height": 480,
        "content": "## STEP 6: Daily Status Check\n\nThis step controls how many emails can be sent per day.\n\nIt:\n\u2022 Blocks sending on weekends\n\u2022 Enforces daily email limits\n\u2022 Tracks counts per email type\n\n\n\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "7bb21639-7b9f-4eab-acc5-ebb971833fba",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -928,
        -416
      ],
      "parameters": {
        "color": 7,
        "width": 528,
        "height": 480,
        "content": "## STEP 5: Human Like Delay\n\nA random delay is added before sending each email.\n\nThis makes the workflow behave more like a human\nand less like a bot, reducing the risk of spam detection\nor account restrictions.\n\n\n\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "0c731a75-e623-42ff-9112-7cf3bac441ed",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        304,
        -416
      ],
      "parameters": {
        "color": 7,
        "width": 272,
        "height": 480,
        "content": "## STEP 8: Subject and Content Generation\n\nThis step generates personalized subject lines\nand opening sentences.\n\n\n\n\n\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "23e62390-7138-46e8-b30d-4a571eb10712",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        592,
        -416
      ],
      "parameters": {
        "color": 7,
        "width": 512,
        "height": 480,
        "content": "## STEP 9: Send Email\n\nThis step sends the actual email using Gmail.\n\nThe email includes:\n\u2022 Personalized subject line\n\u2022 Custom opening\n\u2022 Main message\n\u2022 Signature and links\n\nAttachments can also be included here.\n\n\n\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "e813f237-ae28-4546-8f2a-5a313a0bbb5e",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1152,
        -432
      ],
      "parameters": {
        "color": 7,
        "height": 544,
        "content": "## STEP 10: Update Sheet\n\nAfter an email is sent, this step updates Google Sheets.\n\nIt records:\n\u2022 Email sent status\n\u2022 Date sent\n\u2022 Email address\n\nThis ensures accurate tracking\nand prevents duplicate sends.\n\n\n\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "dbb6e068-bfda-433d-aa6e-9e78995f2944",
      "name": "Sticky Note10",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -64,
        -416
      ],
      "parameters": {
        "color": 7,
        "width": 352,
        "height": 480,
        "content": "## STEP 7: Initial Email Check\n\nThis step confirms the correct email record is being processed.\n\n-->It prevents mismatched data before generating content or sending emails.\n\n\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "4349a640-c900-443a-b6f7-c18d143fd69c",
      "name": "INITIAL EMAIL SHEET",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -32,
        -112
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1160858465,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1ua7aVmykESCwx6JBHBZHDmNyg7tmTkGnaL4WeoptHSE/edit#gid=1160858465",
          "cachedResultName": "PORTFOLIO"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1ua7aVmykESCwx6JBHBZHDmNyg7tmTkGnaL4WeoptHSE",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1ua7aVmykESCwx6JBHBZHDmNyg7tmTkGnaL4WeoptHSE/edit?usp=drivesdk",
          "cachedResultName": "JOB"
        },
        "authentication": "serviceAccount"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "7f2db0d1-4524-44f1-b11c-b0feb4d385a2",
      "name": "Has Name?",
      "type": "n8n-nodes-base.if",
      "position": [
        -1296,
        336
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "36c386b4-e586-4374-997d-f7879f6d8670",
              "operator": {
                "type": "string",
                "operation": "notEmpty",
                "singleValue": true
              },
              "leftValue": "={{ $json.Name }}",
              "rightValue": ""
            }
          ]
        },
        "looseTypeValidation": true
      },
      "retryOnFail": true,
      "typeVersion": 2.2
    }
  ],
  "active": false,
  "settings": {
    "timezone": "Africa/Lagos",
    "callerPolicy": "workflowsFromSameOwner",
    "errorWorkflow": "",
    "availableInMCP": false,
    "executionOrder": "v1",
    "saveDataSuccessExecution": "all"
  },
  "versionId": "1a6195c4-2b71-4adc-bffc-5e1d6e7bc2b3",
  "connections": {
    "Wait": {
      "main": [
        [
          {
            "node": "Initial",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Initial": {
      "main": [
        [
          {
            "node": "Check Daily Email Counter",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Is SPAM?": {
      "main": [
        [],
        [
          {
            "node": "EMAIL VERIFICATION DONE?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "9am Daily": {
      "main": [
        [
          {
            "node": "EMAILS SHEET",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Has Name?": {
      "main": [
        [
          {
            "node": "Initial Email NOT Sent?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "VALID EMAIL": {
      "main": [
        [
          {
            "node": "VALID EMAIL?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "EMAILS SHEET": {
      "main": [
        [
          {
            "node": "10 SECONDS WAIT",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "VALID EMAIL?": {
      "main": [
        [
          {
            "node": "Is SPAM?",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "Download file": {
      "main": [
        [
          {
            "node": "SEND INITIAL EMAIL",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Initial Email": {
      "main": [
        [],
        [
          {
            "node": "Human wait time1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "SUBJECT LINES": {
      "main": [
        [
          {
            "node": "Initial Email NOT Sent? SECOND CHECK",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "10 SECONDS WAIT": {
      "main": [
        [
          {
            "node": "Get Contacts with Emails",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Human wait time1": {
      "main": [
        [
          {
            "node": "Wait",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "SEND INITIAL EMAIL": {
      "main": [
        [
          {
            "node": "UPDATE EMAIL SHEET",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "UPDATE EMAIL SHEET": {
      "main": [
        [
          {
            "node": "Initial Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "undelivered email?": {
      "main": [
        [
          {
            "node": "Has Name?",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "INITIAL EMAIL SHEET": {
      "main": [
        [
          {
            "node": "ONLY CHECK EMAIL NEEDED",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Initial Email NOT Sent?": {
      "main": [
        [
          {
            "node": "Initial Email",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "ONLY CHECK EMAIL NEEDED": {
      "main": [
        [
          {
            "node": "SUBJECT LINES",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "EMAIL VERIFICATION DONE?": {
      "main": [
        [
          {
            "node": "undelivered email?",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "Get Contacts with Emails": {
      "main": [
        [
          {
            "node": "VALID EMAIL",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Daily Email Counter": {
      "main": [
        [
          {
            "node": "INITIAL EMAIL SHEET",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Initial Email NOT Sent? SECOND CHECK": {
      "main": [
        [
          {
            "node": "Download file",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    }
  }
}