{
  "id": "1q5Uq1CaoW5RqKlU",
  "meta": {
    "instanceId": "aef76b423886a07b252d20106f8086abdbbd112b2f476427e6dfc77234612f4b"
  },
  "name": "UNSUBSCRIBE MANAGER FOR LEAD GEN V.3.0",
  "tags": [
    {
      "id": "vLLcwhiSm3lgtjpI",
      "name": "PORTFOLIO",
      "createdAt": "2025-10-30T14:01:29.686Z",
      "updatedAt": "2025-10-30T14:01:29.686Z"
    }
  ],
  "nodes": [
    {
      "id": "d11fc570-173b-4584-b733-884ad7f0b6c7",
      "name": "Watch New replies",
      "type": "n8n-nodes-base.gmailTrigger",
      "position": [
        -448,
        160
      ],
      "parameters": {
        "filters": {
          "includeSpamTrash": true
        },
        "pollTimes": {
          "item": [
            {
              "mode": "everyX",
              "unit": "minutes",
              "value": 5
            }
          ]
        }
      },
      "retryOnFail": true,
      "typeVersion": 1.3
    },
    {
      "id": "3f255b99-90dc-49e9-9f6e-fe312dde0bfa",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        384,
        272
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o-mini",
          "cachedResultName": "gpt-4o-mini"
        },
        "options": {
          "maxTokens": 20,
          "temperature": 0.1
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "2ebd3350-9ae9-462c-883e-df3aa08f8d84",
      "name": "DETECT INTENT",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "position": [
        256,
        128
      ],
      "parameters": {
        "text": "=You are a message intent detector for outreach emails. \nYour job is to determine if this message means the sender wants to stop receiving emails or unsubscribe.\n\nReply strictly with one word:\n- \"unsubscribe\" → if they indicate they don't want further contact (even indirectly)\n- \"keep\" → if they are interested, neutral, or unrelated.\n\nMessage:\n{{ $json.snippet }}",
        "batching": {},
        "promptType": "define"
      },
      "retryOnFail": true,
      "typeVersion": 1.7
    },
    {
      "id": "12d530c3-e5fa-4a8b-bd40-3194789d54ba",
      "name": "NORMALIZE AI OUTPUT",
      "type": "n8n-nodes-base.code",
      "position": [
        544,
        128
      ],
      "parameters": {
        "jsCode": "return items.map(item => {\n  let aiResponse = \"\";\n\n  const json = item.json;\n  if (json.message?.[0]?.content) {\n    aiResponse = json.message[0].content;\n  } else if (json.data) {\n    aiResponse = json.data;\n  } else if (json.choices?.[0]?.message?.content) {\n    aiResponse = json.choices[0].message.content;\n  } else if (json.text) {\n    aiResponse = json.text;\n  }\n\n  aiResponse = aiResponse?.trim().toLowerCase() || \"\";\n\n  const isUnsubscribe =\n    aiResponse.includes(\"unsubscribe\") ||\n    aiResponse.includes(\"remove me\") ||\n    aiResponse.includes(\"opt out\") ||\n    aiResponse.includes(\"stop emailing\") ||\n    aiResponse.includes(\"do not contact\");\n\n  return {\n    json: {\n      ...json,\n      aiResponse,\n      isUnsubscribe\n    }\n  };\n});"
      },
      "retryOnFail": true,
      "typeVersion": 2
    },
    {
      "id": "097760ab-a7f7-4c68-956c-7f2f3743d48d",
      "name": "CHECK MAIN SHEET",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        224,
        576
      ],
      "parameters": {
        "options": {},
        "filtersUI": {
          "values": [
            {
              "lookupValue": "={{ \n  $('Watch New replies').item.json.From.match(/<([^>]+)>/)?.[1]?.trim().toLowerCase() || \n  $('Watch New replies').item.json.From.trim().toLowerCase() \n}}",
              "lookupColumn": "EMAIL"
            }
          ]
        },
        "sheetName": {
          "__rl": true,
          "mode": "id",
          "value": "your-google-sheet-id"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "your-google-sheet-id"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "credential-id",
          "name": "googleSheetsOAuth2Api Credential"
        }
      },
      "retryOnFail": true,
      "typeVersion": 4.7
    },
    {
      "id": "3c7f3275-2562-4a74-8dd9-46bb6f21a5cc",
      "name": "Delete rows or columns from sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        448,
        576
      ],
      "parameters": {
        "operation": "delete",
        "sheetName": {
          "__rl": true,
          "mode": "id",
          "value": "your-google-sheet-id"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "your-google-sheet-id"
        },
        "startIndex": "={{ $json.row_number }}",
        "authentication": "serviceAccount"
      },
      "retryOnFail": true,
      "typeVersion": 4.7
    },
    {
      "id": "e6f988b5-3d8d-4113-bccf-9df91f1e92c1",
      "name": "ADD TO UNSUBSCRIBE",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1312,
        240
      ],
      "parameters": {
        "columns": {
          "value": {
            "DATE": "={{ new Date().toISOString().split('T')[0] }}",
            "EMAIL": "={{ $('IS EMAIL THERE?').first().json.Email }}",
            "WHERE": "UNSUBSCRIBE MESSAGE REPLY",
            "MESSAGE": "={{ $('Watch New replies').item.json.snippet }}"
          },
          "schema": [
            {
              "id": "EMAIL",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "EMAIL",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "DATE",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "DATE",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "WHERE",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "WHERE",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "MESSAGE",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "MESSAGE",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {
          "useAppend": true
        },
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "id",
          "value": "your-google-sheet-id"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "your-google-sheet-id"
        },
        "authentication": "serviceAccount"
      },
      "executeOnce": false,
      "retryOnFail": true,
      "typeVersion": 4.7
    },
    {
      "id": "1fb3adb5-cf01-41f7-980a-d366013e894f",
      "name": "ADD UNSUBSCRIBE TO EMAIL",
      "type": "n8n-nodes-base.gmail",
      "position": [
        752,
        576
      ],
      "webhookId": "4880abb5-be92-4f90-bb1e-188852f33655",
      "parameters": {
        "labelIds": [
          "Label_2476288409640151649"
        ],
        "messageId": "={{ $('Watch New replies').item.json.id }}",
        "operation": "addLabels"
      },
      "retryOnFail": true,
      "typeVersion": 2.1
    },
    {
      "id": "68fd2508-7c12-4121-b7a0-1fb18fd81893",
      "name": "Get unsubscribe sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1088,
        48
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "id",
          "value": "your-google-sheet-id"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "your-google-sheet-id"
        },
        "authentication": "serviceAccount"
      },
      "retryOnFail": true,
      "typeVersion": 4.7,
      "alwaysOutputData": true
    },
    {
      "id": "94e94f3c-1484-4ba4-8b2c-0747f94c605c",
      "name": "IS EMAIL THERE?",
      "type": "n8n-nodes-base.code",
      "position": [
        1280,
        48
      ],
      "parameters": {
        "jsCode": "//----------------------------------------------------\n// Inputs\n//----------------------------------------------------\nconst unsubscribed = $items(\"Get unsubscribe sheet\").map(i => \n  (i.json.Email || \"\").toLowerCase().trim()\n);\nconst currentEmail = $('Watch New replies').item.json.From\n  .match(/<([^>]+)>/)?.[1]?.toLowerCase().trim() || \n  $('Watch New replies').item.json.From.toLowerCase().trim();\n\n//----------------------------------------------------\n// Check and decide\n//----------------------------------------------------\nif (!unsubscribed.includes(currentEmail)) {\n  return [{ json: { Email: currentEmail}}];\n} else {\n  return []; // Skip if already in the sheet\n}"
      },
      "typeVersion": 2
    },
    {
      "id": "7eb58195-bbaf-479b-83b9-2cf31323d6b4",
      "name": "IF IT ALREADY EXISTS, DO NOTHING",
      "type": "n8n-nodes-base.if",
      "position": [
        1088,
        224
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.Email }}",
              "rightValue": "={{ $('Get unsubscribe sheet').item.json.EMAIL }}"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "4b885ba7-1ef6-4393-a91f-bf881c9f90ce",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1312,
        -384
      ],
      "parameters": {
        "width": 816,
        "height": 1168,
        "content": "## UNSUBSCRIBE MANAGER\n**This workflow helps manage your leads and email deliverability health by removing contacts that have unsubscribed from your outreach list automatically.**\n\n\n\n**Who is this for?**\nFor marketers, freelancers, basically anyone that does lead generation and outreach via emails and need to keep their list clean and email deliverability healthy and strong.\n\n\n\n\n**How it works**\nThis works in 6 simple steps; starting from receiving an email to the AI node -> to automatically reading the content and determining if the prospect is interested or needs to be removed from your list---> to finally removing from your main sheet and adding an unsubscribe tag to that contact in your Gmail.\n\n\n**More Info**\n\n**Step 3**\nHere is the prompt to be used in the AI node; this can be edited.\n\n**AI PROMPT**\n_You are a message intent detector for outreach emails._\n_Your job is to determine if this message means the sender wants to stop receiving emails or unsubscribe._\n\n_Reply strictly with one word:_\n_- \"unsubscribe\" → if they indicate they don't want further contact (even indirectly)_\n_- \"keep\" → if they are interested, neutral, or unrelated._\n\n_Message:_\n_{{ $json.snippet }}_\n\nThe {{ $json.snippet }} is gotten from the Gmail node.\n\n\n**NORMALIZE AI OUTPUT**\nWe can't always trust the response of AI, so the **_Normalize AI Output_** node is a safe guard to ensure the two words we need are strictly passed on to the next node. The code is in the node.\n\n   \n\n**Steps 4&5**\n\n**IS EMAIL THERE?**\nThis checks the email from Gmail against your unsubscribe sheet to ensure it isn't already there. The code is in the node. This is one way of doing the checks, the other simple way is using the _IF_ node as was used in the _CHECK MAIN SHEET_ node.\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "b5ba836c-2941-446f-a3ed-32359fc06f25",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -144,
        -48
      ],
      "parameters": {
        "color": 7,
        "width": 336,
        "height": 432,
        "content": "## Step 2 (Optional)\n**Exclude any emails you usually receive/personal emails.** \n"
      },
      "typeVersion": 1
    },
    {
      "id": "7e74f9e0-7764-4404-8d28-08e2db82f295",
      "name": "No Operation, do nothing",
      "type": "n8n-nodes-base.noOp",
      "position": [
        1552,
        144
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "65a72f4e-b85b-4b7d-b191-601a3a2a53fd",
      "name": "No Operation, do nothing1",
      "type": "n8n-nodes-base.noOp",
      "position": [
        944,
        576
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "74e491a2-322b-4558-89d6-c78b9e64bf47",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -480,
        -48
      ],
      "parameters": {
        "color": 7,
        "width": 288,
        "height": 432,
        "content": "## Step 1\n**GMAIL Trigger watches for new replies** "
      },
      "typeVersion": 1
    },
    {
      "id": "297fdd22-5c8a-4b39-841a-1a4429e77018",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        224,
        -48
      ],
      "parameters": {
        "color": 7,
        "width": 544,
        "height": 432,
        "content": "## Step 3\n**The AI checks the response and summaries in two words ** \"Unsubscribe\" or \"Keep\"  and ensures the output comes out as \"unsubscribe or keep** "
      },
      "typeVersion": 1
    },
    {
      "id": "77774adc-abc6-4302-97ec-12f3251ad204",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        800,
        -48
      ],
      "parameters": {
        "color": 7,
        "width": 720,
        "height": 432,
        "content": "## Step 4\n**If AI says \"unsubscribe\", check if the email is not already in the unsubscribe sheet and then add it.** "
      },
      "typeVersion": 1
    },
    {
      "id": "fe0a8ec7-b8de-4a77-9cd2-c4e500b44904",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        176,
        416
      ],
      "parameters": {
        "color": 7,
        "width": 448,
        "height": 352,
        "content": "## Step 5\n**Check and remove from the main sheet** "
      },
      "typeVersion": 1
    },
    {
      "id": "f37ebb6f-76ad-4b17-ac28-33bbaf17c170",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        704,
        416
      ],
      "parameters": {
        "color": 7,
        "width": 448,
        "height": 352,
        "content": "## Step 6\n**Add \"Unsubscribe\" tag to email on Gmail** "
      },
      "typeVersion": 1
    },
    {
      "id": "c4f3b118-d38c-4695-9dbe-82cb272cca95",
      "name": "UNSUBSCRIBE?",
      "type": "n8n-nodes-base.if",
      "position": [
        848,
        64
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "",
              "operator": {
                "name": "filter.operator.equals",
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.text }}",
              "rightValue": "unsubscribe"
            }
          ]
        }
      },
      "retryOnFail": true,
      "typeVersion": 2.2
    },
    {
      "id": "335c9d2d-022e-46a9-964a-9052c59f3c46",
      "name": "Personal Emails?",
      "type": "n8n-nodes-base.if",
      "position": [
        -64,
        160
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "",
              "operator": {
                "type": "string",
                "operation": "contains"
              },
              "leftValue": "={{ $json.From }}",
              "rightValue": "=your personal email"
            }
          ]
        },
        "looseTypeValidation": true
      },
      "retryOnFail": true,
      "typeVersion": 2.2
    }
  ],
  "active": false,
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "2468f2da-5bfe-4a8d-b9b0-48bb576eb2e5",
  "connections": {
    "UNSUBSCRIBE?": {
      "main": [
        [
          {
            "node": "Get unsubscribe sheet",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "No Operation, do nothing",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "DETECT INTENT": {
      "main": [
        [
          {
            "node": "NORMALIZE AI OUTPUT",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IS EMAIL THERE?": {
      "main": [
        [
          {
            "node": "IF IT ALREADY EXISTS, DO NOTHING",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "CHECK MAIN SHEET": {
      "main": [
        [
          {
            "node": "Delete rows or columns from sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Personal Emails?": {
      "main": [
        [
          {
            "node": "No Operation, do nothing",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "DETECT INTENT",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "DETECT INTENT",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Watch New replies": {
      "main": [
        [
          {
            "node": "Personal Emails?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "ADD TO UNSUBSCRIBE": {
      "main": [
        [
          {
            "node": "CHECK MAIN SHEET",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "NORMALIZE AI OUTPUT": {
      "main": [
        [
          {
            "node": "UNSUBSCRIBE?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get unsubscribe sheet": {
      "main": [
        [
          {
            "node": "IS EMAIL THERE?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "ADD UNSUBSCRIBE TO EMAIL": {
      "main": [
        [
          {
            "node": "No Operation, do nothing1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF IT ALREADY EXISTS, DO NOTHING": {
      "main": [
        [
          {
            "node": "No Operation, do nothing",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "ADD TO UNSUBSCRIBE",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Delete rows or columns from sheet": {
      "main": [
        [
          {
            "node": "ADD UNSUBSCRIBE TO EMAIL",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}