{
  "id": "lSCiZfz9WhjHCeQg",
  "name": "Deal Escalation Risk Predictor copy",
  "tags": [],
  "nodes": [
    {
      "id": "bce6c7a7-7cf9-4f29-a2c3-814b75792b5e",
      "name": "Start Deal Risk Analysis",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        864,
        528
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "43efc2f8-7056-4083-a791-a521790ff537",
      "name": "Fetch Open Opportunities",
      "type": "n8n-nodes-base.salesforce",
      "position": [
        1120,
        432
      ],
      "parameters": {
        "limit": 10,
        "options": {
          "conditionsUi": {
            "conditionValues": []
          }
        },
        "resource": "opportunity",
        "operation": "getAll"
      },
      "credentials": {
        "salesforceOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "44fe6814-6372-4920-bc3e-79fd9701fc1b",
      "name": "Fetch Recent Activities (Last 30 Days)",
      "type": "n8n-nodes-base.salesforce",
      "position": [
        1120,
        624
      ],
      "parameters": {
        "query": "=SELECT Id, Subject, Status, Priority, WhatId \nFROM Task \nWHERE WhatId != NULL \nAND CreatedDate = LAST_N_DAYS:30",
        "resource": "search"
      },
      "credentials": {
        "salesforceOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "0fbf651c-d3d8-4734-a5fe-d59afab1347e",
      "name": "Map Opportunities with Activities",
      "type": "n8n-nodes-base.merge",
      "position": [
        1344,
        528
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "advanced": true,
        "joinMode": "enrichInput1",
        "mergeByFields": {
          "values": [
            {
              "field1": "Id",
              "field2": "WhatId"
            }
          ]
        }
      },
      "typeVersion": 3.2,
      "alwaysOutputData": true
    },
    {
      "id": "5226b08c-ea0d-4a15-a3bc-3ffbe7b0728c",
      "name": "Build Deal Context for Risk Analysis",
      "type": "n8n-nodes-base.code",
      "position": [
        1568,
        528
      ],
      "parameters": {
        "jsCode": "const dealsMap = {};\n\nfor (const item of $input.all()) {\n  const data = item.json;\n  const dealId = data.WhatId || data.Id;\n\n  if (!dealsMap[dealId]) {\n    dealsMap[dealId] = {\n      Id: dealId,\n      Amount: data.Amount || 0,\n      Probability: data.Probability || 0,\n      Type: data.Type || \"N/A\",\n      activities: [],\n      allActivitiesCompleted: true\n    };\n  }\n\n  if (data.Subject) {\n    dealsMap[dealId].activities.push({\n      subject: data.Subject,\n      status: data.Status,\n      priority: data.Priority\n    });\n\n    //  If ANY activity is not completed \u2192 false\n    if (data.Status !== \"Completed\") {\n      dealsMap[dealId].allActivitiesCompleted = false;\n    }\n  }\n}\n\nreturn Object.values(dealsMap).map(deal => ({ json: deal }));"
      },
      "typeVersion": 2
    },
    {
      "id": "5b7805ce-348c-4958-a624-7e368f43db76",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1024,
        256
      ],
      "parameters": {
        "color": 7,
        "width": 480,
        "height": 560,
        "content": "## Deal Data Intake & Activity Mapping\n\nFetches all open opportunities and recent activities from Salesforce, then merges them to create a unified deal view. This ensures each deal is enriched with its latest engagement data for accurate risk analysis."
      },
      "typeVersion": 1
    },
    {
      "id": "676d002f-97f9-46cb-a30e-fee57556e4b4",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1536,
        256
      ],
      "parameters": {
        "color": 7,
        "width": 448,
        "height": 560,
        "content": "## Deal Context Building\n\nTransforms raw Salesforce data into structured deal objects by grouping activities per deal, calculating key attributes, and tracking whether all activities are completed. This prepares clean input for AI analysis."
      },
      "typeVersion": 1
    },
    {
      "id": "be12faf8-2779-4712-b8e7-6676d9e74039",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2016,
        256
      ],
      "parameters": {
        "color": 7,
        "width": 432,
        "height": 560,
        "content": "##  Smart Filtering & Batching\n\nFilters out fully safe deals (100% + active) and processes remaining deals in batches with delay to avoid API overload."
      },
      "typeVersion": 1
    },
    {
      "id": "7455c4a7-a5f2-4e91-bd7e-e3f91de7d3ab",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2496,
        256
      ],
      "parameters": {
        "color": 7,
        "width": 448,
        "height": 560,
        "content": "##  AI-Based Risk Prediction\n\nUses Google Gemini to evaluate each deal\u2019s risk level based on probability, activity engagement, and predefined business rules, returning a structured JSON risk assessment."
      },
      "typeVersion": 1
    },
    {
      "id": "5ce8b5d9-ceef-45c2-9baf-6a0c670d3467",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2976,
        256
      ],
      "parameters": {
        "color": 7,
        "width": 448,
        "height": 544,
        "content": "## AI Response Cleaning & Validation\n\n Cleans the AI output by removing formatting issues, parsing JSON safely, and validating risk levels to ensure consistent and reliable downstream processing."
      },
      "typeVersion": 1
    },
    {
      "id": "bcf5cfe9-92bc-4a63-afa2-04206a032ef6",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3472,
        256
      ],
      "parameters": {
        "color": 7,
        "width": 656,
        "height": 544,
        "content": "## High-Risk Detection & Escalation\n\nFilters only high-risk deals and updates Salesforce with risk insights, then sends a Slack alert to notify stakeholders for immediate action."
      },
      "typeVersion": 1
    },
    {
      "id": "e932dd6e-29e0-4165-9e4a-130a0a3fa120",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        0,
        0
      ],
      "parameters": {
        "width": 768,
        "height": 1104,
        "content": "# Deal Escalation Risk Predictor\n\n# How It Work\n\n###  This workflow automatically analyzes Salesforce deals to detect escalation risk using AI. It begins by fetching open opportunities and recent activities, then merges them to create a complete deal-level view. The workflow structures this data into a clean format, including deal value, probability, type, and engagement history.\n\n\n\n# Setup Steps\n\n## Configure Integrations\nConnect Salesforce, Google Gemini, and Slack in n8n.\n\n## Add Trigger\nUse a Manual Trigger .\n\n## Fetch & Merge Data\nRetrieve opportunities and recent activities, then merge them.\n\n## Build Deal Context\nStructure deal data with activity tracking and key fields.\n\n##  Filter & Batch Deals\nFilter safe deals and process remaining ones in batches with delay.\n\n\n## Run AI Analysis\nSend deal data to Gemini for risk prediction.\n\n## Validate Output\nClean and parse AI response into structured JSON.\n\n## Take Action\nUpdate high-risk deals in Salesforce and send Slack alerts."
      },
      "typeVersion": 1
    },
    {
      "id": "2c3afe12-7c5b-4e08-8cdf-f2229a8fcf4e",
      "name": "Filter: High Probability & Active Deals",
      "type": "n8n-nodes-base.if",
      "position": [
        2064,
        528
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "0280fb3e-8b1b-42cf-bf84-41b388148502",
              "operator": {
                "type": "number",
                "operation": "equals"
              },
              "leftValue": "={{ $json.Probability }}",
              "rightValue": 100
            },
            {
              "id": "928303af-1400-4ffd-9d77-53b0024ca05d",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json.activities }}",
              "rightValue": ""
            }
          ]
        },
        "looseTypeValidation": true
      },
      "typeVersion": 2.3
    },
    {
      "id": "2421d3e8-1446-4730-aa8b-1f50d786f695",
      "name": "Loop Over Opportunities",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        1792,
        528
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "5aff2e7a-0221-4dac-a71f-3bb5201ea378",
      "name": "Format Slack Alert Message",
      "type": "n8n-nodes-base.set",
      "position": [
        3728,
        544
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "c52a8cb6-f1fa-4a69-92b9-575dcd73d499",
              "name": "slackMessage",
              "type": "string",
              "value": "=*High Risk Alert*\n\n*Deal ID:* {{ $('Clean & Validate AI Response').item.json.deal_id }}\n*AI Summary:* {{ $('Clean & Validate AI Response').item.json.summary }}\n"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "19356d17-e83e-433e-a124-dc09199985f9",
      "name": "Check Risk level",
      "type": "n8n-nodes-base.if",
      "position": [
        3152,
        544
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "8bf48743-e697-4f5c-b94a-0042ae43e9ee",
              "operator": {
                "name": "filter.operator.equals",
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.risk_level }}",
              "rightValue": "high"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "c97e9511-d22b-4415-96df-7d46d1d2c338",
      "name": "Notify High Risk Deal",
      "type": "n8n-nodes-base.slack",
      "position": [
        3952,
        544
      ],
      "parameters": {
        "text": "={{ $json.slackMessage }}",
        "user": {
          "__rl": true,
          "mode": "list",
          "value": "U0AP3B0UTMH",
          "cachedResultName": "vishakag21"
        },
        "select": "user",
        "otherOptions": {},
        "authentication": "oAuth2"
      },
      "credentials": {
        "slackOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.4
    },
    {
      "id": "9dcfe5e7-31e5-408c-80a0-531456c391ce",
      "name": "Update High Risk Deal Flag",
      "type": "n8n-nodes-base.salesforce",
      "position": [
        3504,
        544
      ],
      "parameters": {
        "resource": "opportunity",
        "operation": "update",
        "updateFields": {
          "description": "=High Risk Deal Detected.\nDeal ID: {{ $('Prevent API Overload').item.json.Id }}\nRisk Level: {{ $json.risk_level }}\n\nSummary: {{ $json.summary }}\n\nPricing Risk: {{ $json.pricing_risk }}\nDelivery Risk: {{ $json.delivery_risk }}\nStakeholder Risk: {{ $json.stakeholder_risk }}"
        },
        "opportunityId": "={{ $('Prevent API Overload').item.json.Id }}"
      },
      "credentials": {
        "salesforceOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "6490bacd-d4a8-4012-803e-9217e418fe4e",
      "name": "Clean & Validate AI Response",
      "type": "n8n-nodes-base.code",
      "position": [
        2816,
        544
      ],
      "parameters": {
        "jsCode": "// Loop over all input items\nreturn $input.all().map(item => {\n  const raw = item.json.content?.parts?.[0]?.text;\n\n  // If no content at all\n  if (!raw) {\n    return { json: {\n      deal_id:\"null\",\n      risk_level: \"unknown\",\n      pricing_risk: false,\n      delivery_risk: false,\n      stakeholder_risk: false,\n      summary: \"No response received from AI model\",\n      parse_error: true\n    }};\n  }\n\n  // Remove ```json and ``` markdown fences\n  const cleaned = raw\n    .replace(/```json/gi, '')\n    .replace(/```/g, '')\n    .trim();\n\n  try {\n    const parsed = JSON.parse(cleaned);\n\n    // Validate expected fields exist\n    const validLevels = [\"high\", \"medium\", \"low\"];\n    if (!validLevels.includes(parsed.risk_level)) {\n      parsed.risk_level = \"unknown\";\n      parsed.parse_error = true;\n      parsed.summary = parsed.summary || \"AI returned invalid risk level\";\n    }\n\n    return { json: parsed };\n\n  } catch (err) {\n    // AI response could not be parsed\n    return { json: {\n      risk_level: \"unknown\",\n      pricing_risk: false,\n      delivery_risk: false,\n      stakeholder_risk: false,\n      summary: \"AI response could not be parsed\",\n      parse_error: true,\n      raw_response: raw.slice(0, 300) // first 300 chars for debugging\n    }};\n  }\n});"
      },
      "typeVersion": 2
    },
    {
      "id": "0ed0f72f-56cf-43fd-b6d5-e1203f1151a2",
      "name": "Predict Deal Escalation Risk",
      "type": "@n8n/n8n-nodes-langchain.googleGemini",
      "position": [
        2496,
        560
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "models/gemini-2.5-flash",
          "cachedResultName": "models/gemini-2.5-flash"
        },
        "options": {},
        "messages": {
          "values": [
            {
              "content": "=You are a Senior Sales Risk Analyst.\n\nAnalyze the following Salesforce deal and determine if it is at risk of escalation.\n\nConsider:\n- Low probability deals (below 40% is concerning)\n- Lack of recent or meaningful activities\n- Type of customer (new vs existing)\n- Engagement quality (number and type of activities)\n\nDeal Details:\n- Deal ID: {{ $json.Id }}\n- Amount: {{ $json.Amount }}\n- Probability: {{ $json.Probability }}%\n- Type: {{ $json.Type }}\n- Activity Count: {{ $json.activities.length }}\n\nActivities:\n{{ JSON.stringify($json.activities) }}\n\nInstructions:\n- Assess overall risk level (high, medium, low)\n- Identify specific risks: pricing_risk, delivery_risk, stakeholder_risk\n- Provide a short, clear one-line summary explaining the reason\n\nOutput Rules:\n- Return ONLY valid JSON \u2014 no markdown fences, no explanation outside JSON\n- Use this exact format:\n\n{\n  \"deal_id\": \"{{ $json.Id }}\",\n  \"risk_level\": \"high | medium | low\",\n  \"pricing_risk\": true | false,\n  \"delivery_risk\": true | false,\n  \"stakeholder_risk\": true | false,\n  \"summary\": \"one concise sentence explaining the risk\"\n}\n\nYou are a rule-based system.\n\nRULES:\n1. If Probability = 100 AND allActivitiesCompleted = true \u2192 LOW risk\n2. If Probability < 30 \u2192 HIGH risk\n3. Else \u2192 MEDIUM risk\n4.If risk_level = high \u2192 at least one of (pricing_risk, delivery_risk, stakeholder_risk) MUST be true.\n\nDO NOT break rules.\n\nReturn JSON only."
            }
          ]
        },
        "builtInTools": {}
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "executeOnce": false,
      "retryOnFail": false,
      "typeVersion": 1.1
    },
    {
      "id": "d8ebae26-a386-4a70-bd32-cd1439f1728c",
      "name": "Prevent API Overload",
      "type": "n8n-nodes-base.wait",
      "position": [
        2304,
        544
      ],
      "parameters": {
        "amount": 3
      },
      "retryOnFail": true,
      "typeVersion": 1.1
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "availableInMCP": false,
    "executionOrder": "v1"
  },
  "versionId": "e39eecf7-ec94-478d-9bf6-390af53f8f53",
  "connections": {
    "Check Risk level": {
      "main": [
        [
          {
            "node": "Update High Risk Deal Flag",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Loop Over Opportunities",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prevent API Overload": {
      "main": [
        [
          {
            "node": "Predict Deal Escalation Risk",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Notify High Risk Deal": {
      "main": [
        [
          {
            "node": "Loop Over Opportunities",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Opportunities": {
      "main": [
        [],
        [
          {
            "node": "Filter: High Probability & Active Deals",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Open Opportunities": {
      "main": [
        [
          {
            "node": "Map Opportunities with Activities",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Start Deal Risk Analysis": {
      "main": [
        [
          {
            "node": "Fetch Open Opportunities",
            "type": "main",
            "index": 0
          },
          {
            "node": "Fetch Recent Activities (Last 30 Days)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Slack Alert Message": {
      "main": [
        [
          {
            "node": "Notify High Risk Deal",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update High Risk Deal Flag": {
      "main": [
        [
          {
            "node": "Format Slack Alert Message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Clean & Validate AI Response": {
      "main": [
        [
          {
            "node": "Check Risk level",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Predict Deal Escalation Risk": {
      "main": [
        [
          {
            "node": "Clean & Validate AI Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Map Opportunities with Activities": {
      "main": [
        [
          {
            "node": "Build Deal Context for Risk Analysis",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Deal Context for Risk Analysis": {
      "main": [
        [
          {
            "node": "Loop Over Opportunities",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Recent Activities (Last 30 Days)": {
      "main": [
        [
          {
            "node": "Map Opportunities with Activities",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Filter: High Probability & Active Deals": {
      "main": [
        [],
        [
          {
            "node": "Prevent API Overload",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}