使用 IF 節點來傳送後續追蹤電郵

Hey Everyone

I’m currently building a workflow to send cold outreach to leads for my business. I’ve automated the initial email and follow-ups, but I want to include a way to stop the workflow if a lead responds to an email.

I’ve set up an IF node after my first ‘send a message’ node; With the true branch leading to an ‘Update Spreadsheet’ Node (for my crm tracker). The False branch leads a ‘Wait’ Node, before continuing with the rest of the sequence.

So far, I haven’t been able to get data through the false node (true node works fine). I’ve set the conditions to {{ $json.labelIds[0] }} is not equal to {{ $json.id }}. But I’m not sure how any actual data would get through, since the previous node is a ‘send message’ node and doesn’t actually have any data.

What’s the best way to get this sorted?

Full Code: {
“nodes”: [
{
“parameters”: {
“documentId”: {
“__rl”: true,
“value”: “1ELHPLTbzEpco28TT3ETagDNbISfOgxN7MTYnlqkKKec”,
“mode”: “list”,
“cachedResultName”: “Test Outreach”,
“cachedResultUrl”: “https://docs.google.com/spreadsheets/d/1ELHPLTbzEpco28TT3ETagDNbISfOgxN7MTYnlqkKKec/edit?usp=drivesdk
},
“sheetName”: {
“__rl”: true,
“value”: “gid=0”,
“mode”: “list”,
“cachedResultName”: “Sheet1”,
“cachedResultUrl”: “https://docs.google.com/spreadsheets/d/1ELHPLTbzEpco28TT3ETagDNbISfOgxN7MTYnlqkKKec/edit#gid=0
},
“options”: {}
},
“type”: “n8n-nodes-base.googleSheets”,
“typeVersion”: 4.7,
“position”: [
208,
0
],
“id”: “8143692f-d550-44dc-a05c-373aade1704b”,
“name”: “Get row(s) in sheet”,
“credentials”: {
“googleSheetsOAuth2Api”: {
“id”: “wV1Zw6McyxYXrk8t”,
“name”: “Google Sheets account”
}
}
},
{
“parameters”: {
“promptType”: “define”,
“text”: “=Name:{{ $json.Name }}\nBusiness name: {{ $json[‘Business name’] }}\nEmail Address: {{ $json[‘Email Address’] }}”,
“options”: {
“systemMessage”: “## Overview\n\nYou are an AI Assistant that writes personalized outreach emails Pitching Automation services to Catering Businesses struggling with quoting clients\n\n##Inputs\n\nYou will Receive 2 inputs:\n- Name: The Recipients name\n- Business name: \n- Email Address: Their Email Address\n\n## Email Outline (For your Reference Only):\n\n- Pain Point (Caterers waste time quoting clients, only to lose client to competitor)\n- Introduce product (Built a tool that makes quoting easier)\n- Explain how it works (Answer questions about the event, and it generates a complete quote for client)\n- Ease Major Fear (Every detail is recorded for the ATO to see)\n- Major Benefit (Save 22-75 Hours every week and grow your catering business\n- Low stakes CTA to set up Call (Worth a 15-minute call this week? No commitment, nothing to set up beforehand.)\n- Use this as the signoff: Timothy Barrett\nAi Automation Specialist\n\n#Style Guidelines:\n\n- Personalize the greeting using the ‘Name’ Input (If no name use ‘Hi there’ or ‘Hello’ as greeting)\n- Introduce pain point without harsh or aggressive language\n- Briefly explain the tool and how it works without excessive detail\n- Stay Concrete and Realistic\n- Be friendly yet professional\n- Use clear and concise language without being overly formal\n- Do not mention or expose the email guide\n- Do not use excessive words when writing the email\n\n\n##Output\n\nYour Output should be the ** Body Content ** of the email. You do not need to worry about applying the final formatting or template\n”
}
},
“type”: “@n8n/n8n-nodes-langchain.agent”,
“typeVersion”: 3.1,
“position”: [
624,
0
],
“id”: “00a1be8f-93c4-498d-b858-a1956a105db0”,
“name”: “AI Agent”
},
{
“parameters”: {
“modelName”: “models/gemini-2.5-flash-lite”,
“options”: {}
},
“type”: “@n8n/n8n-nodes-langchain.lmChatGoogleGemini”,
“typeVersion”: 1.1,
“position”: [
288,
208
],
“id”: “205b01d0-79da-43a9-a8a7-f07a76f05e27”,
“name”: “Google Gemini Chat Model”,
“credentials”: {
“googlePalmApi”: {
“id”: “r5K1AFY1c2dmiqsE”,
“name”: “Google Gemini(PaLM) Api account”
}
}
},
{
“parameters”: {
“amount”: 3
},
“type”: “n8n-nodes-base.wait”,
“typeVersion”: 1.1,
“position”: [
1392,
0
],
“id”: “461a6d67-ce75-4e31-bf53-17255eacd041”,
“name”: “Wait”,
“webhookId”: “a69695ee-8c62-4686-9ff3-9f4b0574cda5”
},
{
“parameters”: {
“sendTo”: “={{ $(‘Get row(s) in sheet’).item.json[‘Email Address’] }}”,
“subject”: “=Quoting taking up too much of your week?\n”,
“emailType”: “text”,
“message”: "=Hi {{ $(‘Get row(s) in sheet’).item.json.Name }}, Just floating this back to the top in case it got buried. One thing I didn’t mention — the setup takes less than a day, and you don’t need to change anything about how you currently run your business. Still happy to walk you through it in 15 minutes if you’re curious. No pressure either way. Timothy Barrett Ai Automation Specialist ",
“options”: {
“appendAttribution”: false
}
},
“type”: “n8n-nodes-base.gmail”,
“typeVersion”: 2.2,
“position”: [
1600,
0
],
“id”: “8d79ed17-ecdc-474a-9638-d4070c9086d0”,
“name”: “Send a message1”,
“webhookId”: “5734b9ce-7d99-47af-9fe6-d636654548eb”,
“credentials”: {
“gmailOAuth2”: {
“id”: “49vocCpyDoaHrQbO”,
“name”: “Gmail OAuth2 API”
}
}
},
{
“parameters”: {
“amount”: 4
},
“type”: “n8n-nodes-base.wait”,
“typeVersion”: 1.1,
“position”: [
1808,
0
],
“id”: “63bd0285-6fa9-41ef-8a17-ecd024589b9a”,
“name”: “Wait1”,
“webhookId”: “85d25d42-c881-4963-9f1d-69323af6e75e”
},
{
“parameters”: {
“sendTo”: “={{ $(‘Get row(s) in sheet’).item.json[‘Email Address’] }}”,
“subject”: “={{ $(‘Get row(s) in sheet’).item.json.Name }}, how are you going with Quotes?”,
“emailType”: “text”,
“message”: “=Hi {{ $(‘Get row(s) in sheet’).item.json.Name }}, I’ll keep this short — is quoting still something that eats into your week, or have you got it sorted? Either way is fine, just want to make sure I’m not sending you something that isn’t relevant. If it’s still an issue, I’m confident I can help. If not, no worries at all — I won’t keep following up. Timothy Barrett Ai Automation Specialist”,
“options”: {
“appendAttribution”: false
}
},
“type”: “n8n-nodes-base.gmail”,
“typeVersion”: 2.2,
“position”: [
2016,
0
],
“id”: “81296453-dd26-49c1-b286-3a3e9c6beb7f”,
“name”: “Send a message2”,
“webhookId”: “976d692c-e011-4425-b29c-e659e61a6eb9”,
“credentials”: {
“gmailOAuth2”: {
“id”: “49vocCpyDoaHrQbO”,
“name”: “Gmail OAuth2 API”
}
}
},
{
“parameters”: {
“amount”: 6
},
“type”: “n8n-nodes-base.wait”,
“typeVersion”: 1.1,
“position”: [
2224,
0
],
“id”: “53c37146-eaba-4ac2-ac26-503e17d10c32”,
“name”: “Wait2”,
“webhookId”: “a8618019-c757-4b7c-aa79-00442e27b40c”
},
{
“parameters”: {
“sendTo”: “={{ $(‘Get row(s) in sheet’).item.json[‘Email Address’] }}”,
“subject”: “=Last one from me — {{ $(‘Get row(s) in sheet’).item.json.Name }}”,
“emailType”: “text”,
“message”: “=Hi {{ $(‘Get row(s) in sheet’).item.json.Name }}, I’ve reached out a couple of times so I’ll leave it here — I don’t want to clog up your inbox. If quoting ever becomes a bigger headache down the track — especially heading into the warmer months — feel free to reach out. I’m easy to find. Wishing you all the best Timothy Barrett Ai Automation Specialist”,
“options”: {
“appendAttribution”: false
}
},
“type”: “n8n-nodes-base.gmail”,
“typeVersion”: 2.2,
“position”: [
2432,
0
],
“id”: “465af20d-a8af-4ad8-8b2e-be0c5e790771”,
“name”: “Send a message3”,
“webhookId”: “4167b770-e706-4909-a9e6-becef020a50d”,
“credentials”: {
“gmailOAuth2”: {
“id”: “49vocCpyDoaHrQbO”,
“name”: “Gmail OAuth2 API”
}
}
},
{
“parameters”: {
“conditions”: {
“options”: {
“caseSensitive”: true,
“leftValue”: “”,
“typeValidation”: “strict”,
“version”: 3
},
“conditions”: [
{
“id”: “9ffdfabb-151f-416f-89ae-683a22790b20”,
“leftValue”: “={{ $json.labelIds[2] }}”,
“rightValue”: “={{ $json.id }}”,
“operator”: {
“type”: “string”,
“operation”: “equals”
}
},
{
“id”: “caef476e-e11d-4497-9006-d978b8b8f4cf”,
“leftValue”: “={{ $json.labelIds[0] }}”,
“rightValue”: “={{ $json.id }}”,
“operator”: {
“type”: “string”,
“operation”: “notEquals”
}
}
],
“combinator”: “or”
},
“options”: {}
},
“type”: “n8n-nodes-base.if”,
“typeVersion”: 2.3,
“position”: [
1184,
16
],
“id”: “a4b40baf-79cc-4d5c-9e62-57c1461f0112”,
“name”: “If”
},
{
“parameters”: {},
“type”: “n8n-nodes-base.limit”,
“typeVersion”: 1,
“position”: [
416,
0
],
“id”: “2c86cfb2-11ca-49db-b379-2f66571a243b”,
“name”: “Limit”
},
{
“parameters”: {
“operation”: “appendOrUpdate”,
“documentId”: {
“__rl”: true,
“value”: “1ELHPLTbzEpco28TT3ETagDNbISfOgxN7MTYnlqkKKec”,
“mode”: “list”,
“cachedResultName”: “Test Outreach”,
“cachedResultUrl”: “https://docs.google.com/spreadsheets/d/1ELHPLTbzEpco28TT3ETagDNbISfOgxN7MTYnlqkKKec/edit?usp=drivesdk
},
“sheetName”: {
“__rl”: true,
“value”: “gid=0”,
“mode”: “list”,
“cachedResultName”: “Sheet1”,
“cachedResultUrl”: “https://docs.google.com/spreadsheets/d/1ELHPLTbzEpco28TT3ETagDNbISfOgxN7MTYnlqkKKec/edit#gid=0
},
“columns”: {
“mappingMode”: “defineBelow”,
“value”: {
“Response?”: “=Yes”
},
“matchingColumns”: [
“Response?”
],
“schema”: [
{
“id”: “Name”,
“displayName”: “Name”,
“required”: false,
“defaultMatch”: false,
“display”: true,
“type”: “string”,
“canBeUsedToMatch”: true,
“removed”: true
},
{
“id”: “Address”,
“displayName”: “Address”,
“required”: false,
“defaultMatch”: false,
“display”: true,
“type”: “string”,
“canBeUsedToMatch”: true,
“removed”: true
},
{
“id”: “Phone”,
“displayName”: “Phone”,
“required”: false,
“defaultMatch”: false,
“display”: true,
“type”: “string”,
“canBeUsedToMatch”: true,
“removed”: true
},
{
“id”: “Email Address”,
“displayName”: “Email Address”,
“required”: false,
“defaultMatch”: false,
“display”: true,
“type”: “string”,
“canBeUsedToMatch”: true,
“removed”: true
},
{
“id”: “Business name”,
“displayName”: “Business name”,
“required”: false,
“defaultMatch”: false,
“display”: true,
“type”: “string”,
“canBeUsedToMatch”: true,
“removed”: true
},
{
“id”: “Response?”,
“displayName”: “Response?”,
“required”: false,
“defaultMatch”: false,
“display”: true,
“type”: “string”,
“canBeUsedToMatch”: true,
“removed”: false
}
],
“attemptToConvertTypes”: false,
“convertFieldsToString”: false
},
“options”: {
“locationDefine”: {
“values”: {}
}
}
},
“type”: “n8n-nodes-base.googleSheets”,
“typeVersion”: 4.7,
“position”: [
1376,
-160
],
“id”: “beb247c7-0f55-459b-8e90-cb362efeb53a”,
“name”: “Append or update row in sheet”,
“credentials”: {
“googleSheetsOAuth2Api”: {
“id”: “wV1Zw6McyxYXrk8t”,
“name”: “Google Sheets account”
}
}
},
{
“parameters”: {
“sendTo”: “={{ $(‘Get row(s) in sheet’).item.json[‘Email Address’] }}”,
“subject”: “=Quote Solutions for {{ $(‘Get row(s) in sheet’).item.json[‘Business name’] }}”,
“message”: “={{ $json.output }}”,
“options”: {
“appendAttribution”: false
}
},
“type”: “n8n-nodes-base.gmail”,
“typeVersion”: 2.2,
“position”: [
976,
16
],
“id”: “22f734b7-a94f-438f-8cfc-c9874e260264”,
“name”: “Send a message”,
“webhookId”: “043fd017-dab8-4f3a-acf2-b162290745c7”,
“credentials”: {
“gmailOAuth2”: {
“id”: “49vocCpyDoaHrQbO”,
“name”: “Gmail OAuth2 API”
}
}
},
{
“parameters”: {},
“type”: “n8n-nodes-base.manualTrigger”,
“typeVersion”: 1,
“position”: [
0,
0
],
“id”: “08802300-d516-4322-b3d0-db5112774541”,
“name”: “When clicking ‘Execute workflow’”
}
],
“connections”: {
“Get row(s) in sheet”: {
“main”: [
[
{
“node”: “Limit”,
“type”: “main”,
“index”: 0
}
]
]
},
“AI Agent”: {
“main”: [
[
{
“node”: “Send a message”,
“type”: “main”,
“index”: 0
}
]
]
},
“Google Gemini Chat Model”: {
“ai_languageModel”: [
[
{
“node”: “AI Agent”,
“type”: “ai_languageModel”,
“index”: 0
}
]
]
},
“Wait”: {
“main”: [
[
{
“node”: “Send a message1”,
“type”: “main”,
“index”: 0
}
]
]
},
“Send a message1”: {
“main”: [
[
{
“node”: “Wait1”,
“type”: “main”,
“index”: 0
}
]
]
},
“Wait1”: {
“main”: [
[
{
“node”: “Send a message2”,
“type”: “main”,
“index”: 0
}
]
]
},
“Send a message2”: {
“main”: [
[
{
“node”: “Wait2”,
“type”: “main”,
“index”: 0
}
]
]
},
“Wait2”: {
“main”: [
[
{
“node”: “Send a message3”,
“type”: “main”,
“index”: 0
}
]
]
},
“If”: {
“main”: [
[
{
“node”: “Append or update row in sheet”,
“type”: “main”,
“index”: 0
}
],
[
{
“node”: “Wait”,
“type”: “main”,
“index”: 0
}
]
]
},
“Limit”: {
“main”: [
[
{
“node”: “AI Agent”,
“type”: “main”,
“index”: 0
}
]
]
},
“Send a message”: {
“main”: [
[
{
“node”: “If”,
“type”: “main”,
“index”: 0
}
]
]
},
“When clicking ‘Execute workflow’”: {
“main”: [
[
{
“node”: “Get row(s) in sheet”,
“type”: “main”,
“index”: 0
}
]
]
}
},
“pinData”: {},
“meta”: {
“templateCredsSetupCompleted”: true,
“instanceId”: “845031bfdb8f607d8c7ae907fb5de28c6fb4d0a8d0cd06c1a605d7c42f4018a9”
}
}

