This workflow corresponds to n8n.io template #14803 — we link there as the canonical source.
This workflow follows the Chainllm → Gmail recipe pattern — see all workflows that pair these two integrations.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"id": "hcoLK6FM6m0dWzEt",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "Zoho CRM \u2013 Smart Follow-up Sequence Optimizer",
"tags": [],
"nodes": [
{
"id": "cb0333cd-4a41-497d-b9d6-40e1c2462d55",
"name": "Daily Follow-up Scan Trigger",
"type": "n8n-nodes-base.cron",
"position": [
-1232,
128
],
"parameters": {
"triggerTimes": {
"item": [
{
"hour": 9
}
]
}
},
"typeVersion": 1
},
{
"id": "ab540138-8943-40bf-a97f-7c258e908170",
"name": "Set Inactivity Cutoff Window",
"type": "n8n-nodes-base.set",
"position": [
-960,
128
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "c70f6b30-1700-4a4d-99c0-e2f7856db82d",
"name": "cutoffDate",
"type": "string",
"value": "={{ new Date(Date.now() - 7 * 24 * 60 * 60 * 1000)\n .toISOString()\n .slice(0,19) }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "7fbeda38-2029-4f30-b747-ba6263ccb92a",
"name": "Fetch Active Deals from Zoho CRM",
"type": "n8n-nodes-base.zohoCrm",
"position": [
-656,
128
],
"parameters": {
"options": {},
"resource": "deal",
"operation": "getAll",
"returnAll": true
},
"credentials": {
"zohoOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "d315bee6-ca1f-4aa2-812b-42d430df63c9",
"name": "Evaluate Follow-up Eligibility",
"type": "n8n-nodes-base.code",
"position": [
-352,
128
],
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "const d = $input.item.json;\nconst now = new Date();\n\nif (!d.Auto_Follow_up_Enabled) return { json: { due: false } };\nif (d.Follow_up_Status !== 'Pending') return { json: { due: false } };\nif (!d.Next_Follow_up_Due) return { json: { due: false } };\n\nconst dueDate = new Date(d.Next_Follow_up_Due);\n\nreturn {\n json: {\n due: dueDate <= now,\n dealId: d.id,\n dealName: d.Deal_Name,\n raw: d\n }\n};\n"
},
"typeVersion": 2
},
{
"id": "038a9003-4514-4dee-8a97-58967710e8f2",
"name": "Is Follow-up Due?",
"type": "n8n-nodes-base.if",
"position": [
-96,
128
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "35eb963a-29f4-40cb-8ca1-1ae2543927e1",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": "={{$json.due}}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2
},
{
"id": "d6ff28e0-0366-465c-be1a-2ad459745e4e",
"name": "Generate Personalized Follow-up (AI)",
"type": "@n8n/n8n-nodes-langchain.chainLlm",
"position": [
176,
112
],
"parameters": {
"text": "=You are a CRM assistant.\n\nGenerate a personalized follow-up message for this deal.\n\nDeal Name: {{ $json.dealName }}\nAccount: {{ $json.raw.Account_Name.name }}\nStage: {{ $json.raw.Stage }}\nLast Follow-up: {{ $json.raw.Last_Follow_up_At }}\n\nReturn ONLY valid JSON in the following format:\n\n{\n \"subject\": \"...\",\n \"message\": \"...\",\n \"channel\": \"email\",\n \"priority\": \"High\",\n \"next_action\": \"send_followup\"\n}\nReturn ONLY valid JSON.Do not add explanations.\nDo not add markdown.",
"batching": {},
"messages": {
"messageValues": [
{
"message": "You are a CRM follow-up assistant. Generate short, professional follow-up content. No emojis. No fluff. Business tone."
}
]
},
"promptType": "define",
"hasOutputParser": true
},
"typeVersion": 1.7
},
{
"id": "40c1b94a-2bcf-4b75-bff2-8d93753e78e0",
"name": "AI Model (Gemini)",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
64,
400
],
"parameters": {
"options": {}
},
"credentials": {
"googlePalmApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "abc3e871-197a-4b9f-885d-02f8c82b1edf",
"name": "Parse AI Response (Structured JSON)",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
416,
416
],
"parameters": {
"jsonSchemaExample": "{\n \"subject\": \"...\",\n \"message\": \"...\",\n \"channel\": \"email\",\n \"priority\": \"High\",\n \"next_action\": \"send_followup\"\n}"
},
"typeVersion": 1.3
},
{
"id": "d395128a-c3a3-4529-8b7c-ec0e32779752",
"name": "Decision Engine",
"type": "n8n-nodes-base.code",
"position": [
576,
112
],
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "// ----------------------------\n// INPUT DATA\n// ----------------------------\nconst deal = $('Is Follow-up Due?').item.json.raw;\nconst ai = $json.output || {};\n\n// ----------------------------\n// SAFE DATE RESOLUTION\n// ----------------------------\nconst lastActivityTime =\n deal.Last_Activity_Time ||\n deal.Last_Follow_up_At ||\n deal.Created_Time ||\n null;\n\nlet daysSinceLastActivity = null;\n\nif (lastActivityTime) {\n const lastActivity = new Date(lastActivityTime);\n daysSinceLastActivity = Math.floor(\n (Date.now() - lastActivity.getTime()) / (1000 * 60 * 60 * 24)\n );\n}\n\n// ----------------------------\n// FOLLOW-UP CHANNEL LOGIC\n// ----------------------------\n// Default from AI\nlet followUpType = ai.channel || \"email\";\n\n// Hard override based on inactivity\nif (daysSinceLastActivity !== null) {\n if (daysSinceLastActivity > 14) {\n followUpType = \"call\";\n } else if (daysSinceLastActivity > 7) {\n followUpType = \"whatsapp\";\n }\n}\n\n// ----------------------------\n// FINAL OUTPUT\n// ----------------------------\nreturn {\n ...$json,\n\n followUpDecision: {\n lastActivityTime,\n followUpType,\n daysSinceLastActivity,\n aiSuggestedChannel: ai.channel || null,\n priority: ai.priority || \"Normal\",\n nextAction: ai.next_action || null,\n }\n};\n"
},
"typeVersion": 2
},
{
"id": "8c5c7e59-c8df-4a73-bb70-b07e0a67b404",
"name": "Channel Routing",
"type": "n8n-nodes-base.switch",
"position": [
816,
96
],
"parameters": {
"rules": {
"values": [
{
"outputKey": "Email",
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "40039f9a-416b-4454-b096-781b1fe5851c",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.followUpDecision.followUpType }}",
"rightValue": "email"
}
]
},
"renameOutput": true
},
{
"outputKey": "slack",
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "0f314f51-a705-411a-87f4-f9d6c2e70e71",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.followUpDecision.followUpType }}",
"rightValue": "slack"
}
]
},
"renameOutput": true
},
{
"outputKey": "Whatsapp",
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "40c58835-3665-4dd2-a367-787c4b7f3165",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.followUpDecision.followUpType }}",
"rightValue": "whatsapp"
}
]
},
"renameOutput": true
}
]
},
"options": {},
"looseTypeValidation": true
},
"typeVersion": 3.3
},
{
"id": "5d333c39-d210-414d-a681-cb3b2d07607d",
"name": "Send follow-up email",
"type": "n8n-nodes-base.gmail",
"position": [
1184,
-112
],
"parameters": {
"sendTo": "=",
"message": "={{ $json.output.message }}",
"options": {},
"subject": "={{ $json.output.subject }}"
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "3a7706d5-f156-44fd-80f9-df6c137d6bd4",
"name": "Send Slack follow-up",
"type": "n8n-nodes-base.slack",
"position": [
1184,
112
],
"parameters": {
"text": "={{ $json.output.message }}",
"user": {
"__rl": true,
"mode": "id",
"value": "{userid}"
},
"select": "user",
"otherOptions": {},
"authentication": "oAuth2"
},
"credentials": {
"slackOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 2.3
},
{
"id": "97e22d0d-b75c-4419-857b-2b8d88824abb",
"name": "Send WhatsApp Follow-up",
"type": "n8n-nodes-base.whatsApp",
"position": [
1184,
336
],
"parameters": {
"textBody": "={{ $json.output.message }}",
"operation": "send",
"additionalFields": {}
},
"typeVersion": 1.1
},
{
"id": "f0e99c4d-e4a5-4fb4-be7e-641c5d87c637",
"name": "Create CRM Follow-up Task",
"type": "n8n-nodes-base.httpRequest",
"position": [
1568,
112
],
"parameters": {
"url": "https://www.zohoapis.com/crm/v2/Tasks",
"method": "POST",
"options": {},
"jsonBody": "={\n \"data\": [\n {\n \"Subject\": \"Follow-up: {{ $('Is Follow-up Due?').item.json.dealName }}\",\n \"Due_Date\": \"{{ new Date().toISOString().split('T')[0] }}\",\n \"Status\": \"Not Started\",\n \"Priority\": \"High\",\n \"What_Id\": \"{{ $('Is Follow-up Due?').item.json.dealId }}\",\n \"$se_module\": \"Deals\",\n \"Owner\": {\n \"id\": \"{{ $('Is Follow-up Due?').item.json.raw.Owner.id }}\"\n },\n \"Description\": \"Auto-generated follow-up task for overdue deal.\"\n }\n ]\n}\n",
"sendBody": true,
"specifyBody": "json",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "zohoOAuth2Api"
},
"credentials": {
"zohoOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.3
},
{
"id": "d066aebe-cce0-4013-a614-26bd844e0506",
"name": "Update Deal Follow-up Status",
"type": "n8n-nodes-base.zohoCrm",
"position": [
1840,
112
],
"parameters": {
"dealId": "={{ $('Is Follow-up Due?').item.json.dealId }}",
"resource": "deal",
"operation": "update",
"updateFields": {
"customFields": {
"customFields": [
{
"value": "Sent",
"fieldId": "Follow_up_Status"
}
]
}
}
},
"credentials": {
"zohoOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "13808eaa-1c8a-4dd5-baf6-87ba5ebd6fea",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1936,
-416
],
"parameters": {
"width": 560,
"height": 528,
"content": "## Zoho CRM \u2013 Smart Follow-up Sequence Optinizer\n**How it works** \nThis workflow runs weekly and Automatically detect inactive deals and trigger intelligent, AI-driven follow-ups across multiple channels to improve deal conversion and prevent pipeline leakage.\n\n**Setup steps**\n1. Configure Zoho CRM credentials in all Zoho nodes (OAuth2 recommended).\n\n2. Verify Deal Fields Mapping, Add Custom fields in Zoho Deal : Last Activity Time, Last Follow-up Date, Created Date\n\n3. Configure AI Node (OpenAI/Gemini)\n\n4. Validate Function Node logic: correctly calculates daysSinceLastActivity\n\n5. Set up Switch Node conditions : Email, WhatsApp,Slack or Call \n\n6. Configure Email, WhatsApp, Slack or Call credentials.\n\n7. Configure Zoho CRM Task Node"
},
"typeVersion": 1
},
{
"id": "8626a902-bf77-4179-86e1-f4b4020f456d",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1280,
-32
],
"parameters": {
"color": 7,
"width": 544,
"height": 384,
"content": "## Deal Data Collection\nTriggers the workflow on schedule and fetches active Deals from Zoo CRM for processing."
},
"typeVersion": 1
},
{
"id": "5bd8f0a6-988c-4c86-95bd-cd8ff99541d7",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
-704,
-32
],
"parameters": {
"color": 7,
"width": 720,
"height": 384,
"content": "## Deal Processing & Inactivity Detection\nSplits deals, calculates inactivity and filters only stalled deals that need follow-up."
},
"typeVersion": 1
},
{
"id": "b138be0c-8577-41a0-ad74-39101c6fbcff",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
80,
-32
],
"parameters": {
"color": 7,
"width": 624,
"height": 384,
"content": "## AI Evaluation & Follow-Up Decision\nSplits deals, calculates inactivity and filters only stalled deals that need follow-up."
},
"typeVersion": 1
},
{
"id": "da319c31-7549-46c7-b412-8681ee9cc4da",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
752,
-256
],
"parameters": {
"color": 7,
"width": 1296,
"height": 768,
"content": "## Channel Routing & CRM Actions\nRoutes deals to Email/WhatsApp/Call and creates alerts & CRM tasks for action."
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "8e83fce0-879c-4c96-9439-f87a00a6cfa8",
"connections": {
"Channel Routing": {
"main": [
[
{
"node": "Send follow-up email",
"type": "main",
"index": 0
}
],
[
{
"node": "Send Slack follow-up",
"type": "main",
"index": 0
}
],
[
{
"node": "Send WhatsApp Follow-up",
"type": "main",
"index": 0
}
]
]
},
"Decision Engine": {
"main": [
[
{
"node": "Channel Routing",
"type": "main",
"index": 0
}
]
]
},
"AI Model (Gemini)": {
"ai_languageModel": [
[
{
"node": "Generate Personalized Follow-up (AI)",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Is Follow-up Due?": {
"main": [
[
{
"node": "Generate Personalized Follow-up (AI)",
"type": "main",
"index": 0
}
],
[]
]
},
"Send Slack follow-up": {
"main": [
[
{
"node": "Create CRM Follow-up Task",
"type": "main",
"index": 0
}
]
]
},
"Send follow-up email": {
"main": [
[
{
"node": "Create CRM Follow-up Task",
"type": "main",
"index": 0
}
]
]
},
"Send WhatsApp Follow-up": {
"main": [
[
{
"node": "Create CRM Follow-up Task",
"type": "main",
"index": 0
}
]
]
},
"Create CRM Follow-up Task": {
"main": [
[
{
"node": "Update Deal Follow-up Status",
"type": "main",
"index": 0
}
]
]
},
"Daily Follow-up Scan Trigger": {
"main": [
[
{
"node": "Set Inactivity Cutoff Window",
"type": "main",
"index": 0
}
]
]
},
"Set Inactivity Cutoff Window": {
"main": [
[
{
"node": "Fetch Active Deals from Zoho CRM",
"type": "main",
"index": 0
}
]
]
},
"Update Deal Follow-up Status": {
"main": [
[]
]
},
"Evaluate Follow-up Eligibility": {
"main": [
[
{
"node": "Is Follow-up Due?",
"type": "main",
"index": 0
}
]
]
},
"Fetch Active Deals from Zoho CRM": {
"main": [
[
{
"node": "Evaluate Follow-up Eligibility",
"type": "main",
"index": 0
}
]
]
},
"Parse AI Response (Structured JSON)": {
"ai_outputParser": [
[
{
"node": "Generate Personalized Follow-up (AI)",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"Generate Personalized Follow-up (AI)": {
"main": [
[
{
"node": "Decision Engine",
"type": "main",
"index": 0
}
]
]
}
}
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
gmailOAuth2googlePalmApislackOAuth2ApizohoOAuth2Api
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow automatically detects inactive deals in Zoho CRM and triggers AI-driven follow-ups across multiple channels. It analyzes deal activity, determines the optimal follow-up method, generates personalized communication using AI, routes execution through…
Source: https://n8n.io/workflows/14803/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
Ai Price Tracker. Uses scheduleTrigger, httpRequest, markdown, chainLlm. Scheduled trigger; 42 nodes.
This comprehensive N8N automation template revolutionizes content creation by delivering a complete end-to-end solution for AI-powered blog generation. Transform simple ideas into fully SEO-optimized,
Content - Short Form News Script Generator. Uses httpRequest, s3, chainLlm, slack. Scheduled trigger; 45 nodes.
Automate your Bitcoin content pipeline by turning the latest CoinDesk headlines into structured Japanese summaries posted to Discord every six hours — completely hands-free. Who is this for Crypto tra
Test Webhooks in n8n Without Changing WEBHOOK_URL (PostBin & BambooHR Example). Uses manualTrigger, stickyNote, httpRequest, postBin. Event-driven trigger; 58 nodes.