AutomationFlowsAI & RAG › Forecast Demand, Optimize Pricing, and Engage Customers with Gpt‑4.1,…

Forecast Demand, Optimize Pricing, and Engage Customers with Gpt‑4.1,…

Original n8n title: Forecast Demand, Optimize Pricing, and Engage Customers with Gpt‑4.1, Postgres, Email, and Slack

ByCheng Siong Chin @cschin on n8n.io

This workflow automates inventory management and customer engagement for e-commerce businesses and retail operations managing multiple product categories. It solves the critical challenge of maintaining optimal stock levels while personalizing customer communications across…

Webhook trigger★★★★★ complexityAI-powered37 nodesAgentOpenAI ChatOutput Parser StructuredPostgresSlackEmail Send
AI & RAG Trigger: Webhook Nodes: 37 Complexity: ★★★★★ AI nodes: yes Added:

This workflow corresponds to n8n.io template #12791 — we link there as the canonical source.

This workflow follows the Agent → Emailsend 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
{
  "id": "XJkO31tm0GLmkHN1",
  "name": "E-commerce Intelligence & Automated Customer Engagement Platform",
  "tags": [],
  "nodes": [
    {
      "id": "7fdc5d93-218c-4ad3-863e-9101ff48bc5e",
      "name": "Webhook - Ingest Data",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -1824,
        1132
      ],
      "parameters": {
        "path": "ecommerce-data",
        "options": {},
        "httpMethod": "POST",
        "responseData": "firstEntryBinary",
        "responseMode": "lastNode"
      },
      "typeVersion": 2.1
    },
    {
      "id": "9113fb5a-bacd-44f5-9211-cc61b6583b13",
      "name": "Workflow Configuration",
      "type": "n8n-nodes-base.set",
      "position": [
        -1600,
        1132
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "id-1",
              "name": "lowStockThreshold",
              "type": "number",
              "value": 10
            },
            {
              "id": "id-2",
              "name": "negativeSentimentThreshold",
              "type": "number",
              "value": -0.5
            },
            {
              "id": "id-3",
              "name": "highDemandThreshold",
              "type": "number",
              "value": 100
            },
            {
              "id": "id-4",
              "name": "apiRateLimit",
              "type": "number",
              "value": 100
            },
            {
              "id": "id-5",
              "name": "batchSize",
              "type": "number",
              "value": 50
            },
            {
              "id": "id-6",
              "name": "retryAttempts",
              "type": "number",
              "value": 3
            },
            {
              "id": "id-7",
              "name": "retryDelay",
              "type": "number",
              "value": 5000
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "3258f3f5-55d1-40a3-aa93-669e605d3038",
      "name": "Route by Data Type",
      "type": "n8n-nodes-base.switch",
      "position": [
        -1376,
        1100
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "outputKey": "orders",
              "conditions": {
                "options": {
                  "leftValue": "",
                  "caseSensitive": false,
                  "typeValidation": "loose"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.dataType }}",
                    "rightValue": "order"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "reviews",
              "conditions": {
                "options": {
                  "leftValue": "",
                  "caseSensitive": false,
                  "typeValidation": "loose"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.dataType }}",
                    "rightValue": "review"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "inventory",
              "conditions": {
                "options": {
                  "leftValue": "",
                  "caseSensitive": false,
                  "typeValidation": "loose"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.dataType }}",
                    "rightValue": "inventory"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "social",
              "conditions": {
                "options": {
                  "leftValue": "",
                  "caseSensitive": false,
                  "typeValidation": "loose"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.dataType }}",
                    "rightValue": "social_media"
                  }
                ]
              },
              "renameOutput": true
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 3.4
    },
    {
      "id": "85d21012-c743-416b-9a35-5fa9a2705e3b",
      "name": "Normalize Orders",
      "type": "n8n-nodes-base.set",
      "position": [
        -1152,
        384
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "id-1",
              "name": "orderId",
              "type": "string",
              "value": "={{ $json.id || $json.order_id }}"
            },
            {
              "id": "id-2",
              "name": "customerId",
              "type": "string",
              "value": "={{ $json.customer_id || $json.customerId }}"
            },
            {
              "id": "id-3",
              "name": "orderDate",
              "type": "string",
              "value": "={{ $json.created_at || $json.orderDate || $now }}"
            },
            {
              "id": "id-4",
              "name": "totalAmount",
              "type": "number",
              "value": "={{ $json.total || $json.amount || 0 }}"
            },
            {
              "id": "id-5",
              "name": "status",
              "type": "string",
              "value": "={{ $json.status || 'pending' }}"
            },
            {
              "id": "id-6",
              "name": "products",
              "type": "array",
              "value": "={{ $json.items || $json.products || [] }}"
            },
            {
              "id": "id-7",
              "name": "dataType",
              "type": "string",
              "value": "order"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "be411153-3f10-455b-a05e-9d7ef23124f4",
      "name": "Normalize Reviews",
      "type": "n8n-nodes-base.set",
      "position": [
        -1152,
        984
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "id-1",
              "name": "reviewId",
              "type": "string",
              "value": "={{ $json.id || $json.review_id }}"
            },
            {
              "id": "id-2",
              "name": "productId",
              "type": "string",
              "value": "={{ $json.product_id || $json.productId }}"
            },
            {
              "id": "id-3",
              "name": "customerId",
              "type": "string",
              "value": "={{ $json.customer_id || $json.customerId }}"
            },
            {
              "id": "id-4",
              "name": "rating",
              "type": "number",
              "value": "={{ $json.rating || $json.stars || 0 }}"
            },
            {
              "id": "id-5",
              "name": "reviewText",
              "type": "string",
              "value": "={{ $json.text || $json.comment || $json.review || '' }}"
            },
            {
              "id": "id-6",
              "name": "reviewDate",
              "type": "string",
              "value": "={{ $json.created_at || $json.date || $now }}"
            },
            {
              "id": "id-7",
              "name": "dataType",
              "type": "string",
              "value": "review"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "74c31f34-bec6-43c2-b76a-86d250319229",
      "name": "Normalize Inventory",
      "type": "n8n-nodes-base.set",
      "position": [
        -1152,
        1280
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "id-1",
              "name": "productId",
              "type": "string",
              "value": "={{ $json.id || $json.product_id || $json.sku }}"
            },
            {
              "id": "id-2",
              "name": "productName",
              "type": "string",
              "value": "={{ $json.name || $json.product_name || '' }}"
            },
            {
              "id": "id-3",
              "name": "currentStock",
              "type": "number",
              "value": "={{ $json.stock || $json.quantity || 0 }}"
            },
            {
              "id": "id-4",
              "name": "reorderPoint",
              "type": "number",
              "value": "={{ $json.reorder_point || $json.minStock || 20 }}"
            },
            {
              "id": "id-5",
              "name": "lastUpdated",
              "type": "string",
              "value": "={{ $json.updated_at || $now }}"
            },
            {
              "id": "id-6",
              "name": "warehouseLocation",
              "type": "string",
              "value": "={{ $json.location || $json.warehouse || 'default' }}"
            },
            {
              "id": "id-7",
              "name": "dataType",
              "type": "string",
              "value": "inventory"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "0e2ca03a-fbd9-479f-b92f-76e7f280f7e9",
      "name": "Normalize Social Media",
      "type": "n8n-nodes-base.set",
      "position": [
        -1152,
        1472
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "id-1",
              "name": "postId",
              "type": "string",
              "value": "={{ $json.id || $json.post_id }}"
            },
            {
              "id": "id-2",
              "name": "platform",
              "type": "string",
              "value": "={{ $json.platform || $json.source || 'unknown' }}"
            },
            {
              "id": "id-3",
              "name": "content",
              "type": "string",
              "value": "={{ $json.text || $json.message || $json.content || '' }}"
            },
            {
              "id": "id-4",
              "name": "author",
              "type": "string",
              "value": "={{ $json.author || $json.username || $json.user || '' }}"
            },
            {
              "id": "id-5",
              "name": "timestamp",
              "type": "string",
              "value": "={{ $json.created_at || $json.timestamp || $now }}"
            },
            {
              "id": "id-6",
              "name": "engagement",
              "type": "number",
              "value": "={{ $json.likes + $json.shares + $json.comments || 0 }}"
            },
            {
              "id": "id-7",
              "name": "dataType",
              "type": "string",
              "value": "social_media"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "93eb893b-6903-43a3-8002-be19d240a591",
      "name": "Validate Orders",
      "type": "n8n-nodes-base.filter",
      "position": [
        -928,
        384
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "combinator": "and",
          "conditions": [
            {
              "id": "id-1",
              "operator": {
                "type": "string",
                "operation": "notEmpty"
              },
              "leftValue": "={{ $json.orderId }}",
              "rightValue": ""
            },
            {
              "id": "id-2",
              "operator": {
                "type": "string",
                "operation": "notEmpty"
              },
              "leftValue": "={{ $json.customerId }}",
              "rightValue": ""
            },
            {
              "id": "id-3",
              "operator": {
                "type": "number",
                "operation": "gt"
              },
              "leftValue": "={{ $json.totalAmount }}",
              "rightValue": 0
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "d3394dfa-400a-47aa-9152-708bf770b8fd",
      "name": "Validate Reviews",
      "type": "n8n-nodes-base.filter",
      "position": [
        -928,
        984
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "id-1",
              "operator": {
                "type": "string",
                "operation": "notEmpty"
              },
              "leftValue": "={{ $json.reviewId }}",
              "rightValue": ""
            },
            {
              "id": "id-2",
              "operator": {
                "type": "string",
                "operation": "notEmpty"
              },
              "leftValue": "={{ $json.productId }}",
              "rightValue": ""
            },
            {
              "id": "id-3",
              "operator": {
                "type": "string",
                "operation": "notEmpty"
              },
              "leftValue": "={{ $json.reviewText }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "264fbc46-7020-43c9-88a5-5e28c8c75a8b",
      "name": "Validate Inventory",
      "type": "n8n-nodes-base.filter",
      "position": [
        -928,
        1280
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "condition-1",
              "operator": {
                "type": "string",
                "operation": "notEmpty"
              },
              "leftValue": "={{ $json.productId }}",
              "rightValue": ""
            },
            {
              "id": "condition-2",
              "operator": {
                "type": "number",
                "operation": "gte"
              },
              "leftValue": "={{ $json.currentStock }}",
              "rightValue": 0
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "3d263e0d-bd10-4996-a7aa-c1dc7abc9394",
      "name": "Validate Social Media",
      "type": "n8n-nodes-base.filter",
      "position": [
        -928,
        1472
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "id-1",
              "operator": {
                "type": "string",
                "operation": "notEmpty"
              },
              "leftValue": "={{ $json.postId }}",
              "rightValue": ""
            },
            {
              "id": "id-2",
              "operator": {
                "type": "string",
                "operation": "notEmpty"
              },
              "leftValue": "={{ $json.content }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "05d33403-da1f-4c47-9ff5-b79960a7e37d",
      "name": "AI Agent - Sentiment Analysis",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        -704,
        880
      ],
      "parameters": {
        "text": "=Review: {{ $json.reviewText }}\nRating: {{ $json.rating }}/5",
        "options": {
          "systemMessage": "You are a sentiment analysis expert for e-commerce product reviews.\n\nYour task is to:\n1. Analyze the sentiment of customer reviews\n2. Classify sentiment as positive, neutral, or negative\n3. Extract key themes and topics mentioned\n4. Identify specific product features discussed\n5. Assess urgency of any issues raised\n\nProvide structured output with sentiment score (-1 to 1), classification, key themes, and urgency level."
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 3.1
    },
    {
      "id": "61cd1314-9b39-4506-80eb-00366c9b1f92",
      "name": "AI Agent - Demand Forecasting",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        -704,
        128
      ],
      "parameters": {
        "text": "=Order Data: {{ JSON.stringify($json) }}",
        "options": {
          "systemMessage": "You are a demand forecasting specialist for e-commerce operations.\n\nYour task is to:\n1. Analyze order patterns and trends\n2. Predict future demand for products\n3. Identify seasonal patterns and anomalies\n4. Calculate recommended stock levels\n5. Flag products with unusual demand spikes or drops\n\nProvide structured output with demand forecast, confidence level, recommended actions, and risk factors."
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 3.1
    },
    {
      "id": "22aa936d-eb33-4b5c-b6b6-15aeadde8583",
      "name": "AI Agent - Product Recommendations",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        -704,
        480
      ],
      "parameters": {
        "text": "=Customer Order: {{ JSON.stringify($json) }}",
        "options": {
          "systemMessage": "You are a personalized product recommendation engine for e-commerce.\n\nYour task is to:\n1. Analyze customer purchase history and preferences\n2. Generate personalized product recommendations\n3. Consider product compatibility and complementary items\n4. Factor in current promotions and inventory availability\n5. Rank recommendations by relevance and likelihood of purchase\n\nProvide structured output with top 5 product recommendations, reasoning, expected conversion probability, and upsell opportunities."
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 3.1
    },
    {
      "id": "d69ab9bc-6cc0-46d1-aca4-b9bac2e97f59",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        -696,
        304
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini"
        },
        "options": {},
        "builtInTools": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "875ab010-179c-43b9-9f27-d20e3fd11e38",
      "name": "Structured Output - Sentiment",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        -632,
        1104
      ],
      "parameters": {
        "jsonSchemaExample": "{\n\t\"sentimentScore\": 0.85,\n\t\"classification\": \"positive\",\n\t\"keyThemes\": [\"product quality\", \"customer service\", \"delivery speed\"],\n\t\"urgency\": \"low\",\n\t\"actionRequired\": false\n}"
      },
      "typeVersion": 1.3
    },
    {
      "id": "ab3c9a3e-856d-46ee-8d07-0498699d6449",
      "name": "Structured Output - Forecast",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        -568,
        304
      ],
      "parameters": {
        "jsonSchemaExample": "{\n\t\"forecastedDemand\": 1500,\n\t\"confidenceLevel\": 0.85,\n\t\"recommendedStockLevel\": 2000,\n\t\"trendDirection\": \"increasing\",\n\t\"riskFactors\": [\"seasonal variation\", \"supply chain delays\"]\n}"
      },
      "typeVersion": 1.3
    },
    {
      "id": "cb59cf2f-5bb8-4135-892d-9c50a6e65aca",
      "name": "Structured Output - Recommendations",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        -632,
        704
      ],
      "parameters": {
        "schemaType": "manual",
        "inputSchema": "{\n\t\"type\": \"object\",\n\t\"properties\": {\n\t\t\"recommendations\": {\n\t\t\t\"type\": \"array\",\n\t\t\t\"items\": {\n\t\t\t\t\"type\": \"object\",\n\t\t\t\t\"properties\": {\n\t\t\t\t\t\"productId\": {\n\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t},\n\t\t\t\t\t\"productName\": {\n\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t},\n\t\t\t\t\t\"score\": {\n\t\t\t\t\t\t\"type\": \"number\"\n\t\t\t\t\t},\n\t\t\t\t\t\"reasoning\": {\n\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t\"conversionProbability\": {\n\t\t\t\"type\": \"number\"\n\t\t},\n\t\t\"upsellOpportunities\": {\n\t\t\t\"type\": \"array\",\n\t\t\t\"items\": {\n\t\t\t\t\"type\": \"string\"\n\t\t\t}\n\t\t}\n\t}\n}"
      },
      "typeVersion": 1.3
    },
    {
      "id": "92ea6225-686b-4ae9-b1fc-cabb5e47afa7",
      "name": "Apply Pricing Rules",
      "type": "n8n-nodes-base.code",
      "position": [
        80,
        208
      ],
      "parameters": {
        "jsCode": "// Apply Dynamic Pricing Rules\n// Based on demand forecast, inventory levels, and competitor pricing with margin protection\n\nconst items = $input.all();\nconst processedItems = [];\n\nfor (const item of items) {\n  const data = item.json;\n  \n  // Extract relevant data\n  const basePrice = data.basePrice || data.price || 0;\n  const demandForecast = data.demandForecast || data.forecast || 'medium';\n  const inventoryLevel = data.inventoryLevel || data.inventory || 0;\n  const competitorPrice = data.competitorPrice || basePrice;\n  const minMargin = data.minMargin || 0.15; // 15% minimum margin\n  const cost = data.cost || basePrice * 0.6; // Assume 40% margin if cost not provided\n  \n  let finalPrice = basePrice;\n  let priceAdjustment = 0;\n  let adjustmentReason = [];\n  \n  // Rule 1: Demand-based pricing\n  if (demandForecast === 'high' || demandForecast > 0.7) {\n    priceAdjustment += basePrice * 0.10; // Increase by 10%\n    adjustmentReason.push('High demand forecast');\n  } else if (demandForecast === 'low' || demandForecast < 0.3) {\n    priceAdjustment -= basePrice * 0.08; // Decrease by 8%\n    adjustmentReason.push('Low demand forecast');\n  }\n  \n  // Rule 2: Inventory-based pricing\n  if (inventoryLevel < 10) {\n    priceAdjustment += basePrice * 0.05; // Increase by 5% for low stock\n    adjustmentReason.push('Low inventory');\n  } else if (inventoryLevel > 100) {\n    priceAdjustment -= basePrice * 0.10; // Decrease by 10% for overstock\n    adjustmentReason.push('Overstock clearance');\n  }\n  \n  // Rule 3: Competitor pricing adjustment\n  if (competitorPrice < basePrice * 0.95) {\n    const competitivePrice = competitorPrice * 0.98; // Price slightly below competitor\n    priceAdjustment = competitivePrice - basePrice;\n    adjustmentReason.push('Competitive pricing match');\n  }\n  \n  // Calculate proposed price\n  finalPrice = basePrice + priceAdjustment;\n  \n  // Rule 4: Margin protection - ensure minimum margin is maintained\n  const minPrice = cost / (1 - minMargin);\n  if (finalPrice < minPrice) {\n    finalPrice = minPrice;\n    adjustmentReason.push('Margin protection applied');\n  }\n  \n  // Calculate final metrics\n  const margin = ((finalPrice - cost) / finalPrice) * 100;\n  const priceChangePercent = ((finalPrice - basePrice) / basePrice) * 100;\n  \n  processedItems.push({\n    json: {\n      ...data,\n      basePrice: basePrice,\n      finalPrice: Math.round(finalPrice * 100) / 100,\n      priceAdjustment: Math.round(priceAdjustment * 100) / 100,\n      priceChangePercent: Math.round(priceChangePercent * 100) / 100,\n      margin: Math.round(margin * 100) / 100,\n      adjustmentReason: adjustmentReason.join(', '),\n      pricingTimestamp: new Date().toISOString()\n    }\n  });\n}\n\nreturn processedItems;"
      },
      "typeVersion": 2
    },
    {
      "id": "01ec4551-0a55-41dc-8bed-9537e2498a4d",
      "name": "Apply Promotion Rules",
      "type": "n8n-nodes-base.code",
      "position": [
        304,
        208
      ],
      "parameters": {
        "jsCode": "// Apply Promotion Rules based on customer segments, product categories, seasonal campaigns, and inventory clearance\n\nconst items = $input.all();\nconst promotionalItems = [];\n\nfor (const item of items) {\n  const data = item.json;\n  \n  // Initialize promotion fields\n  let promotionType = 'none';\n  let discountPercentage = 0;\n  let promotionReason = [];\n  \n  // Extract relevant data\n  const customerSegment = data.customerSegment || data.customer_segment || 'standard';\n  const productCategory = data.productCategory || data.category || 'general';\n  const inventoryLevel = data.inventoryLevel || data.stock_level || 100;\n  const productPrice = data.price || data.product_price || 0;\n  const purchaseHistory = data.purchaseHistory || data.total_purchases || 0;\n  \n  // Get current date for seasonal campaigns\n  const currentDate = new Date();\n  const currentMonth = currentDate.getMonth() + 1; // 1-12\n  const currentDay = currentDate.getDate();\n  \n  // Rule 1: Customer Segment-based Promotions\n  if (customerSegment === 'vip' || customerSegment === 'premium') {\n    discountPercentage = Math.max(discountPercentage, 15);\n    promotionType = 'vip_discount';\n    promotionReason.push('VIP Customer Loyalty Discount');\n  } else if (customerSegment === 'loyal' && purchaseHistory > 5) {\n    discountPercentage = Math.max(discountPercentage, 10);\n    promotionType = 'loyalty_discount';\n    promotionReason.push('Loyal Customer Appreciation');\n  } else if (customerSegment === 'new' || purchaseHistory === 0) {\n    discountPercentage = Math.max(discountPercentage, 20);\n    promotionType = 'new_customer_welcome';\n    promotionReason.push('New Customer Welcome Offer');\n  }\n  \n  // Rule 2: Product Category Promotions\n  if (productCategory === 'electronics') {\n    discountPercentage = Math.max(discountPercentage, 12);\n    promotionType = 'category_promo';\n    promotionReason.push('Electronics Flash Sale');\n  } else if (productCategory === 'fashion' || productCategory === 'clothing') {\n    discountPercentage = Math.max(discountPercentage, 25);\n    promotionType = 'category_promo';\n    promotionReason.push('Fashion Week Special');\n  } else if (productCategory === 'home' || productCategory === 'furniture') {\n    discountPercentage = Math.max(discountPercentage, 18);\n    promotionType = 'category_promo';\n    promotionReason.push('Home Makeover Sale');\n  }\n  \n  // Rule 3: Seasonal Campaign Promotions\n  // Black Friday (November)\n  if (currentMonth === 11 && currentDay >= 20 && currentDay <= 30) {\n    discountPercentage = Math.max(discountPercentage, 40);\n    promotionType = 'seasonal_campaign';\n    promotionReason.push('Black Friday Mega Sale');\n  }\n  // Holiday Season (December)\n  else if (currentMonth === 12) {\n    discountPercentage = Math.max(discountPercentage, 30);\n    promotionType = 'seasonal_campaign';\n    promotionReason.push('Holiday Season Special');\n  }\n  // Summer Sale (June-August)\n  else if (currentMonth >= 6 && currentMonth <= 8) {\n    discountPercentage = Math.max(discountPercentage, 20);\n    promotionType = 'seasonal_campaign';\n    promotionReason.push('Summer Clearance Sale');\n  }\n  // Spring Sale (March-May)\n  else if (currentMonth >= 3 && currentMonth <= 5) {\n    discountPercentage = Math.max(discountPercentage, 15);\n    promotionType = 'seasonal_campaign';\n    promotionReason.push('Spring Refresh Sale');\n  }\n  \n  // Rule 4: Inventory Clearance (High Priority)\n  if (inventoryLevel > 200) {\n    discountPercentage = Math.max(discountPercentage, 35);\n    promotionType = 'clearance';\n    promotionReason.push('Overstock Clearance - Limited Time');\n  } else if (inventoryLevel > 100) {\n    discountPercentage = Math.max(discountPercentage, 25);\n    promotionType = 'clearance';\n    promotionReason.push('Inventory Reduction Sale');\n  } else if (inventoryLevel < 10) {\n    // Low stock - no discount, create urgency\n    promotionType = 'urgency';\n    promotionReason.push('Low Stock Alert - Order Now');\n  }\n  \n  // Calculate final price\n  const discountAmount = (productPrice * discountPercentage) / 100;\n  const finalPrice = productPrice - discountAmount;\n  \n  // Build promotional item\n  promotionalItems.push({\n    json: {\n      ...data,\n      promotion: {\n        applied: discountPercentage > 0,\n        type: promotionType,\n        discountPercentage: discountPercentage,\n        discountAmount: Math.round(discountAmount * 100) / 100,\n        originalPrice: productPrice,\n        finalPrice: Math.round(finalPrice * 100) / 100,\n        reasons: promotionReason,\n        campaignDate: currentDate.toISOString(),\n        urgency: inventoryLevel < 10 ? 'high' : inventoryLevel < 50 ? 'medium' : 'low'\n      },\n      promotionApplied: true,\n      processedAt: new Date().toISOString()\n    }\n  });\n}\n\nreturn promotionalItems;"
      },
      "typeVersion": 2
    },
    {
      "id": "d20b248d-1673-4dd7-a2d7-12bf28cd046b",
      "name": "Apply Replenishment Rules",
      "type": "n8n-nodes-base.code",
      "position": [
        528,
        208
      ],
      "parameters": {
        "jsCode": "// Calculate replenishment quantities based on demand forecast, lead times, safety stock levels, and supplier constraints\n\nconst items = $input.all();\nconst replenishmentResults = [];\n\nfor (const item of items) {\n  const data = item.json;\n  \n  // Extract relevant data\n  const currentStock = data.currentStock || 0;\n  const demandForecast = data.demandForecast || 0;\n  const leadTimeDays = data.leadTimeDays || 7;\n  const safetyStockLevel = data.safetyStockLevel || 0;\n  const supplierMinOrder = data.supplierMinOrder || 1;\n  const supplierMaxOrder = data.supplierMaxOrder || 10000;\n  const productId = data.productId || data.id;\n  \n  // Calculate daily demand rate\n  const dailyDemand = demandForecast / 30; // Assuming monthly forecast\n  \n  // Calculate lead time demand\n  const leadTimeDemand = dailyDemand * leadTimeDays;\n  \n  // Calculate reorder point (lead time demand + safety stock)\n  const reorderPoint = leadTimeDemand + safetyStockLevel;\n  \n  // Calculate optimal order quantity\n  let orderQuantity = 0;\n  \n  if (currentStock <= reorderPoint) {\n    // Calculate quantity needed to reach target stock level\n    const targetStock = reorderPoint + (dailyDemand * 30); // 30 days of stock\n    orderQuantity = Math.max(0, targetStock - currentStock);\n    \n    // Apply supplier constraints\n    orderQuantity = Math.max(orderQuantity, supplierMinOrder);\n    orderQuantity = Math.min(orderQuantity, supplierMaxOrder);\n    \n    // Round up to nearest whole number\n    orderQuantity = Math.ceil(orderQuantity);\n  }\n  \n  // Calculate days until stockout\n  const daysUntilStockout = currentStock > 0 ? currentStock / dailyDemand : 0;\n  \n  // Determine urgency level\n  let urgency = 'low';\n  if (currentStock <= safetyStockLevel) {\n    urgency = 'critical';\n  } else if (currentStock <= reorderPoint) {\n    urgency = 'high';\n  } else if (daysUntilStockout <= leadTimeDays * 2) {\n    urgency = 'medium';\n  }\n  \n  replenishmentResults.push({\n    json: {\n      ...data,\n      replenishment: {\n        productId,\n        currentStock,\n        demandForecast,\n        dailyDemand: Math.round(dailyDemand * 100) / 100,\n        reorderPoint: Math.ceil(reorderPoint),\n        safetyStockLevel,\n        orderQuantity,\n        leadTimeDays,\n        daysUntilStockout: Math.round(daysUntilStockout * 10) / 10,\n        urgency,\n        shouldReorder: orderQuantity > 0,\n        supplierConstraints: {\n          minOrder: supplierMinOrder,\n          maxOrder: supplierMaxOrder\n        },\n        calculatedAt: new Date().toISOString()\n      }\n    }\n  });\n}\n\nreturn replenishmentResults;"
      },
      "typeVersion": 2
    },
    {
      "id": "745fbd00-297b-433b-bea7-f16504a1dbe6",
      "name": "Check for Exceptions",
      "type": "n8n-nodes-base.if",
      "position": [
        752,
        208
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "leftValue": "",
            "caseSensitive": false,
            "typeValidation": "loose"
          },
          "combinator": "or",
          "conditions": [
            {
              "id": "id-1",
              "operator": {
                "type": "number",
                "operation": "lt"
              },
              "leftValue": "={{ $json.currentStock }}",
              "rightValue": "={{ $('Workflow Configuration').first().json.lowStockThreshold }}"
            },
            {
              "id": "id-2",
              "operator": {
                "type": "number",
                "operation": "lt"
              },
              "leftValue": "={{ $json.sentimentScore }}",
              "rightValue": "={{ $('Workflow Configuration').first().json.negativeSentimentThreshold }}"
            },
            {
              "id": "id-3",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.actionRequired }}",
              "rightValue": "true"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "b03bb460-1c02-4089-b1ac-009eb6340461",
      "name": "Merge Analysis Results",
      "type": "n8n-nodes-base.merge",
      "position": [
        -368,
        560
      ],
      "parameters": {
        "numberInputs": 3
      },
      "typeVersion": 3.2
    },
    {
      "id": "45c21d19-bed5-4f6c-a85c-862c0fd8ec8e",
      "name": "Wait for Manual Review",
      "type": "n8n-nodes-base.wait",
      "position": [
        976,
        128
      ],
      "parameters": {
        "resume": "webhook",
        "options": {},
        "resumeAmount": 24,
        "limitWaitTime": true
      },
      "typeVersion": 1.1
    },
    {
      "id": "8aff2f23-83a6-4c6c-82ad-5a2755d425bf",
      "name": "Store in CRM Database",
      "type": "n8n-nodes-base.postgres",
      "position": [
        1200,
        208
      ],
      "parameters": {
        "table": {
          "__rl": true,
          "mode": "name",
          "value": "<__PLACEHOLDER_VALUE__CRM table name__>"
        },
        "schema": {
          "__rl": true,
          "mode": "list",
          "value": "public"
        },
        "columns": {
          "value": {
            "status": "={{ $json.status }}",
            "orderId": "={{ $json.orderId }}",
            "orderDate": "={{ $json.orderDate }}",
            "customerId": "={{ $json.customerId }}",
            "totalAmount": "={{ $json.totalAmount }}",
            "sentimentScore": "={{ $json.sentimentScore }}",
            "recommendations": "={{ $json.recommendations }}"
          },
          "mappingMode": "defineBelow"
        },
        "options": {}
      },
      "typeVersion": 2.6
    },
    {
      "id": "5bb5f1fe-4015-443c-921f-c12cf35a42e9",
      "name": "Store in Inventory Database",
      "type": "n8n-nodes-base.postgres",
      "position": [
        -640,
        1280
      ],
      "parameters": {
        "table": {
          "__rl": true,
          "mode": "name",
          "value": "<__PLACEHOLDER_VALUE__Inventory table name__>"
        },
        "schema": {
          "__rl": true,
          "mode": "list",
          "value": "public"
        },
        "columns": {
          "value": {
            "productId": "={{ $json.productId }}",
            "lastUpdated": "={{ $json.lastUpdated }}",
            "currentStock": "={{ $json.currentStock }}",
            "reorderPoint": "={{ $json.reorderPoint }}",
            "forecastedDemand": "={{ $json.forecastedDemand }}"
          },
          "schema": [
            {
              "id": "productId",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "productId",
              "defaultMatch": true,
              "canBeUsedToMatch": true
            },
            {
              "id": "currentStock",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "currentStock",
              "defaultMatch": false,
              "canBeUsedToMatch": false
            },
            {
              "id": "reorderPoint",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "reorderPoint",
              "defaultMatch": false,
              "canBeUsedToMatch": false
            },
            {
              "id": "lastUpdated",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "lastUpdated",
              "defaultMatch": false,
              "canBeUsedToMatch": false
            },
            {
              "id": "forecastedDemand",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "forecastedDemand",
              "defaultMatch": false,
              "canBeUsedToMatch": false
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "productId"
          ]
        },
        "options": {},
        "operation": "update"
      },
      "typeVersion": 2.6
    },
    {
      "id": "bdd3564a-f903-4ae7-a263-6afab58b2b8b",
      "name": "Notify Supply Chain Team",
      "type": "n8n-nodes-base.slack",
      "position": [
        -432,
        1296
      ],
      "parameters": {
        "text": "=\u26a0\ufe0f Inventory Alert\n\nProduct: {{ $json.productName }}\nCurrent Stock: {{ $json.currentStock }}\nReorder Point: {{ $json.reorderPoint }}\nForecasted Demand: {{ $json.forecastedDemand }}\n\nAction: Replenishment order recommended",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "id",
          "value": "<__PLACEHOLDER_VALUE__Supply Chain Slack channel ID__>"
        },
        "otherOptions": {},
        "authentication": "oAuth2"
      },
      "credentials": {
        "slackOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.4
    },
    {
      "id": "53674ff3-8c07-4a66-b90a-f2afa3823006",
      "name": "Notify Customer Support Team",
      "type": "n8n-nodes-base.slack",
      "position": [
        -640,
        1472
      ],
      "parameters": {
        "text": "=\ud83d\udd14 Social Media Mention\n\nPlatform: {{ $json.platform }}\nAuthor: {{ $json.author }}\nContent: {{ $json.content }}\nEngagement: {{ $json.engagement }}\n\nRequires monitoring and potential response",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "id",
          "value": "<__PLACEHOLDER_VALUE__Customer Support Slack channel ID__>"
        },
        "otherOptions": {},
        "authentication": "oAuth2"
      },
      "credentials": {
        "slackOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.4
    },
    {
      "id": "53973b60-c07c-4728-8206-b4d5b96cbb11",
      "name": "Send Email Campaign",
      "type": "n8n-nodes-base.emailSend",
      "position": [
        1648,
        208
      ],
      "parameters": {
        "html": "=<h1>Hello {{ $json.customerName }}!</h1>\n\n<p>We've curated some special recommendations just for you based on your recent activity:</p>\n\n<h2>Recommended Products</h2>\n<ul>\n{{ $json.recommendations }}\n</ul>\n\n<h2>Exclusive Offers</h2>\n<p>{{ $json.promotionalOffers }}</p>\n\n<p>Thank you for being a valued customer!</p>\n\n<p>Best regards,<br>Your E-commerce Team</p>",
        "options": {},
        "subject": "Personalized Recommendations Just for You",
        "toEmail": "={{ $json.customerEmail }}",
        "fromEmail": "<__PLACEHOLDER_VALUE__Sender email address__>"
      },
      "typeVersion": 2.1
    },
    {
      "id": "93bb9492-a6db-4805-9818-8d041f5eb0e7",
      "name": "Prepare Campaign Data",
      "type": "n8n-nodes-base.set",
      "position": [
        1424,
        208
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "id-1",
              "name": "customerEmail",
              "type": "string",
              "value": "={{ $json.email || $json.customerEmail }}"
            },
            {
              "id": "id-2",
              "name": "customerName",
              "type": "string",
              "value": "={{ $json.name || $json.customerName }}"
            },
            {
              "id": "id-3",
              "name": "recommendationsList",
              "type": "string",
              "value": "={{ $json.recommendations }}"
            },
            {
              "id": "id-4",
              "name": "campaignId",
              "type": "string",
              "value": "={{ $now.toFormat('yyyyMMdd') }}-personalized"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "3c704851-32cd-4393-87f1-6ec899f0d238",
      "name": "Remove Duplicate Records",
      "type": "n8n-nodes-base.removeDuplicates",
      "position": [
        -144,
        208
      ],
      "parameters": {
        "compare": "selectedFields",
        "options": {},
        "fieldsToCompare": "orderId, customerId"
      },
      "typeVersion": 2
    },
    {
      "id": "11098ffc-acf5-480c-a0c1-28b2df720d12",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1824,
        -288
      ],
      "parameters": {
        "width": 752,
        "height": 224,
        "content": "## How It Works\nThis workflow automates inventory management and customer engagement for e-commerce businesses and retail operations managing multiple product categories. It solves the critical challenge of maintaining optimal stock levels while personalizing customer communications across order fulfillment, product recommendations, and support interactions. The system processes webhook-triggered data across four parallel streams (orders, reviews, inventory, social media), applies AI-powered analysis for sentiment extraction, pricing optimization, promotion targeting, and demand forecasting, then distributes personalized communications through email campaigns and Slack/Microsoft Teams notifications. This eliminates manual inventory tracking, reduces stockouts, and delivers data-driven customer engagement.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "f9d43e23-e427-4f48-941c-197362a7bbdd",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1008,
        -304
      ],
      "parameters": {
        "width": 496,
        "height": 256,
        "content": "## Setup Steps\n1. Configure webhook URLs for orders, reviews, inventory systems, and social media platforms\n2. Add AI model API credentials (OpenAI/Anthropic) for sentiment, pricing\n3. Connect CRM database for customer profile management and segmentation\n4. Set up email service (Gmail/SendGrid) with campaign templates for personalized communications\n5. Integrate Slack workspace or Microsoft Teams channels for internal inventory alerts"
      },
      "typeVersion": 1
    },
    {
      "id": "a9fe5806-bfe7-4fe5-86e1-e62443e98c12",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -448,
        -416
      ],
      "parameters": {
        "color": 4,
        "width": 400,
        "height": 368,
        "content": "## Prerequisites\nActive e-commerce platform with webhook support, AI service API keys\n## Use Cases\nMulti-channel retailers optimizing stock across locations, subscription box services  \n## Customization\nAdjust AI prompts for industry-specific sentiment rules, modify inventory thresholds for restocking alerts\n## Benefits\nReduces inventory management overhead by 70%, prevents stockouts through predictive forecasting"
      },
      "typeVersion": 1
    },
    {
      "id": "8d0b01bc-faf7-45d6-a4f6-554eb2e8b298",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -192,
        0
      ],
      "parameters": {
        "color": 7,
        "width": 2208,
        "height": 512,
        "content": "## Automated Engagement Distribution\n**Why:** Coordinated delivery through CRM, email campaigns, and team notifications ensures stakeholders receive relevant updates while customers experience personalized interactions."
      },
      "typeVersion": 1
    },
    {
      "id": "56751703-bd02-4237-b685-c8a60276cbe6",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -768,
        0
      ],
      "parameters": {
        "color": 7,
        "width": 544,
        "height": 1680,
        "content": "## AI-Powered Intelligence Analysis\n**Why:** Parallel AI agents process data for sentiment analysis, pricing strategy, promotional targeting, and inventory forecasting, transforming raw data into actionable insights."
      },
      "typeVersion": 1
    },
    {
      "id": "512f5dc0-57ea-43bf-b01c-a11e5b91d829",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1856,
        16
      ],
      "parameters": {
        "color": 7,
        "width": 1056,
        "height": 1584,
        "content": "## Multi-Channel Data Ingestion\n**Why:** Webhook triggers capture real-time events from orders, reviews, inventory, and social platforms, ensuring immediate response to business-critical changes."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "availableInMCP": false,
    "executionOrder": "v1"
  },
  "versionId": "93f013e0-9e94-41c3-9f7c-6a868ce4a840",
  "connections": {
    "Validate Orders": {
      "main": [
        [
          {
            "node": "AI Agent - Demand Forecasting",
            "type": "main",
            "index": 0
          },
          {
            "node": "AI Agent - Product Recommendations",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Normalize Orders": {
      "main": [
        [
          {
            "node": "Validate Orders",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Validate Reviews": {
      "main": [
        [
          {
            "node": "AI Agent - Sentiment Analysis",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Normalize Reviews": {
      "main": [
        [
          {
            "node": "Validate Reviews",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent - Sentiment Analysis",
            "type": "ai_languageModel",
            "index": 0
          },
          {
            "node": "AI Agent - Demand Forecasting",
            "type": "ai_languageModel",
            "index": 0
          },
          {
            "node": "AI Agent - Product Recommendations",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Route by Data Type": {
      "main": [
        [
          {
            "node": "Normalize Orders",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Normalize Reviews",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Normalize Inventory",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Normalize Social Media",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Validate Inventory": {
      "main": [
        [
          {
            "node": "Store in Inventory Database",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Apply Pricing Rules": {
      "main": [
        [
          {
            "node": "Apply Promotion Rules",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Normalize Inventory": {
      "main": [
        [
          {
            "node": "Validate Inventory",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check for Exceptions": {
      "main": [
        [
          {
            "node": "Wait for Manual Review",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Store in CRM Database",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Apply Promotion Rules": {
      "main": [
        [
          {
            "node": "Apply Replenishment Rules",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Campaign Data": {
      "main": [
        [
          {
            "node": "Send Email Campaign",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Store in CRM Database": {
      "main": [
        [
          {
            "node": "Prepare Campaign Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Validate Social Media": {
      "main": [
        [
          {
            "node": "Notify Customer Support Team",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Webhook - Ingest Data": {
      "main": [
        [
          {
            "node": "Workflow Configuration",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge Analysis Results": {
      "main": [
        [
          {
            "node": "Remove Duplicate Records",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Normalize Social Media": {
      "main": [
        [
          {
            "node": "Validate Social Media",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait for Manual Review": {
      "main": [
        [
          {
            "node": "Store in CRM Database",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Workflow Configuration": {
      "main": [
        [
          {
            "node": "Route by Data Type",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Remove Duplicate Records": {
      "main": [
        [
          {
            "node": "Apply Pricing Rules",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Apply Replenishment Rules": {
      "main": [
        [
          {
            "node": "Check for Exceptions",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Store in Inventory Database": {
      "main": [
        [
          {
            "node": "Notify Supply Chain Team",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output - Forecast": {
      "ai_outputParser": [
        [
          {
            "node": "AI Agent - Demand Forecasting",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "AI Agent - Demand Forecasting": {
      "main": [
        [
          {
            "node": "Merge Analysis Results",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "AI Agent - Sentiment Analysis": {
      "main": [
        [
          {
            "node": "Merge Analysis Results",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output - Sentiment": {
      "ai_outputParser": [
        [
          {
            "node": "AI Agent - Sentiment Analysis",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "AI Agent - Product Recommendations": {
      "main": [
        [
          {
            "node": "Merge Analysis Results",
            "type": "main",
            "index": 2
          }
        ]
      ]
    },
    "Structured Output - Recommendations": {
      "ai_outputParser": [
        [
          {
            "node": "AI Agent - Product Recommendations",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    }
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

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

About this workflow

This workflow automates inventory management and customer engagement for e-commerce businesses and retail operations managing multiple product categories. It solves the critical challenge of maintaining optimal stock levels while personalizing customer communications across…

Source: https://n8n.io/workflows/12791/ — 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 automates customer feedback processing by analyzing sentiment, identifying key issues, generating personalized responses, and escalating critical cases to support teams when required. De

Redis, Postgres, Agent +7
AI & RAG

This workflow automates veterinary clinic operations and client communications for animal hospitals and veterinary practices managing appointments, inventory, and patient care. It solves the dual chal

HTTP Request, Agent, OpenAI Chat +4
AI & RAG

Automate peer review assignment and grading with AI-powered evaluation. Designed for educators managing collaborative assessments efficiently.

OpenAI Chat, Agent, Output Parser Structured +4
AI & RAG

This workflow transforms natural language queries into research reports through a five-stage AI pipeline. When triggered via webhook (typically from Google Sheets using the companion [](https://gist.g

Redis, Agent, Output Parser Structured +7
AI & RAG

This workflow automates end-to-end carbon emissions monitoring, strategy optimisation, and ESG reporting using a multi-agent AI supervisor architecture in n8n. Designed for sustainability managers, ES

Agent, OpenAI Chat, Output Parser Structured +10