Tim,不要讓 reply-stop 分支依賴 Send Message 節點的輸出。保持原始 lead 行的活動狀態,然後在等待後執行一個單獨的收件匣/搜尋檢查,其鑰匙應為已傳送的執行緒/訊息或 lead 電子郵件地址。IF 應從該 reply-check 結果讀取,而不是從 send 節點讀取。

你現在用什麼來偵測回覆:透過執行緒/訊息 id 搜尋 Gmail、透過寄件者電子郵件搜尋 Gmail,還是只使用 send 輸出中的 labelIds 欄位?

我在我的 IF 節點的欄位中使用 Gmail 按訊息/對話串 ID 搜尋

這是正確的查詢方式。只將 Gmail 搜尋作為是/否檢查:找到匹配的執行緒/訊息 → 停止並更新追蹤器;無結果 → 繼續後續流程。

後續分支仍需攜帶原始的 Google Sheets 潛在客戶列。僅使用搜尋結果來決定停止/繼續,而非作為下一封電郵的資料來源。

基於 @oimrqs_ops 上面的說明——這是實際執行該操作的工作流程。

假分支沒有任何內容,因為 IF 在讀取傳送節點的輸出,當沒有回覆時,搜尋會傳回零個項目,所以其後的每個節點都會無聲地停止。兩件事結合在一起可以修正它:

  1. 決定要根據潛在客戶列,而不是根據搜尋結果,這樣正好一個項目會流過,潛在客戶的電子郵件會保留到後續分支中。
  2. 檢測實際的入站回覆,而不僅僅是執行緒中的任何訊息。Gmail 執行緒始終包含你自己已傳送的郵件,所以計算執行緒訊息會停止每個後續操作。搜尋 from:<lead> 只會匹配真正的回覆。

