{
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "8ac7bc5d-c409-44b2-8176-24ecbd2ae969",
      "name": "Groq Chat Model1",
      "type": "@n8n/n8n-nodes-langchain.lmChatGroq",
      "position": [
        18496,
        6112
      ],
      "parameters": {
        "model": "llama-3.3-70b-versatile",
        "options": {}
      },
      "typeVersion": 1
    },
    {
      "id": "f6b4adc7-0709-4058-8ff6-9107ccfbef6b",
      "name": "Send a message2",
      "type": "n8n-nodes-base.gmail",
      "position": [
        19088,
        5856
      ],
      "parameters": {
        "sendTo": "your-email",
        "message": "={{ $json.email_data.full_report }}",
        "options": {},
        "subject": "Revenue Forecast Summary Data"
      },
      "typeVersion": 2.2
    },
    {
      "id": "911581aa-7453-44ca-b5c6-db1a6ce8efd7",
      "name": "Send a message3",
      "type": "n8n-nodes-base.slack",
      "position": [
        19088,
        6064
      ],
      "parameters": {
        "text": "={{ $json.email_data.full_report }}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "gmail-id",
          "cachedResultName": "all-n8ntest"
        },
        "otherOptions": {},
        "authentication": "oAuth2"
      },
      "typeVersion": 2.4
    },
    {
      "id": "5bcf9c46-80b9-4c46-999e-ab02c2743f9b",
      "name": "Loop Over Items1",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        18352,
        5936
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "08c06ca5-dfaf-4b10-ae33-df0fb3e2cc6d",
      "name": "Wait1",
      "type": "n8n-nodes-base.wait",
      "position": [
        19472,
        6048
      ],
      "parameters": {},
      "typeVersion": 1.1
    },
    {
      "id": "ed54b5d9-678f-4a17-8b56-d96cc7dda6f8",
      "name": "Format AI response1",
      "type": "n8n-nodes-base.code",
      "position": [
        18864,
        5952
      ],
      "parameters": {
        "jsCode": "// Extract AI response text\nconst aiOutput = $input.first().json.output;\n\n// Helper function to extract section content\nfunction extractSection(text, sectionTitle) {\n  const regex = new RegExp(`## ${sectionTitle}([\\\\s\\\\S]*?)(?=##|$)`, 'i');\n  const match = text.match(regex);\n  return match ? match[1].trim() : 'Not available';\n}\n\n// Helper function to extract bullet points\nfunction extractBullets(text) {\n  const bullets = text.match(/[\\*\\+\\-]\\s+\\*\\*(.+?)\\*\\*/g) || [];\n  return bullets.map(b => b.replace(/[\\*\\+\\-]\\s+\\*\\*(.+?)\\*\\*/, '$1')).join(', ');\n}\n\n// Helper function to clean markdown formatting\nfunction cleanText(text) {\n  return text\n    .replace(/\\*\\*/g, '') // Remove bold markers\n    .replace(/\\*/g, '')   // Remove italic markers\n    .replace(/\\t/g, '')   // Remove tabs\n    .replace(/\\n\\n+/g, '\\n') // Remove multiple newlines\n    .trim();\n}\n\n// Extract revenue figures\nfunction extractRevenue(text) {\n  const bestCase = text.match(/Best Case:\\s*\u20b9?([\\d,]+)/i);\n  const likelyCase = text.match(/Likely Case:\\s*\u20b9?([\\d,]+)/i);\n  const worstCase = text.match(/Worst Case:\\s*\u20b9?([\\d,]+)/i);\n  const weighted = text.match(/Weighted Pipeline Value:\\s*\u20b9?([\\d,]+)/i);\n  \n  return {\n    best_case: bestCase ? `\u20b9${bestCase[1]}` : '\u20b90',\n    likely_case: likelyCase ? `\u20b9${likelyCase[1]}` : '\u20b90',\n    worst_case: worstCase ? `\u20b9${worstCase[1]}` : '\u20b90',\n    weighted_value: weighted ? `\u20b9${weighted[1]}` : '\u20b90'\n  };\n}\n\n// Extract high-risk deals\nfunction extractHighRiskDeals(text) {\n  const dealName = text.match(/\\*\\*Deal Name:\\*\\*\\s*(.+)/);\n  const dealAmount = text.match(/\\*\\*Deal Amount:\\*\\*\\s*\u20b9?([\\d,]+)/);\n  const riskFactors = text.match(/\\*\\*Risk Factors:\\*\\*([\\s\\S]*?)(?=\\*\\*Recommended|$)/);\n  \n  let riskText = '';\n  if (dealName && dealAmount) {\n    riskText = `${dealName[1]} (\u20b9${dealAmount[1]})`;\n    if (riskFactors) {\n      const factors = riskFactors[1].match(/\\+\\s+(.+)/g);\n      if (factors) {\n        riskText += ' - ' + factors.map(f => f.replace(/\\+\\s+/, '')).join('; ');\n      }\n    }\n  }\n  return riskText || 'No high-risk deals identified';\n}\n\n// Extract top recommendations\nfunction extractRecommendations(text) {\n  const recommendations = text.match(/\\*\\*Top 3 Actions.*?:\\*\\*([\\s\\S]*?)(?=\\*\\*Deals Requiring|$)/);\n  if (recommendations) {\n    const actions = recommendations[1].match(/\\d+\\.\\s+\\*\\*(.+?)\\*\\*/g);\n    if (actions) {\n      return actions.map((a, i) => {\n        const title = a.match(/\\*\\*(.+?)\\*\\*/)[1];\n        const desc = recommendations[1].match(new RegExp(`${i + 1}\\\\.\\\\s+\\\\*\\\\*${title}\\\\*\\\\*:?\\\\s*(.+?)(?=\\\\n\\\\s*\\\\d+\\\\.|$)`, 's'));\n        return `${i + 1}. ${title}${desc ? ': ' + cleanText(desc[1]) : ''}`;\n      }).join('\\n');\n    }\n  }\n  return 'No specific recommendations';\n}\n\n// Extract revenue drivers\nfunction extractRevenueDrivers(text) {\n  const section = extractSection(aiOutput, 'Revenue Drivers Analysis');\n  const keyDeals = section.match(/\\*\\*Key Deals:\\*\\*\\s*(.+)/);\n  const trends = section.match(/\\*\\*Revenue Trends:\\*\\*\\s*(.+)/);\n  \n  let drivers = '';\n  if (trends) drivers += cleanText(trends[1]) + '. ';\n  if (keyDeals) drivers += 'Key deals: ' + cleanText(keyDeals[1]);\n  \n  return drivers || 'Insufficient data for analysis';\n}\n\n// Parse all sections\nconst revenue = extractRevenue(aiOutput);\nconst highRiskDeals = extractHighRiskDeals(extractSection(aiOutput, 'High-Risk Deals'));\nconst revenueDrivers = extractRevenueDrivers(aiOutput);\nconst recommendations = extractRecommendations(aiOutput);\n\n// Format for Google Sheets\nconst formattedData = {\n  timestamp: new Date().toLocaleString('en-IN', { timeZone: 'Asia/Kolkata' }),\n  forecast_period: new Date().toLocaleString('en-IN', { month: 'long', year: 'numeric' }),\n  expected_revenue: revenue.likely_case,\n  best_case: revenue.best_case,\n  worst_case: revenue.worst_case,\n  weighted_pipeline: revenue.weighted_value,\n  high_risk_deals: highRiskDeals,\n  revenue_drivers: revenueDrivers,\n  recommendations: recommendations,\n  full_ai_response: cleanText(aiOutput),\n  report_sent_to: 'user@example.com, user@example.com'\n};\n\n// Format for Email HTML (clean sections)\nconst emailData = {\n  timestamp: formattedData.timestamp,\n  forecast_summary: `\n    <p><strong>Expected Revenue:</strong> ${revenue.likely_case}</p>\n    <p><strong>Best Case:</strong> ${revenue.best_case}</p>\n    <p><strong>Worst Case:</strong> ${revenue.worst_case}</p>\n    <p><strong>Weighted Pipeline:</strong> ${revenue.weighted_value}</p>\n  `,\n  high_risk_section: `\n    <p>${highRiskDeals}</p>\n  `,\n  revenue_drivers_section: `\n    <p>${revenueDrivers}</p>\n  `,\n  recommendations_section: `\n    <pre style=\"background-color: #f4f4f4; padding: 15px; border-radius: 5px; white-space: pre-wrap;\">${recommendations}</pre>\n  `,\n  full_report: aiOutput.replace(/\\n/g, '<br>').replace(/\\*\\*(.+?)\\*\\*/g, '<strong>$1</strong>')\n};\n\n// Return both formats\nreturn [\n  {\n    json: {\n      // For Google Sheets\n      sheets_data: formattedData,\n      \n      // For Email\n      email_data: emailData,\n      \n      // Raw data for debugging\n      raw_output: aiOutput\n    }\n  }\n];"
      },
      "typeVersion": 2
    },
    {
      "id": "75c2b1e5-d2c2-4867-93e7-41d81f3db16a",
      "name": "Append row in sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        19248,
        5952
      ],
      "parameters": {
        "columns": {
          "value": {
            "Status": "Email Sent",
            "Best_Case": "={{ $json.sheets_data.best_case }}",
            "Time Stamp": "={{ $json.sheets_data.timestamp }}",
            "Worst_Case": "={{ $json.sheets_data.worst_case }}",
            "Report_Sent_To": "={{ $json.sheets_data.report_sent_to }}",
            "Forecast_Period": "={{ $json.sheets_data.forecast_period }}",
            "High_Risk_Deals": "={{ $json.sheets_data.high_risk_deals }}",
            "Recommendations": "={{ $json.sheets_data.recommendations }}",
            "Revenue_Drivers": "={{ $json.sheets_data.revenue_drivers }}",
            "Expected_Revenue": "={{ $json.sheets_data.expected_revenue }}",
            "Full_AI_Response": "={{ $json.sheets_data.full_ai_response }}",
            "Weighted_Pipeline": "={{ $json.sheets_data.weighted_pipeline }}"
          },
          "schema": [
            {
              "id": "Time Stamp",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Time Stamp",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Forecast_Period",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Forecast_Period",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Expected_Revenue",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Expected_Revenue",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Best_Case",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Best_Case",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Worst_Case",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Worst_Case",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Weighted_Pipeline",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Weighted_Pipeline",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "High_Risk_Deals",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "High_Risk_Deals",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Revenue_Drivers",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Revenue_Drivers",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Recommendations",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Recommendations",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Full_AI_Response",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Full_AI_Response",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Report_Sent_To",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Report_Sent_To",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Status",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1485545756,
          "cachedResultUrl": "sheet-url",
          "cachedResultName": "sheet-name"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "sheet-value",
          "cachedResultUrl": "sheet-url",
          "cachedResultName": "sheet-name"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "ad3b35be-95a2-4fa5-813a-62910b68b002",
      "name": "HubSpot Trigger1",
      "type": "n8n-nodes-base.hubspotTrigger",
      "position": [
        17808,
        5936
      ],
      "parameters": {
        "eventsUi": {
          "eventValues": [
            {
              "name": "deal.creation"
            }
          ]
        },
        "additionalFields": {}
      },
      "typeVersion": 1
    },
    {
      "id": "9686ae09-74f9-4f99-b92a-457b83f1cfaa",
      "name": "Get many deals1",
      "type": "n8n-nodes-base.hubspot",
      "position": [
        17984,
        5936
      ],
      "parameters": {
        "filters": {},
        "resource": "deal",
        "operation": "getAll"
      },
      "typeVersion": 2.2
    },
    {
      "id": "fe6d16bc-d256-4c3f-9945-7be037564dda",
      "name": "Format Hubspot Data1",
      "type": "n8n-nodes-base.code",
      "position": [
        18160,
        5936
      ],
      "parameters": {
        "jsCode": "// Helper: map region to currency\nfunction getCurrency(region) {\n  const map = {\n    \"India\": \"INR\",\n    \"USA\": \"USD\",\n    \"United States\": \"USD\",\n    \"UK\": \"GBP\",\n    \"United Kingdom\": \"GBP\",\n    \"UAE\": \"AED\"\n  };\n  return map[region] || \"USD\"; // default\n}\n\nreturn items.map(item => {\n  const deal = item.json.properties || {};\n\n  // Extract values safely\n  const dealName = deal.dealname || \"Unknown Deal\";\n  const dealAmount = Number(deal.amount || 0);\n\n  const stage = deal.dealstage || \"Unknown\";\n  const closeDate = deal.closedate\n    ? new Date(Number(deal.closedate)).toISOString().split(\"T\")[0]\n    : null;\n\n  const probability = deal.hs_probability\n    ? Math.round(Number(deal.hs_probability) * 100)\n    : 0;\n\n  const owner = deal.hubspot_owner_id || \"Unassigned\";\n\n  const region =\n    deal.country ||\n    deal.region ||\n    deal.hs_country_region ||\n    \"Unknown\";\n\n  const currency = getCurrency(region);\n\n  return {\n    json: {\n      \"Deal Name\": dealName,\n      \"Customer Name\": deal.associatedcompanyname || \"N/A\",\n      \"Deal Amount\": dealAmount,\n      \"Currency\": currency,\n      \"Stage\": stage,\n      \"Close Date\": closeDate,\n      \"Probability (%)\": probability,\n      \"Sales Owner\": owner,\n      \"Region\": region\n    }\n  };\n});\n"
      },
      "typeVersion": 2
    },
    {
      "id": "4da571ca-aae7-4c74-b2a4-b19bf50da20a",
      "name": "AI Revenue Forecast & Risk Analysis1",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        18560,
        5952
      ],
      "parameters": {
        "text": "=Analyze the following sales pipeline data and generate a revenue forecast report:\n\n**Current Date:** {{$now.format('YYYY-MM-DD')}}\n**Forecast Period:** Next 30 days\n\n**Sales Pipeline Data:**\n{{JSON.stringify($json)}}\n\nPlease provide:\n\n1. **Revenue Forecast Summary**\n   - Expected revenue (best case, likely case, worst case)\n   - Weighted pipeline value\n   - Conversion rate trends\n\n2. **High-Risk Deals** (identify deals that may slip or not close)\n   - Deal name, amount, and risk factors\n   - Recommended actions to mitigate risks\n\n3. **Revenue Drivers Analysis**\n   - Why is revenue increasing or decreasing compared to last period?\n   - Which deals are moving the needle?\n   - Pipeline health assessment\n\n4. **Key Recommendations**\n   - Top 3 actions for sales leadership\n   - Deals requiring immediate attention\n\nFormat your response in clear sections with bullet points for easy reading.",
        "options": {
          "systemMessage": "=You are an expert Revenue Forecasting AI specialized in sales pipeline analysis. Your role is to:\n\n1. Analyze sales deal data (amount, stage, close date, probability)\n2. Generate accurate revenue forecasts for the next month/quarter\n3. Identify high-risk deals that may not close\n4. Explain key revenue drivers (why revenue is increasing or decreasing)\n5. Provide actionable insights for sales leadership\n\n**Output Requirements:**\n- Be concise and executive-ready\n- Use clear, business-friendly language\n- Highlight critical risks and opportunities\n- Provide specific deal-level recommendations\n- Format responses in structured sections\n\n**Tone:** Professional, data-driven, and action-oriented"
        },
        "promptType": "define"
      },
      "typeVersion": 3
    },
    {
      "id": "cdf2afe5-3f49-4c3f-a508-ee0570f81a18",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        17136,
        5648
      ],
      "parameters": {
        "width": 640,
        "height": 688,
        "content": "## AI Revenue Forecast Generator\n\nThis workflow automatically generates an AI-powered revenue forecast whenever a new deal is created in HubSpot. It analyzes the entire sales pipeline to estimate expected revenue, identify high-risk deals, and highlight key revenue drivers. The goal is to give sales leaders a clear, executive-ready view of pipeline health and upcoming revenue.\n\n### How it works\n- Triggers when a deal is created in HubSpot  \n- Fetches all active deals from the pipeline  \n- Cleans and standardizes deal data (amount, stage, probability, region)  \n- Sends structured data to an AI model for forecasting and risk analysis  \n- Generates best, likely, and worst-case revenue scenarios  \n- Shares the report via Slack and Email  \n- Logs all insights in Google Sheets for tracking and audits  \n\n### Setup steps\n1. Connect your HubSpot account and enable the Deal Created trigger  \n2. Ensure required deal properties are available  \n3. Connect your AI provider (Groq / LLM)  \n4. Connect Slack and choose a channel  \n5. Connect Gmail for email delivery  \n6. Connect Google Sheets for data logging  \n7. Turn the workflow ON and test by creating a deal  "
      },
      "typeVersion": 1
    },
    {
      "id": "d1c68d2b-7f47-4d6c-a8ce-81381ecd368b",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        17792,
        5648
      ],
      "parameters": {
        "color": 7,
        "width": 688,
        "height": 688,
        "content": "## Step 1 \u2013 Collect & prepare HubSpot deals  \nTriggers on deal creation, fetches all active deals, and formats key fields for AI analysis.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "73e70ef7-057a-45dc-9ce1-27986c76a405",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        18496,
        5648
      ],
      "parameters": {
        "color": 7,
        "width": 1136,
        "height": 688,
        "content": "## Step 2 \u2013 Generate & distribute AI forecast  \nAI generates revenue forecasts and risk insights, sends them to Slack and Email, and logs them in Google Sheets."
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "Wait1": {
      "main": [
        [
          {
            "node": "Loop Over Items1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get many deals1": {
      "main": [
        [
          {
            "node": "Format Hubspot Data1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Groq Chat Model1": {
      "ai_languageModel": [
        [
          {
            "node": "AI Revenue Forecast & Risk Analysis1",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "HubSpot Trigger1": {
      "main": [
        [
          {
            "node": "Get many deals1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Items1": {
      "main": [
        [],
        [
          {
            "node": "AI Revenue Forecast & Risk Analysis1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Append row in sheet": {
      "main": [
        [
          {
            "node": "Wait1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format AI response1": {
      "main": [
        [
          {
            "node": "Send a message2",
            "type": "main",
            "index": 0
          },
          {
            "node": "Append row in sheet",
            "type": "main",
            "index": 0
          },
          {
            "node": "Send a message3",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Hubspot Data1": {
      "main": [
        [
          {
            "node": "Loop Over Items1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Revenue Forecast & Risk Analysis1": {
      "main": [
        [
          {
            "node": "Format AI response1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}