{
  "id": "gWYB2udQphzvbBtr",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "SPAM MANAGER FOR LEAD GENERATION",
  "tags": [
    {
      "id": "vLLcwhiSm3lgtjpI",
      "name": "PORTFOLIO",
      "createdAt": "2025-10-30T14:01:29.686Z",
      "updatedAt": "2025-10-30T14:01:29.686Z"
    }
  ],
  "nodes": [
    {
      "id": "32987478-6fa0-4af1-a228-506d1de3b155",
      "name": "DATA",
      "type": "n8n-nodes-base.code",
      "position": [
        -4464,
        960
      ],
      "parameters": {
        "jsCode": "// Get all items (rows) from the node named \"if\"\nconst allRows = $items(\"MERGE\").map(item => item.json);\n\n// You can now inspect or return them\nreturn allRows.map((row, index) => ({\n  json: {\n    index: index + 1,\n    ...row,\n  }\n}));"
      },
      "typeVersion": 2
    },
    {
      "id": "e0c2ec34-f541-4516-ba88-3f533c0300c2",
      "name": "MERGE",
      "type": "n8n-nodes-base.code",
      "position": [
        -3856,
        544
      ],
      "parameters": {
        "jsCode": "/**\n * \ud83e\udde9 Smart Merge Node (Keep Matches)\n * Matches case-insensitive emails between:\n *   - Node 1: EXTRACT EMAIL\n *   - Node 2: MAIN SHEET\n *\n * \u2705 Automatically detects email field in MAIN SHEET (even if it's \"EMAIL\" or \"Email Address\")\n * \u2705 Returns all details from both nodes\n */\n\nconst snippetNode = \"EXTRACT EMAIL\";\nconst sheetNode = \"MAIN SHEET\";\n\n// \ud83d\udd39 Get both datasets\nconst snippets = $items(snippetNode).map(i => i.json);\nconst sheet = $items(sheetNode).map(i => i.json);\n\n// \ud83e\udde0 Step 1 \u2014 Detect email field name in MAIN SHEET dynamically\nlet emailFieldName = \"email\";\nif (sheet.length > 0) {\n  const firstRowKeys = Object.keys(sheet[0]);\n  const guess = firstRowKeys.find(k => k.toLowerCase().includes(\"email\"));\n  if (guess) emailFieldName = guess;\n}\n\nconsole.log(`\ud83d\udce7 Using email field from MAIN SHEET: \"${emailFieldName}\"`);\n\n// \ud83e\udde9 Step 2 \u2014 Build lookup from MAIN SHEET (case-insensitive)\nconst lookup = {};\nfor (const row of sheet) {\n  const emailValue = row[emailFieldName];\n  const email = emailValue ? String(emailValue).toLowerCase().trim() : null;\n  if (email) lookup[email] = row;\n}\n\n// \ud83d\udd0d Step 3 \u2014 Merge based on matching emails\nconst results = [];\nfor (const snip of snippets) {\n  const email = snip.email ? snip.email.toLowerCase().trim() : null;\n  if (email && lookup[email]) {\n    results.push({\n      json: {\n        email,\n        snippet: snip,            // full data from EXTRACT EMAIL node\n        matchedRecord: lookup[email],  // full row from MAIN SHEET\n      },\n    });\n  }\n}\n\n// \u26a0\ufe0f Step 4 \u2014 Handle no matches\nif (results.length === 0) {\n  console.warn(`\u26a0\ufe0f No matches found between \"${snippetNode}\" and \"${sheetNode}\".`);\n}\n\nreturn results;"
      },
      "typeVersion": 2
    },
    {
      "id": "f274460e-3394-46b3-818f-3f2ddfb831a6",
      "name": "EXTRACT EMAIL",
      "type": "n8n-nodes-base.code",
      "position": [
        -4368,
        544
      ],
      "parameters": {
        "jsCode": "/**\n * \ud83d\udce7 Extract Email + Message ID from Gmail snippet\n * Example input:\n * {\n *   \"id\": \"19a5c9cd5za12bfa\",\n *   \"snippet\": \"Delivery incomplete... to user@example.com...\"\n * }\n */\n\nreturn items.map(item => {\n  const text = item.json.snippet || \"\";\n  const messageId = item.json.id || null;\n  const emailRegex = /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}/g;\n\n  // Find all emails in the snippet\n  const emails = text.match(emailRegex) || [];\n\n  return {\n    json: {\n      MESSAGE_ID: messageId,\n      snippet: text,\n      email: emails[0] || null // Return the first matched email\n    }\n  };\n});"
      },
      "retryOnFail": true,
      "typeVersion": 2
    },
    {
      "id": "13ff3901-bad6-4615-83d6-3e4d891e73d4",
      "name": "CHECK INBOX",
      "type": "n8n-nodes-base.gmailTrigger",
      "position": [
        -4608,
        544
      ],
      "parameters": {
        "filters": {
          "sender": "user@example.com",
          "readStatus": "both",
          "includeSpamTrash": true
        },
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        }
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "retryOnFail": true,
      "typeVersion": 1.3
    },
    {
      "id": "ef0f0d7f-d898-411e-8ac1-353c115edf4c",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -4688,
        288
      ],
      "parameters": {
        "color": 7,
        "width": 736,
        "height": 480,
        "content": "\n### Step 1: GMAIL TRIGGER\n\n\u2060->Monitors your Gmail inbox for bounce or spam messages (like mailer-daemon replies) and extracts the email to compare with your MAIN outreach sheet\n"
      },
      "typeVersion": 1
    },
    {
      "id": "e7d866ef-2051-48a7-b026-88585a9d99af",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -3680,
        288
      ],
      "parameters": {
        "color": 7,
        "width": 352,
        "height": 480,
        "content": "### Step 3:  CHECK SPAM STATUS\n-> If the email has already been marked as spam, do nothing; else move on to add the \"SPAM\" tag"
      },
      "typeVersion": 1
    },
    {
      "id": "e9869de3-6f6a-4996-b513-b7ec7082611d",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -4000,
        800
      ],
      "parameters": {
        "color": 7,
        "width": 672,
        "height": 576,
        "content": "### Step 5: GMAIL TAG\n-> Adds \"Unsubscribe\" and/or \"Spam\" in GMAIL\n->Marks as read in GMAIL"
      },
      "typeVersion": 1
    },
    {
      "id": "66ac7a9f-412d-44c0-8050-cb07de8a700e",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -5232,
        272
      ],
      "parameters": {
        "width": 512,
        "height": 1104,
        "content": "## SPAM MANAGER FOR LEAD GENERATION\n\n\n\n\n## HOW?\n\nThis workflow keeps your sender reputation high \n\nby removing dead, blocked, and invalid emails before they drag down your \n\ncampaigns.\n\nEvery \u201cDelivery failed\u201d or \u201cMailbox full\u201d reply is caught and logged \n\nautomatically ensuring you only contact real, active prospects.\n\n\n\n\n\n## SETUP STEPS\n\n-->Connect Gmail credentials & node\n\n-->Connect NocoDB API token/Google Sheets\n\n-->Have a column in your sheets for \"SPAM\" and \"SPAM DATE\"\n\n--> Create a new sheet just for \"SPAM\" emails, this helps you cross \n\nreference with other sheets in the future.\n\n-->Follow the steps highlighted and then test the workflow\n"
      },
      "typeVersion": 1
    },
    {
      "id": "3e1cade6-d84e-46ce-adfb-358df4c24ede",
      "name": "MAIN OUTREACH SHEET",
      "type": "n8n-nodes-base.nocoDb",
      "position": [
        -4112,
        544
      ],
      "parameters": {
        "options": {},
        "operation": "getAll",
        "returnAll": true,
        "authentication": "nocoDbApiToken"
      },
      "credentials": {
        "nocoDbApiToken": {
          "name": "<your credential>"
        }
      },
      "executeOnce": true,
      "retryOnFail": true,
      "typeVersion": 3
    },
    {
      "id": "aa762630-8b44-42ec-b2f2-3d5d46016899",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -3936,
        288
      ],
      "parameters": {
        "color": 7,
        "height": 480,
        "content": "\n### Step 2: MERGE\n\n\u2060->Merge email from the GMAIl node with the emails in your MAIN outreach sheet\n"
      },
      "typeVersion": 1
    },
    {
      "id": "f561fc71-7f90-4064-b58a-82507091dd8e",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -4688,
        800
      ],
      "parameters": {
        "color": 7,
        "width": 672,
        "height": 576,
        "content": "### Step 4:  CHECK SPAM STATUS\n->Add the \"SPAM\" tag to the MAIN outreach sheet and also create a copy of the contact in your SPAM sheet"
      },
      "typeVersion": 1
    },
    {
      "id": "dca0cd60-08a4-4168-9264-7d6e810584be",
      "name": "ADD TO SPAM SHEET",
      "type": "n8n-nodes-base.nocoDb",
      "position": [
        -4448,
        1184
      ],
      "parameters": {
        "fieldsUi": {
          "fieldValues": [
            {
              "fieldName": "EMAIL",
              "fieldValue": "={{ $json.snippet.email }}"
            },
            {
              "fieldName": "MESSAGE",
              "fieldValue": "={{ $json.snippet.snippet }}"
            },
            {
              "fieldName": "DATE",
              "fieldValue": "={{ new Date().toISOString().split('T')[0] }}"
            },
            {
              "fieldName": "WHERE",
              "fieldValue": "BAD EMAIL"
            }
          ]
        },
        "operation": "create",
        "authentication": "nocoDbApiToken"
      },
      "credentials": {
        "nocoDbApiToken": {
          "name": "<your credential>"
        }
      },
      "executeOnce": true,
      "retryOnFail": true,
      "typeVersion": 3
    },
    {
      "id": "12b61410-b706-4e93-a018-37de475581f9",
      "name": "UPDATE SPAM NAME IN MAIN OUTREACH SHEET",
      "type": "n8n-nodes-base.nocoDb",
      "position": [
        -4192,
        912
      ],
      "parameters": {
        "fieldsUi": {
          "fieldValues": [
            {
              "fieldName": "id",
              "fieldValue": "={{ $json.matchedRecord.Id }}"
            },
            {
              "fieldName": "SPAM",
              "fieldValue": "=YES"
            }
          ]
        },
        "operation": "update",
        "authentication": "nocoDbApiToken"
      },
      "credentials": {
        "nocoDbApiToken": {
          "name": "<your credential>"
        }
      },
      "executeOnce": true,
      "retryOnFail": true,
      "typeVersion": 3
    },
    {
      "id": "be8fc34c-bd32-4628-9477-f563cdeecf4a",
      "name": "Already has the spam tag?",
      "type": "n8n-nodes-base.if",
      "position": [
        -3632,
        544
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "114b278c-60f4-41c3-bf7f-42339e662c98",
              "operator": {
                "name": "filter.operator.equals",
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.matchedRecord.SPAM }}",
              "rightValue": "YES"
            }
          ]
        },
        "looseTypeValidation": true
      },
      "retryOnFail": true,
      "typeVersion": 2.2
    },
    {
      "id": "ab021db2-f90b-46e9-99bd-7ade97ea512e",
      "name": "Do Nothing",
      "type": "n8n-nodes-base.noOp",
      "position": [
        -3504,
        416
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "5f1bd35e-9957-47c8-a403-adc4ab7967ee",
      "name": "1 EMAIL AT A TIME",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        -4672,
        1168
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "72d95930-533d-44a8-ba05-3a7d1b138a7d",
      "name": "1 EMAIL AT A TIME. ",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        -3936,
        1120
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "3bb27522-7756-42eb-be80-841f5b107c1f",
      "name": "ADD UNSUBSCRIBE AND/OR SPAM TAG TO EMAIL",
      "type": "n8n-nodes-base.gmail",
      "position": [
        -3712,
        1088
      ],
      "parameters": {
        "labelIds": [
          "Label_2476288409640151649",
          "SPAM"
        ],
        "messageId": "={{ $json.snippet.MESSAGE_ID }}",
        "operation": "addLabels"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "retryOnFail": true,
      "typeVersion": 2.1
    },
    {
      "id": "cc35433e-ef69-433d-817d-44eec777c5e7",
      "name": "MARK EMAIL AS READ",
      "type": "n8n-nodes-base.gmail",
      "position": [
        -3488,
        1184
      ],
      "parameters": {
        "messageId": "={{ $json.id }}",
        "operation": "markAsRead"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "d6dac5e9-8593-4b8a-a34f-206abb2d20ae",
      "name": "NO OPERATION",
      "type": "n8n-nodes-base.noOp",
      "position": [
        -3536,
        928
      ],
      "parameters": {},
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "timezone": "Africa/Lagos",
    "callerPolicy": "workflowsFromSameOwner",
    "errorWorkflow": "UNrVZbiiSpgbbt9H",
    "availableInMCP": false,
    "executionOrder": "v1",
    "saveExecutionProgress": false,
    "timeSavedPerExecution": 5,
    "saveDataSuccessExecution": "none"
  },
  "versionId": "11947fd0-eb54-4b67-930b-b9bfd5e341a1",
  "connections": {
    "DATA": {
      "main": [
        [
          {
            "node": "UPDATE SPAM NAME IN MAIN OUTREACH SHEET",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "MERGE": {
      "main": [
        [
          {
            "node": "Already has the spam tag?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "CHECK INBOX": {
      "main": [
        [
          {
            "node": "EXTRACT EMAIL",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "EXTRACT EMAIL": {
      "main": [
        [
          {
            "node": "MAIN OUTREACH SHEET",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "1 EMAIL AT A TIME": {
      "main": [
        [
          {
            "node": "DATA",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "ADD TO SPAM SHEET",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "ADD TO SPAM SHEET": {
      "main": [
        [
          {
            "node": "1 EMAIL AT A TIME",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "MARK EMAIL AS READ": {
      "main": [
        [
          {
            "node": "1 EMAIL AT A TIME. ",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "1 EMAIL AT A TIME. ": {
      "main": [
        [
          {
            "node": "NO OPERATION",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "ADD UNSUBSCRIBE AND/OR SPAM TAG TO EMAIL",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "MAIN OUTREACH SHEET": {
      "main": [
        [
          {
            "node": "MERGE",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Already has the spam tag?": {
      "main": [
        [
          {
            "node": "Do Nothing",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "1 EMAIL AT A TIME",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "UPDATE SPAM NAME IN MAIN OUTREACH SHEET": {
      "main": [
        [
          {
            "node": "1 EMAIL AT A TIME. ",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "ADD UNSUBSCRIBE AND/OR SPAM TAG TO EMAIL": {
      "main": [
        [
          {
            "node": "MARK EMAIL AS READ",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}