AutomationFlowsCRM & Sales › Reply Triage Agent — Smartlead to Zoho

Reply Triage Agent — Smartlead to Zoho

Reply Triage Agent — Smartlead to Zoho. Uses httpRequest, gmail, slack, zohoCrm. Webhook trigger; 9 nodes.

Webhook trigger★★★★☆ complexity9 nodesHTTP RequestGmailSlackZoho Crm
CRM & Sales Trigger: Webhook Nodes: 9 Complexity: ★★★★☆ Added:

This workflow follows the Gmail → HTTP Request 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 →

Download .json
{
  "name": "Reply Triage Agent \u2014 Smartlead to Zoho",
  "nodes": [
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "smartlead-reply",
        "responseMode": "responseNode",
        "options": {}
      },
      "name": "Webhook: Smartlead Reply",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 1,
      "position": [
        240,
        300
      ]
    },
    {
      "parameters": {
        "functionCode": "// Extract fields from Smartlead payload into the shape Claude expects\nconst payload = $input.first().json;\nreturn [{\n  json: {\n    id: payload.reply_id || payload.id,\n    from: payload.from_email,\n    subject: payload.subject,\n    body: payload.reply_body || payload.body,\n    context: {\n      campaign: payload.campaign_name,\n      previous_touches: payload.previous_touches || 0,\n      last_touch_days_ago: payload.last_touch_days_ago || 0\n    }\n  }\n}];"
      },
      "name": "Normalize Reply Shape",
      "type": "n8n-nodes-base.function",
      "typeVersion": 1,
      "position": [
        460,
        300
      ]
    },
    {
      "parameters": {
        "url": "https://api.anthropic.com/v1/messages",
        "method": "POST",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "x-api-key",
              "value": "={{ $credentials.anthropicApi.apiKey }}"
            },
            {
              "name": "anthropic-version",
              "value": "2023-06-01"
            },
            {
              "name": "content-type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "bodyContentType": "json",
        "jsonBody": "={\n  \"model\": \"claude-sonnet-4-6\",\n  \"max_tokens\": 1024,\n  \"system\": \"You are a reply-triage agent. Output strict JSON matching the schema in prompt.md. Apply routing rules in order. Force human_review when confidence < 7.\",\n  \"messages\": [\n    {\n      \"role\": \"user\",\n      \"content\": {{ JSON.stringify($json) }}\n    }\n  ]\n}"
      },
      "name": "Claude: Classify Reply",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4,
      "position": [
        680,
        300
      ]
    },
    {
      "parameters": {
        "functionCode": "// Parse Claude response, validate schema, route on suggested_action\nconst claudeOutput = $input.first().json;\nconst rawText = claudeOutput.content[0].text;\nlet parsed;\ntry {\n  const match = rawText.match(/\\{[\\s\\S]*\\}/);\n  parsed = JSON.parse(match[0]);\n} catch (e) {\n  return [{ json: { error: 'unparseable', raw: rawText }, pairedItem: 0 }];\n}\n\nconst required = ['intent', 'confidence', 'suggested_action', 'crm_update', 'reasoning'];\nconst missing = required.filter(k => !(k in parsed));\nif (missing.length) {\n  return [{ json: { error: 'schema_violation', missing, parsed }, pairedItem: 0 }];\n}\n\n// Force human review on low confidence regardless of model output\nif (parsed.confidence < 7) {\n  parsed.suggested_action = 'human_review';\n  parsed.reasoning += ' [override: confidence below threshold]';\n}\n\nreturn [{ json: parsed }];"
      },
      "name": "Parse & Guardrail Output",
      "type": "n8n-nodes-base.function",
      "typeVersion": 1,
      "position": [
        900,
        300
      ]
    },
    {
      "parameters": {
        "dataType": "string",
        "value1": "={{ $json.suggested_action }}",
        "rules": {
          "rules": [
            {
              "value2": "auto_reply",
              "output": 0
            },
            {
              "value2": "human_review",
              "output": 1
            },
            {
              "value2": "crm_update_only",
              "output": 2
            },
            {
              "value2": "suppress",
              "output": 3
            }
          ]
        },
        "fallbackOutput": 1
      },
      "name": "Route by Action",
      "type": "n8n-nodes-base.switch",
      "typeVersion": 1,
      "position": [
        1120,
        300
      ]
    },
    {
      "parameters": {
        "operation": "create",
        "subject": "=Re: {{ $('Webhook: Smartlead Reply').first().json.subject }}",
        "to": "={{ $('Webhook: Smartlead Reply').first().json.from_email }}",
        "message": "={{ $json.draft_reply }}",
        "additionalFields": {
          "approvalRequired": true
        }
      },
      "name": "Draft Email (AE Approval)",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2,
      "position": [
        1360,
        180
      ]
    },
    {
      "parameters": {
        "channel": "#ae-review-queue",
        "text": "=:eyes: Reply needs review \u2014 {{ $('Webhook: Smartlead Reply').first().json.from_email }}\nIntent: {{ $json.intent }} | Confidence: {{ $json.confidence }}\nReason: {{ $json.reasoning }}\nThread: <link to Smartlead>"
      },
      "name": "Slack: Human Review Queue",
      "type": "n8n-nodes-base.slack",
      "typeVersion": 2,
      "position": [
        1360,
        300
      ]
    },
    {
      "parameters": {
        "operation": "update",
        "module": "Leads",
        "matchField": "Email",
        "matchValue": "={{ $('Webhook: Smartlead Reply').first().json.from_email }}",
        "updateFields": {
          "Lead_Status": "={{ $json.crm_update.stage }}",
          "Next_Follow_Up_Date": "={{ DateTime.now().plus({days: $json.crm_update.next_follow_up_days}).toISO() }}",
          "Last_Reply_Sentiment": "={{ $json.sentiment }}",
          "Last_Triage_Reasoning": "={{ $json.reasoning }}"
        }
      },
      "name": "Zoho CRM: Update Lead",
      "type": "n8n-nodes-base.zohoCrm",
      "typeVersion": 1,
      "position": [
        1360,
        420
      ]
    },
    {
      "parameters": {
        "operation": "update",
        "module": "Leads",
        "matchField": "Email",
        "matchValue": "={{ $('Webhook: Smartlead Reply').first().json.from_email }}",
        "updateFields": {
          "Lead_Status": "Unsubscribed",
          "Email_Opt_Out": true
        }
      },
      "name": "Zoho CRM: Suppress Lead",
      "type": "n8n-nodes-base.zohoCrm",
      "typeVersion": 1,
      "position": [
        1360,
        540
      ]
    }
  ],
  "connections": {
    "Webhook: Smartlead Reply": {
      "main": [
        [
          {
            "node": "Normalize Reply Shape",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Normalize Reply Shape": {
      "main": [
        [
          {
            "node": "Claude: Classify Reply",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Claude: Classify Reply": {
      "main": [
        [
          {
            "node": "Parse & Guardrail Output",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse & Guardrail Output": {
      "main": [
        [
          {
            "node": "Route by Action",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Route by Action": {
      "main": [
        [
          {
            "node": "Draft Email (AE Approval)",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Slack: Human Review Queue",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Zoho CRM: Update Lead",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Zoho CRM: Suppress Lead",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1",
    "saveExecutionProgress": true,
    "saveManualExecutions": true
  },
  "active": false,
  "versionId": "demo-v1"
}
Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

Reply Triage Agent — Smartlead to Zoho. Uses httpRequest, gmail, slack, zohoCrm. Webhook trigger; 9 nodes.

Source: https://github.com/saurabhshuklagrowisto/saurabh-ai-systems/blob/main/claude-skills/reply-triage-agent/n8n-workflow.json — original creator credit. Request a take-down →

More CRM & Sales workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

CRM & Sales

This workflow receives inbound leads via webhook, uses Anthropic Claude (with website scraping and web search) to score and classify them, then updates HubSpot lifecycle stage, creates deals for hot l

HTTP Request, HubSpot, Slack +1
CRM & Sales

This workflow receives inbound leads via webhook, validates and normalizes the data, scores and routes the lead to a sales rep, checks for duplicates and upserts the contact in HubSpot, drafts an outr

HubSpot, Slack, Gmail +2
CRM & Sales

This is ideal for agencies, freelancers, SaaS founders, and small sales teams who want every lead recorded and followed up automatically within seconds. The workflow supports two storage options: HubS

HTTP Request, Google Sheets, Slack +1
CRM & Sales

Real-Time Lead Processing - Captures and processes leads instantly from website forms with zero delay Intelligent Fit Scoring - Automatically scores leads 0-100 based on company size, seniority, and r

Clearbit, HubSpot, HTTP Request +3
CRM & Sales

This workflow receives B2B referral submissions via a webhook, validates the payload, emails the referrer and referred lead via Gmail, alerts the sales team in Slack, deduplicates and creates records

Gmail, Slack, HubSpot +1