可匯入:

{
  "name": "followup-stop-on-reply",
  "nodes": [
    {
      "parameters": {},
      "id": "00000000-0000-4000-8000-000000000000",
      "name": "Run (replace with your schedule)",
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [
        180,
        320
      ]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "l1",
              "name": "email",
              "value": "=lead@example.com",
              "type": "string"
            },
            {
              "id": "l2",
              "name": "name",
              "value": "=Jane",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "id": "11111111-1111-4111-8111-111111111111",
      "name": "Lead (replace with your Sheet read)",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        400,
        320
      ]
    },
    {
      "parameters": {
        "resource": "message",
        "operation": "getAll",
        "returnAll": false,
        "limit": 10,
        "filters": {
          "q": "=from:{{ $json.email }} newer_than:30d"
        },
        "options": {}
      },
      "id": "22222222-2222-4222-8222-222222222222",
      "name": "Check For Reply",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.1,
      "position": [
        640,
        320
      ],
      "alwaysOutputData": true,
      "credentials": {
        "gmailOAuth2": {
          "id": "",
          "name": "Your Gmail account"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// 根據潛在客戶而不是根據搜尋輸出決定,所以一個項目始終流過
// 潛在客戶的電子郵件會保留到後續分支(破損的部分)。
// Gmail 查詢已經按 from:<lead> 篩選,所以任何傳回的訊息都是
// 入站回覆——你自己發送的郵件永遠不會被匹配(如果你只計算
// 執行緒訊息,那個陷阱會停止每個後續操作)。
const lead = $('Lead (replace with your Sheet read)').first().json;
const msgs = $('Check For Reply').all().map(i => i.json).filter(m => m && m.id);
const leadEmail = String(lead.email || '').toLowerCase();
const hasReply = leadEmail !== '' && msgs.some(m => String(m.From || m.from || leadEmail).toLowerCase().includes(leadEmail));
return [{ json: { email: lead.email, name: lead.name, hasReply, replies: msgs.length } }];"
      },
      "id": "33333333-3333-4333-8333-333333333333",
      "name": "Evaluate Reply",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        880,
        320
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "c1",
              "leftValue": "={{ $json.hasReply }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "44444444-4444-4444-8444-444444444444",
      "name": "Replied?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        1120,
        320
      ]
    },
    {
      "parameters": {
        "message": "潛在客戶已回覆——停止序列並在此更新你的 CRM。",
        "options": {}
      },
      "id": "55555555-5555-4555-8555-555555555555",
      "name": "Stop — update your CRM",
      "type": "n8n-nodes-base.noOp",
      "typeVersion": 1,
      "position": [
        1360,
        200
      ]
    },
    {
      "parameters": {
        "resource": "message",
        "operation": "send",
        "sendTo": "={{ $json.email }}",
        "subject": "=Quick follow-up, {{ $json.name }}",
        "message": "=Hi {{ $json.name }}, just following up on my last note.",
        "options": {}
      },
      "id": "66666666-6666-4666-8666-666666666666",
      "name": "Send Follow-up",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.1,
      "position": [
        1360,
        440
      ],
      "credentials": {
        "gmailOAuth2": {
          "id": "",
          "name": "Your Gmail account"
        }
      }
    }
  ],
  "connections": {
    "Run (replace with your schedule)": {
      "main": [
        [
          {
            "node": "Lead (replace with your Sheet read)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Lead (replace with your Sheet read)": {
      "main": [
        [
          {
            "node": "Check For Reply",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check For Reply": {
      "main": [
        [
          {
            "node": "Evaluate Reply",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Evaluate Reply": {
      "main": [
        [
          {
            "node": "Replied?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Replied?": {
      "main": [
        [
          {
            "node": "Stop — update your CRM",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Send Follow-up",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  }
}

「Check For Reply」搜尋 from:{{潛在客戶電子郵件}} newer_than:30d,Code 節點在潛在客戶上設定 hasReply 並保留電子郵件/名稱,然後 IF 停止或繼續。將第一個 Set 節點替換為你的 Sheet 讀取,將最後的 NoOp 替換為你的 CRM 更新。傳送節點仍然是繼續分支上的葉子。