AutomationFlowsAI & RAG › Revenue Ops CRM Sync and Enrichment

Revenue Ops CRM Sync and Enrichment

Revenue Ops CRM Sync and Enrichment. Uses hubspot, agent, lmChatOpenAi, notion. Scheduled trigger; 14 nodes.

Cron / scheduled trigger★★★★☆ complexityAI-powered14 nodesHubSpotAgentOpenAI ChatNotionSlackGmail
AI & RAG Trigger: Cron / scheduled Nodes: 14 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow follows the Agent → 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 →

Download .json
{
  "name": "Revenue Ops CRM Sync and Enrichment",
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "03e50be0-bd1f-4444-8912-a426aa3efb76",
  "nodes": [
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "hours",
              "hoursInterval": 6
            }
          ]
        }
      },
      "id": "six_hour_trigger",
      "name": "6 Hour Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1,
      "position": [
        220,
        320
      ]
    },
    {
      "parameters": {
        "resource": "deal",
        "operation": "search",
        "additionalFields": {}
      },
      "id": "hubspot_search_deals",
      "name": "HubSpot Search Deals",
      "type": "n8n-nodes-base.hubspot",
      "typeVersion": 2.2,
      "position": [
        470,
        320
      ]
    },
    {
      "parameters": {
        "jsCode": "return $input.all().map((item) => {\n  const daysInStage = Number(item.json.daysInStage || item.json.stageAgeDays || 18);\n  const amount = Number(item.json.amount || item.json.dealValue || 12000);\n\n  let deterministicScore = 30;\n  if (daysInStage > 14) deterministicScore += 25;\n  if (daysInStage > 30) deterministicScore += 20;\n  if (amount >= 10000) deterministicScore += 15;\n\n  return {\n    json: {\n      ...item.json,\n      deterministicScore,\n      daysInStage,\n      amount,\n    },\n  };\n});"
      },
      "id": "deterministic_deal_risk",
      "name": "Deterministic Deal Risk",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        700,
        320
      ]
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "={{'You assess revenue pipeline slippage. Return strict JSON with keys aiScore (0-100), priority (at_risk|healthy), summary (string). Deal payload: ' + JSON.stringify($json)}}",
        "options": {}
      },
      "id": "ai_deal_risk_agent",
      "name": "AI Deal Risk Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "typeVersion": 3.1,
      "position": [
        940,
        220
      ]
    },
    {
      "parameters": {
        "model": {
          "mode": "list",
          "value": "gpt-4.1-mini"
        },
        "options": {}
      },
      "id": "openai_chat_model",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "typeVersion": 1.3,
      "position": [
        940,
        520
      ]
    },
    {
      "parameters": {
        "jsCode": "return $input.all().map((item) => {\n  const rawCandidate =\n    item.json.output ??\n    item.json.text ??\n    item.json.response ??\n    item.json.result ??\n    item.json;\n\n  let parsed = {};\n\n  if (typeof rawCandidate === 'string') {\n    try {\n      parsed = JSON.parse(rawCandidate);\n    } catch (error) {\n      parsed = { summary: rawCandidate };\n    }\n  } else if (rawCandidate && typeof rawCandidate === 'object') {\n    parsed = rawCandidate;\n  }\n\n  const pickNumber = (...keys) => {\n    for (const key of keys) {\n      const value = Number(parsed[key]);\n      if (Number.isFinite(value) && value > 0) return value;\n    }\n    return 0;\n  };\n\n  const pickString = (...keys) => {\n    for (const key of keys) {\n      const value = parsed[key];\n      if (typeof value === 'string' && value.trim()) return value.trim();\n    }\n    return '';\n  };\n\n  return {\n    json: {\n      aiScore: pickNumber('aiScore', 'score', 'riskScore', 'severityScore', 'readinessScore'),\n      aiPriority: pickString('priority', 'queue', 'recommendation', 'decision'),\n      aiSummary: pickString('summary', 'rationale', 'reason', 'triageSummary', 'recommendation') || 'ai_response_unavailable',\n      aiPayload: parsed,\n    },\n  };\n});"
      },
      "id": "parse_ai_output",
      "name": "Parse AI Output",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1160,
        220
      ]
    },
    {
      "parameters": {
        "mode": "combine"
      },
      "id": "merge_ai_with_rules",
      "name": "Merge AI with Rules",
      "type": "n8n-nodes-base.merge",
      "typeVersion": 3,
      "position": [
        1160,
        360
      ]
    },
    {
      "parameters": {
        "jsCode": "return $input.all().map((item) => {\n  const deterministicScore = Number(item.json.deterministicScore || 0);\n  const aiScore = Number(item.json.aiScore || 0);\n  const dealRiskScore = aiScore > 0\n    ? Math.round((deterministicScore * 0.65) + (aiScore * 0.35))\n    : deterministicScore;\n\n  const health = dealRiskScore >= 70 ? 'at_risk' : 'healthy';\n\n  return {\n    json: {\n      ...item.json,\n      dealRiskScore,\n      health,\n      riskSummary: item.json.aiSummary || 'deterministic fallback used',\n    },\n  };\n});"
      },
      "id": "final_deal_decision",
      "name": "Final Deal Decision",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1380,
        360
      ]
    },
    {
      "parameters": {
        "resource": "contact",
        "operation": "upsert",
        "email": "={{\"owner@example.com\"}}",
        "additionalFields": {}
      },
      "id": "hubspot_sync_owner_contact",
      "name": "HubSpot Sync Owner Contact",
      "type": "n8n-nodes-base.hubspot",
      "typeVersion": 2.2,
      "position": [
        1600,
        480
      ]
    },
    {
      "parameters": {
        "conditions": {
          "number": [
            {
              "value1": "={{$json.dealRiskScore}}",
              "operation": "largerEqual",
              "value2": 70
            }
          ]
        }
      },
      "id": "at_risk_check",
      "name": "At Risk Deal?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        1600,
        320
      ]
    },
    {
      "parameters": {
        "resource": "databasePage",
        "operation": "create",
        "databaseId": {
          "mode": "url",
          "value": "https://www.notion.so/00000000000000000000000000000000"
        },
        "title": "={{\"RevOps: \" + ($json.health || \"healthy\") + \" | score \" + ($json.dealRiskScore || 0)}}",
        "simple": true
      },
      "id": "notion_revops_log",
      "name": "Notion RevOps Log",
      "type": "n8n-nodes-base.notion",
      "typeVersion": 2.2,
      "position": [
        1820,
        360
      ]
    },
    {
      "parameters": {
        "resource": "message",
        "operation": "post",
        "select": "channel",
        "channelId": {
          "mode": "id",
          "value": "C01234567"
        },
        "messageType": "text",
        "text": "={{\"\ud83d\udea8 At-risk deal detected | score \" + ($json.dealRiskScore || 0) + \" | days \" + ($json.daysInStage || 0)}}"
      },
      "id": "slack_at_risk_alert",
      "name": "Slack At Risk Alert",
      "type": "n8n-nodes-base.slack",
      "typeVersion": 2.4,
      "position": [
        1820,
        180
      ]
    },
    {
      "parameters": {
        "resource": "message",
        "operation": "post",
        "select": "channel",
        "channelId": {
          "mode": "id",
          "value": "C01234567"
        },
        "messageType": "text",
        "text": "={{\"\u2705 Deal health normal | score \" + ($json.dealRiskScore || 0)}}"
      },
      "id": "slack_healthy_update",
      "name": "Slack Healthy Update",
      "type": "n8n-nodes-base.slack",
      "typeVersion": 2.4,
      "position": [
        1820,
        540
      ]
    },
    {
      "parameters": {
        "resource": "message",
        "operation": "send",
        "sendTo": "={{\"owner@example.com\"}}",
        "subject": "RevOps Deal Health Summary",
        "message": "={{\"Health: \" + ($json.health || \"healthy\") + \"\\nScore: \" + ($json.dealRiskScore || 0) + \"\\nSummary: \" + ($json.riskSummary || \"N/A\")}}"
      },
      "id": "gmail_revops_summary",
      "name": "Gmail RevOps Summary",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.2,
      "position": [
        2050,
        360
      ]
    }
  ],
  "connections": {
    "6 Hour Trigger": {
      "main": [
        [
          {
            "node": "HubSpot Search Deals",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HubSpot Search Deals": {
      "main": [
        [
          {
            "node": "Deterministic Deal Risk",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Deterministic Deal Risk": {
      "main": [
        [
          {
            "node": "AI Deal Risk Agent",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Merge AI with Rules",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Deal Risk Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "AI Deal Risk Agent": {
      "main": [
        [
          {
            "node": "Parse AI Output",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse AI Output": {
      "main": [
        [
          {
            "node": "Merge AI with Rules",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Merge AI with Rules": {
      "main": [
        [
          {
            "node": "Final Deal Decision",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Final Deal Decision": {
      "main": [
        [
          {
            "node": "At Risk Deal?",
            "type": "main",
            "index": 0
          },
          {
            "node": "HubSpot Sync Owner Contact",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "At Risk Deal?": {
      "main": [
        [
          {
            "node": "Slack At Risk Alert",
            "type": "main",
            "index": 0
          },
          {
            "node": "Notion RevOps Log",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Slack Healthy Update",
            "type": "main",
            "index": 0
          },
          {
            "node": "Notion RevOps Log",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Notion RevOps Log": {
      "main": [
        [
          {
            "node": "Gmail RevOps Summary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Pro

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

About this workflow

Revenue Ops CRM Sync and Enrichment. Uses hubspot, agent, lmChatOpenAi, notion. Scheduled trigger; 14 nodes.

Source: https://github.com/JefferyAddaeSecB/n8n-revenue-ops-crm-sync/blob/d5353d2bd59cb3f8fe0bd376f5f580f6e6246104/n8n/workflow.json — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

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

AI & RAG

This workflow is designed for Customer Success Managers and Sales Teams who manage high-volume pipelines in HubSpot. If you have prospects who stop responding after the contract is sent, this automati

HubSpot, Agent, OpenAI Chat +3
AI & RAG

This workflow helps sales teams automatically monitor deal health and detect risks early.

HubSpot, Gmail, Agent +3
AI & RAG

This n8n template demonstrates how to use AI to triage LinkedIn emails in your Gmail inbox, so you only see the messages worth your time. It filters out automated noise, scores sales likelihood, draft

Output Parser Structured, OpenAI Chat, Gmail +3
AI & RAG

Created by: Peyton Leveillee Last updated: October 2025

OpenAI Chat, Google Sheets, HTTP Request +5
AI & RAG

This workflow automates customer outreach for marketing campaigns, including customer prioritization, AI-generated emails, automated sending, reply tracking, and meeting scheduling. Data Synchronizati

Agent, Data Table, OpenAI Chat +6