{
  "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
          }
        ]
      ]
    }
  }
}