Usar el nodo IF para enviar correos electrónicos de seguimiento

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, no hagas que la rama reply-stop dependa de la salida del nodo Send Message. Mantén viva la fila original, luego después de la espera ejecuta una búsqueda de inbox/search separada usando como clave el hilo/mensaje enviado o la dirección de correo del lead. El IF debe leer del resultado del reply-check, no del nodo de envío.

¿Qué estás usando para detectar respuestas en este momento: búsqueda en Gmail por id de hilo/mensaje, búsqueda en Gmail por correo del remitente, o solo el campo labelIds de la salida del envío?

Estoy usando la búsqueda de Gmail por ID de mensaje/hilo en los campos de mi nodo IF

Esa es la búsqueda correcta. Trata la búsqueda de Gmail como una verificación de sí/no solamente: hilo/mensaje coincidente encontrado → detente y actualiza el rastreador; sin resultado → continúa la ruta de seguimiento.

La rama de seguimiento aún necesita llevar la fila de cliente original de Google Sheets. Usa el resultado de búsqueda solo para decidir detener/continuar, no como fuente de datos para el siguiente correo electrónico.

Basándome en lo que @oimrqs_ops expuso arriba, aquí está el flujo de trabajo real que lo hace.

La rama falsa no obtiene nada porque el IF está leyendo la salida del nodo de envío, y cuando no hay respuesta la búsqueda devuelve cero elementos, así que cada nodo después de él se detiene silenciosamente. Dos cosas lo arreglan juntas:

  1. Decidir sobre la fila de contacto, no sobre el resultado de la búsqueda, así exactamente un elemento siempre fluye a través y el email del contacto sobrevive en la rama de seguimiento.
  2. Detectar una respuesta entrante real, no solo cualquier mensaje en el hilo. Un hilo de Gmail siempre contiene tu propio correo enviado, así que contar mensajes del hilo detendría cada seguimiento. Buscar from:<contacto> solo coincide con una respuesta real.

Listo para importar:

«Check For Reply» busca from:{{email del contacto}} newer_than:30d, el nodo Code establece hasReply en el contacto y mantiene email/name, luego el IF detiene o continúa. Reemplaza el primer nodo Set con tu lectura de Hojas y el último NoOp con tu actualización de CRM. El nodo de envío permanece como una rama final en la rama de continuación.