{
  "id": "JvFJ2REOLcJvdEj4",
  "name": "Dynamic Pricing Recommendation Engine",
  "tags": [],
  "nodes": [
    {
      "id": "ea82a0d5-48a5-4632-a249-c31d87113248",
      "name": "Main Sticky",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -16,
        208
      ],
      "parameters": {
        "width": 732,
        "height": 828,
        "content": "## Dynamic Pricing Recommendation Engine\n\nThis workflow automates intelligent pricing recommendations for Salesforce Quotes by combining historical deal analysis with AI-driven decision-making.\n\n### How it works:\n\nThe workflow is triggered via a webhook whenever a new Quote event is received. It fetches related Opportunity and Account details from Salesforce to build complete deal context. This data is normalized and enriched with attributes such as deal size, segment, and industry.\n\nNext, historical deal data is loaded from Google Sheets and filtered to identify the most relevant past deals. A benchmarking layer computes key metrics such as win rate, average discounts, and safe pricing ranges.\n\nThese insights are passed to an AI pricing strategist, which generates an optimal discount, final price, win probability, confidence level, and justification. The output is structured and validated before updating the Quote record in Salesforce.\n\nFinally, a Slack notification is sent with a summary of the pricing recommendation for visibility and collaboration.\n\n### Setup steps:\n1. Configure Webhook node and connect it with Salesforce Quote trigger\n2. Set up Salesforce OAuth2 credentials for Opportunity and Account nodes\n3. Connect Google Sheets and ensure historical deal dataset is structured correctly\n4. Configure Groq/OpenAI credentials for AI nodes\n5. Verify field mappings for Quote update (discount, price, probability, etc.)\n6. Configure Slack credentials and select target user/channel\n7. Test workflow with sample Quote payload"
      },
      "typeVersion": 1
    },
    {
      "id": "28381358-815a-4bab-b69f-43caadcdd4c6",
      "name": "Section 1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        752,
        464
      ],
      "parameters": {
        "color": 7,
        "width": 624,
        "height": 584,
        "content": "## Trigger & CRM Context\n\nCaptures incoming Quote events and enriches them with Opportunity and Account data from Salesforce. This step builds the foundational deal context including deal amount, stage, customer type, and industry required for pricing decisions."
      },
      "typeVersion": 1
    },
    {
      "id": "35964c89-a239-44d4-92c9-ef1ee82a281b",
      "name": "Section 2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1392,
        464
      ],
      "parameters": {
        "color": 7,
        "width": 432,
        "height": 584,
        "content": "## Data Preparation & Enrichment\n\nTransforms raw CRM data into a structured format and loads historical deal records from Google Sheets. This prepares clean, consistent input for downstream analysis and AI processing."
      },
      "typeVersion": 1
    },
    {
      "id": "7210c96b-08c8-4373-8fd5-3f813db8aae4",
      "name": "Section 3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1840,
        464
      ],
      "parameters": {
        "color": 7,
        "width": 416,
        "height": 584,
        "content": "## Feature Engineering & Benchmarking\n\nFilters and ranks historical deals based on similarity to the current deal. Calculates win rates, discount trends, and safe pricing ranges to establish a strong analytical baseline."
      },
      "typeVersion": 1
    },
    {
      "id": "cab20aae-b5a4-4bcb-9c1f-ef5062b99f00",
      "name": "Section 4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2272,
        464
      ],
      "parameters": {
        "color": 7,
        "width": 384,
        "height": 584,
        "content": "## AI Pricing Decision Engine\n\nUses AI to generate optimized pricing recommendations by combining deal context and historical insights. Outputs discount, final price, win probability, confidence level, and detailed justification."
      },
      "typeVersion": 1
    },
    {
      "id": "2da09dde-65f8-4056-9693-312b36fed7f4",
      "name": "Section 5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2672,
        464
      ],
      "parameters": {
        "color": 7,
        "width": 916,
        "height": 584,
        "content": "## Execution, Update & Notification\n\nFormats AI output, updates Salesforce Quote fields, and sends a Slack notification. Ensures the recommendation is actionable, recorded, and communicated to stakeholders."
      },
      "typeVersion": 1
    },
    {
      "id": "40dc8a05-d918-4286-9a6f-505d2d28dd42",
      "name": "Quote Trigger (Webhook)",
      "type": "n8n-nodes-base.webhook",
      "position": [
        784,
        704
      ],
      "parameters": {
        "path": "dynamic-pricing-quote",
        "options": {},
        "httpMethod": "POST"
      },
      "typeVersion": 2.1
    },
    {
      "id": "9ed8d6d1-2163-4dc7-a8a7-4b9ba186dcf6",
      "name": "Fetch Opportunity Details",
      "type": "n8n-nodes-base.salesforce",
      "position": [
        1008,
        704
      ],
      "parameters": {
        "resource": "opportunity",
        "operation": "get",
        "opportunityId": "={{ $json.body.opportunityId }}"
      },
      "typeVersion": 1
    },
    {
      "id": "bf870ac2-8ed4-43a0-a7e2-491339cf0332",
      "name": "Fetch Account Details",
      "type": "n8n-nodes-base.salesforce",
      "position": [
        1232,
        704
      ],
      "parameters": {
        "resource": "account",
        "accountId": "={{ $json.AccountId }}",
        "operation": "get"
      },
      "typeVersion": 1
    },
    {
      "id": "74e6c716-3ad8-414f-8a1a-2d489c6f0358",
      "name": "Normalize Deal Context",
      "type": "n8n-nodes-base.code",
      "position": [
        1456,
        704
      ],
      "parameters": {
        "jsCode": "function getDealSize(amount) {\n  if (!amount) return \"unknown\";\n  if (amount < 5000) return \"small\";\n  if (amount < 20000) return \"medium\";\n  return \"large\";\n}\n\n// Helper: normalize customer segment\nfunction getCustomerSegment(type) {\n  if (!type) return \"unknown\";\n  const t = type.toLowerCase();\n  if (t.includes(\"enterprise\")) return \"enterprise\";\n  if (t.includes(\"smb\")) return \"smb\";\n  return \"mid-market\";\n}\n\n// Normalized output\nconst normalized = {\n  quote_id: $('Quote Trigger (Webhook)').first().json.body.quoteId || null,\n  opportunity_id: $('Fetch Opportunity Details').first().json.Id || null,\n  account_id: $input.first().json.Id || null,\n\n  // Core deal data\n  deal_amount: $('Fetch Opportunity Details').first().json.Amount || 0,\n  close_date: $('Fetch Opportunity Details').first().json.CloseDate || null,\n  stage: $('Fetch Opportunity Details').first().json.StageName || \"unknown\",\n\n  // Derived fields\n  deal_size: getDealSize($('Fetch Opportunity Details').first().json.Amount),\n  customer_segment: getCustomerSegment($input.first().json.Type),\n\n  // Contextual enrichment\n  industry: $input.first().json.Industry || \"unknown\",\n  region: $input.first().json.BillingCity || \"unknown\", // optional future use\n\n  // Metadata for AI\n  timestamp: new Date().toISOString()\n};\n\nreturn [{ json: normalized }];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "3666ad30-7938-4067-8316-54dd3067a8c0",
      "name": "Load Historical Deals (Sheets)",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1680,
        704
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1pdRFz9s2_blZMAsf-4romcXUIOidqI6Kla3mMXZ0FRI",
          "cachedResultUrl": "",
          "cachedResultName": "HistoricalDeals"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "94299de0-f2d4-4ef1-bd34-a9f7ef9d6fed",
      "name": "Match Relevant Historical Deals",
      "type": "n8n-nodes-base.code",
      "position": [
        1904,
        704
      ],
      "parameters": {
        "jsCode": "const current = $items(\"Normalize Deal Context\")[0].json;\nconst history = items.map(item => item.json);\n\n// Normalize helper\nconst normalize = (val) => (val || \"\").toString().toLowerCase().trim();\n\nfunction score(deal) {\n  let score = 0;\n  if (normalize(deal.DealSize) === normalize(current.deal_size)) score += 3;\n  if (normalize(deal.Segment) === normalize(current.customer_segment)) score += 2;\n  if (normalize(deal.Industry) === normalize(current.industry)) score += 1;\n  return score;\n}\n\nconst ranked = history\n  .map(d => ({ ...d, score: score(d) }))\n  .filter(d => d.score >= 3) // threshold\n  .sort((a, b) => b.score - a.score);\n\nreturn ranked.map(d => ({ json: d }));"
      },
      "typeVersion": 2
    },
    {
      "id": "1125e166-7a8d-4951-b684-eec2daf0ba36",
      "name": "Compute Pricing Benchmarks",
      "type": "n8n-nodes-base.code",
      "position": [
        2128,
        704
      ],
      "parameters": {
        "jsCode": "const deals = items.map(item => item.json);\n\n// Separate won/lost deals\nconst wonDeals = deals.filter(d => (d.Outcome || \"\").toLowerCase() === \"won\");\nconst lostDeals = deals.filter(d => (d.Outcome || \"\").toLowerCase() === \"lost\");\n\n// Helper function\nconst avg = (arr, field) => {\n  if (arr.length === 0) return 0;\n  return arr.reduce((sum, d) => sum + Number(d[field] || 0), 0) / arr.length;\n};\n\n// Calculations\nconst avgWonDiscount = avg(wonDeals, \"DiscountGiven\");\nconst avgLostDiscount = avg(lostDeals, \"DiscountGiven\");\n\nconst winRate = deals.length > 0 ? (wonDeals.length / deals.length) : 0;\n\n// Safe pricing logic\nlet recommendedDiscount = avgWonDiscount;\n\n// Adjust if losing deals had higher discounts (bad sign)\nif (avgLostDiscount > avgWonDiscount) {\n  recommendedDiscount = (avgWonDiscount + avgLostDiscount) / 2;\n}\n\n// Define safe range\nconst minDiscount = Math.max(0, avgWonDiscount - 2);\nconst maxDiscount = avgLostDiscount > 0 ? avgLostDiscount : avgWonDiscount + 5;\n\n// Output\nconst result = {\n  total_deals_considered: deals.length,\n  win_rate: Number(winRate.toFixed(2)),\n\n  avg_won_discount: Number(avgWonDiscount.toFixed(2)),\n  avg_lost_discount: Number(avgLostDiscount.toFixed(2)),\n\n  recommended_discount: Number(recommendedDiscount.toFixed(2)),\n\n  discount_range: {\n    min: Number(minDiscount.toFixed(2)),\n    max: Number(maxDiscount.toFixed(2))\n  }\n};\n\nreturn [{ json: result }];"
      },
      "typeVersion": 2
    },
    {
      "id": "45d6da6a-ddcb-41fc-a2a7-97fece11d474",
      "name": "AI Pricing Strategist",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        2352,
        704
      ],
      "parameters": {
        "text": "=Deal Context:\n- Deal Amount: {{ $('Match Relevant Historical Deals').item.json.FinalPrice }}\n- Deal Size:{{ $('Match Relevant Historical Deals').item.json.DealSize }} \n- Customer Segment: {{ $('Match Relevant Historical Deals').item.json.Segment }}\n- Industry: {{ $('Match Relevant Historical Deals').item.json.Industry }}\n\nHistorical Insights:\n- Total Deals Analyzed: {{$json[\"total_deals_considered\"]}}\n- Win Rate: {{$json[\"win_rate\"]}}\n- Avg Winning Discount: {{$json[\"avg_won_discount\"]}}%\n- Avg Losing Discount: {{$json[\"avg_lost_discount\"]}}%\n- Suggested Discount (Baseline): {{$json[\"recommended_discount\"]}}%\n- Safe Discount Range: {{$json[\"discount_range\"][\"min\"]}}% to {{$json[\"discount_range\"][\"max\"]}}%\n\nInstructions:\n1. Recommend an optimal discount percentage.\n2. Calculate the final price based on deal amount.\n3. Estimate win probability (0 to 1).\n4. Provide a strong justification using historical patterns and deal context.\n5. Mention if the deal is risky or safe.\n6. If data is weak, explicitly say confidence is low.\n\nOutput format:\n{\n  \"recommended_discount\": number,\n  \"final_price\": number,\n  \"win_probability\": number,\n  \"confidence\": \"high | medium | low\",\n  \"risk_level\": \"low | medium | high\",\n  \"justification\": \"detailed reasoning\"\n}",
        "options": {
          "systemMessage": "=You are a senior B2B pricing strategist with deep expertise in deal optimization, revenue growth, and competitive sales strategy.\n\nYour job is to recommend the optimal discount and pricing strategy for a deal using:\n- Historical pricing performance\n- Win/loss trends\n- Customer segment behavior\n- Deal size sensitivity\n- Competitive dynamics\n\nYou MUST follow these principles:\n\n1. Maximize win probability WITHOUT unnecessary discounting.\n2. Protect margins \u2014 avoid over-discounting unless strongly justified.\n3. Use historical data as the primary signal (not guesswork).\n4. If historical data shows higher discounts led to losses, AVOID increasing discounts.\n5. Be conservative for large deals unless strong justification exists.\n6. Provide reasoning like a human pricing expert, not a generic AI.\n\nOutput MUST be in strict JSON format.\n\nDO NOT include explanations outside JSON."
        },
        "promptType": "define"
      },
      "typeVersion": 3.1
    },
    {
      "id": "6c01ccdc-c14a-4ba2-9b00-933b9ad044cf",
      "name": "Structure AI Output",
      "type": "n8n-nodes-base.set",
      "position": [
        2704,
        704
      ],
      "parameters": {
        "mode": "raw",
        "options": {},
        "jsonOutput": "={{ $json.output }}"
      },
      "typeVersion": 3.4
    },
    {
      "id": "4c79726f-235a-4ff9-8c6e-5cf5a1ee53f7",
      "name": "Pre-Update Hook",
      "type": "n8n-nodes-base.salesforce",
      "position": [
        2928,
        704
      ],
      "parameters": {
        "resource": "account",
        "operation": "__CUSTOM_API_CALL__"
      },
      "typeVersion": 1
    },
    {
      "id": "8a37754b-ffc0-4df9-a0cb-35bb88e6c64c",
      "name": "Update Quote in Salesforce",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        3152,
        704
      ],
      "parameters": {
        "url": "=https://{DOMAIN_NAME}/services/data/v59.0/sobjects/Quote/{{$node[\"Normalize Deal Context\"].json[\"quote_id\"]}}",
        "method": "PATCH",
        "options": {},
        "jsonBody": "={\n  \"Recommended_Discount__c\": {{ $('Structure AI Output').item.json.recommended_discount }},\n  \"Final_Recommended_Price__c\": {{ $('Structure AI Output').item.json.final_price }},\n  \"Win_Probability__c\": {{ $('Structure AI Output').item.json.win_probability }},\n  \"Pricing_Confidence__c\": \"{{ $('Structure AI Output').item.json.confidence }}\",\n  \"Deal_Risk_Level__c\": \"{{ $('Structure AI Output').item.json.risk_level }}\",\n  \"Pricing_Justification__c\": \"{{ $('Structure AI Output').item.json.justification }}\"\n}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "salesforceOAuth2Api"
      },
      "typeVersion": 4.4
    },
    {
      "id": "d39c1a78-1f8a-4145-a38c-414449995dbb",
      "name": "Send Pricing Summary (Slack)",
      "type": "n8n-nodes-base.slack",
      "position": [
        3376,
        704
      ],
      "parameters": {
        "text": "=*AI Pricing Recommendation Applied*\n\n*Quote ID:* {{$node[\"Normalize Deal Context\"].json[\"quote_id\"]}}\n*Recommended Discount:* {{$node[\"Structure AI Output\"].json['recommended_discount']}}%\n*Final Price:* {{$node[\"Structure AI Output\"].json['final_price']}}\n*Win Probability:* {{$node[\"Structure AI Output\"].json['win_probability']}}\n\n*Risk Level:* {{$node[\"Structure AI Output\"].json['risk_level']}}\n*Confidence:* {{$node[\"Structure AI Output\"].json['confidence']}}\n\n*Justification*:\n{{$node[\"Structure AI Output\"].json['justification']}}",
        "user": {
          "__rl": true,
          "mode": "list",
          "value": "U0ANV4YLNTV",
          "cachedResultName": ""
        },
        "select": "user",
        "otherOptions": {
          "includeLinkToWorkflow": false
        },
        "authentication": "oAuth2"
      },
      "typeVersion": 2.4
    },
    {
      "id": "c5bf5411-bc48-4cc3-aa69-70d4a493cc07",
      "name": "LLM Engine (Groq)",
      "type": "@n8n/n8n-nodes-langchain.lmChatGroq",
      "position": [
        2432,
        928
      ],
      "parameters": {
        "model": "openai/gpt-oss-120b",
        "options": {}
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "executionOrder": "v1"
  },
  "versionId": "d67fb04e-1d5f-49d9-843b-825da826a865",
  "connections": {
    "Pre-Update Hook": {
      "main": [
        [
          {
            "node": "Update Quote in Salesforce",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "LLM Engine (Groq)": {
      "ai_languageModel": [
        [
          {
            "node": "AI Pricing Strategist",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Structure AI Output": {
      "main": [
        [
          {
            "node": "Pre-Update Hook",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Pricing Strategist": {
      "main": [
        [
          {
            "node": "Structure AI Output",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Account Details": {
      "main": [
        [
          {
            "node": "Normalize Deal Context",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Normalize Deal Context": {
      "main": [
        [
          {
            "node": "Load Historical Deals (Sheets)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Quote Trigger (Webhook)": {
      "main": [
        [
          {
            "node": "Fetch Opportunity Details",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Opportunity Details": {
      "main": [
        [
          {
            "node": "Fetch Account Details",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Compute Pricing Benchmarks": {
      "main": [
        [
          {
            "node": "AI Pricing Strategist",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update Quote in Salesforce": {
      "main": [
        [
          {
            "node": "Send Pricing Summary (Slack)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Load Historical Deals (Sheets)": {
      "main": [
        [
          {
            "node": "Match Relevant Historical Deals",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Match Relevant Historical Deals": {
      "main": [
        [
          {
            "node": "Compute Pricing Benchmarks",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}