Using IF node to send follow up emails

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, do not make the reply-stop branch depend on the Send Message node output. Keep the original lead row alive, then after the wait run a separate inbox/search check keyed to the sent thread/message or the lead email address. The IF should read from that reply-check result, not from the send node.

What are you using to detect replies right now: Gmail search by thread/message id, Gmail search by sender email, or only the labelIds field from the send output?

I’m using the Gmail Search by Message/Thread ID in the fields for my IF node

That is the right lookup. Treat the Gmail Search as a yes/no check only: matching thread/message found → stop and update the tracker; no result → continue the follow-up path.

The follow-up branch still needs to carry the original Google Sheets lead row. Use the search result only to decide stop/continue, not as the data source for the next email.

Building on what @oimrqs_ops laid out above — here’s the actual workflow that does it.

The false branch gets nothing because the IF is reading the send node’s output, and when there’s no reply the search returns zero items, so every node after it silently stops. Two things fix it together:

  1. Decide on the lead row, not on the search result, so exactly one item always flows through and the lead’s email survives into the follow-up branch.
  2. Detect an actual inbound reply, not just any message in the thread. A Gmail thread always contains your own sent mail, so counting thread messages would stop every follow-up. Searching from:<lead> only matches a real reply.

Import-ready:

“Check For Reply” searches from:{{lead email}} newer_than:30d, the Code node sets hasReply on the lead and keeps email/name, then the IF stops or continues. Swap the first Set node for your Sheet read and the last NoOp for your CRM update. The send node stays a leaf on the continue branch.