AutomationFlowsE-commerce › Monitor Woocommerce Inventory Daily and Send Slack Alerts with Supabase

Monitor Woocommerce Inventory Daily and Send Slack Alerts with Supabase

ByWeblineIndia @weblineindia on n8n.io

This workflow automatically monitors your WooCommerce store inventory, calculates stock health based on recent sales, classifies products, computes reorder quantities, assigns urgency levels and sends actionable alerts to Slack.

Cron / scheduled trigger★★★★☆ complexity20 nodesWooCommerceSlackSupabase
E-commerce Trigger: Cron / scheduled Nodes: 20 Complexity: ★★★★☆ Added:

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

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": "8C7X9kpfFrRK0sR5",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Daily Inventory Monitoring & Reorder System",
  "tags": [],
  "nodes": [
    {
      "id": "52a8f525-2e28-467f-a155-40b50fd3beee",
      "name": "Inventory Classification",
      "type": "n8n-nodes-base.code",
      "position": [
        432,
        16
      ],
      "parameters": {
        "jsCode": "const results = [];\n\nfor (const item of items) {\n  const {\n    product_id,\n    sku,\n    product_name,\n    stock_quantity,\n    avg_daily_demand,\n    manage_stock\n  } = item.json;\n\n  // ADD THIS BLOCK (TOP of loop)\n  if (!manage_stock) {\n    results.push({\n      json: {\n        product_id,\n        sku,\n        product_name,\n        stock_quantity,\n        avg_daily_demand,\n        days_of_stock_left: null,\n        inventory_status: 'Not Managed',\n        reorder_needed: false,\n        recommended_action: 'Stock not managed'\n      }\n    });\n    continue;\n  }\n  // END ADDITION\n\n  let days_of_stock_left = null;\n  let inventory_status = '';\n  let reorder_needed = false;\n  let recommended_action = '';\n\n  if (avg_daily_demand > 0) {\n    days_of_stock_left = stock_quantity / avg_daily_demand;\n  }\n\n  if (avg_daily_demand === 0 && stock_quantity > 0) {\n    inventory_status = 'Consider Discontinue';\n    recommended_action = 'Stop restocking / apply discount';\n  } else if (days_of_stock_left < 15) {\n    inventory_status = 'At Risk';\n    reorder_needed = true;\n    recommended_action = 'Reorder immediately';\n  } else if (days_of_stock_left <= 45) {\n    inventory_status = 'Steady';\n    recommended_action = 'Monitor stock';\n  } else {\n    inventory_status = 'Top Performer';\n    recommended_action = 'Maintain stock level';\n  }\n\n  results.push({\n    json: {\n      product_id,\n      sku,\n      product_name,\n      stock_quantity,\n      avg_daily_demand,\n      days_of_stock_left,\n      inventory_status,\n      reorder_needed,\n      recommended_action\n    }\n  });\n}\n\nreturn results;\n"
      },
      "typeVersion": 2
    },
    {
      "id": "64858d75-d212-4246-ba72-a47a00dabcd6",
      "name": "Run Daily Invetory check",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -944,
        -16
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "triggerAtHour": 2
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "54e933e4-340c-4a72-8f18-2ccc79d9c2ee",
      "name": "Fecth Products",
      "type": "n8n-nodes-base.wooCommerce",
      "position": [
        -336,
        -96
      ],
      "parameters": {
        "options": {
          "status": "publish"
        },
        "operation": "getAll",
        "returnAll": true
      },
      "credentials": {
        "wooCommerceApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "e412507c-3678-4b57-8a83-e983fededad4",
      "name": "Calculate product sales",
      "type": "n8n-nodes-base.code",
      "position": [
        -336,
        96
      ],
      "parameters": {
        "jsCode": "const productSales = {};\n\n// Dates\nconst now = new Date();\nconst thirtyDaysAgo = new Date();\nthirtyDaysAgo.setDate(now.getDate() - 30);\n\n// Loop through orders\nfor (const item of items) {\n  const order = item.json;\n\n  const date_completed = order.date_completed\n    ? new Date(order.date_completed)\n    : null;\n\n  if (!date_completed || date_completed < thirtyDaysAgo) continue;\n\n  for (const li of order.line_items || []) {\n    const product_id = li.product_id;\n    const qty = li.quantity || 0;\n\n    if (!productSales[product_id]) {\n      productSales[product_id] = {\n        product_id,\n        units_sold_last_30_days: 0\n      };\n    }\n\n    productSales[product_id].units_sold_last_30_days += qty;\n  }\n}\n\n// Final output\nreturn Object.values(productSales).map(p => ({\n  json: {\n    product_id: p.product_id,\n    units_sold_last_30_days: p.units_sold_last_30_days,\n    avg_daily_demand: p.units_sold_last_30_days / 30\n  }\n}));\n"
      },
      "typeVersion": 2
    },
    {
      "id": "ec283899-f9ba-4d6a-a2a1-d31068f6141d",
      "name": "Combine products & sales ",
      "type": "n8n-nodes-base.merge",
      "position": [
        -80,
        16
      ],
      "parameters": {},
      "typeVersion": 3.2
    },
    {
      "id": "2685592b-aae5-466e-9c6b-bf2ea414d97b",
      "name": "Attach sales data to products",
      "type": "n8n-nodes-base.code",
      "position": [
        224,
        16
      ],
      "parameters": {
        "jsCode": "const products = [];\nconst salesMap = {};\n\n// Separate inputs\nfor (const item of items) {\n  // Product data\n  if (item.json.stock_quantity !== undefined && item.json.id) {\n    products.push(item.json);\n  }\n\n  // Sales data\n  if (item.json.product_id !== undefined) {\n    salesMap[item.json.product_id] = item.json;\n  }\n}\n\nconst result = [];\n\nfor (const product of products) {\n  const sales = salesMap[product.id] || {\n    units_sold_last_30_days: 0,\n    avg_daily_demand: 0\n  };\n\n  result.push({\n    json: {\n      product_id: product.id,\n      sku: product.sku,\n      product_name: product.name,\n      stock_quantity: product.stock_quantity,\n      manage_stock: product.manage_stock,\n\n      units_sold_last_30_days: sales.units_sold_last_30_days,\n      avg_daily_demand: sales.avg_daily_demand\n    }\n  });\n}\n\nreturn result;\n"
      },
      "typeVersion": 2
    },
    {
      "id": "ddccc243-010b-48ab-823b-8b8f21e47423",
      "name": "Calculate reorder quantity",
      "type": "n8n-nodes-base.code",
      "position": [
        656,
        16
      ],
      "parameters": {
        "jsCode": "const LEAD_TIME_DAYS = 7;\nconst SAFETY_DAYS = 5;\n\nreturn items.map(item => {\n  const d = item.json; \n\n  const dailyDemand = Math.max(d.avg_daily_demand || 0, 0.01);\n\n  const safety_stock =\n    dailyDemand * SAFETY_DAYS;\n\n  const reorder_point =\n    (dailyDemand * LEAD_TIME_DAYS) + safety_stock;\n\n  const target_stock =\n    dailyDemand * (LEAD_TIME_DAYS + SAFETY_DAYS);\n\n  const reorder_qty_raw =\n    Math.ceil(target_stock - d.stock_quantity);\n\n  const reorder_qty =\n    reorder_qty_raw > 0 ? reorder_qty_raw : 0;\n\n  return {\n    json: {\n      ...d,\n      safety_stock: Math.ceil(safety_stock),\n      reorder_point: Math.ceil(reorder_point),\n      target_stock: Math.ceil(target_stock),\n      reorder_qty\n    }\n  };\n});\n"
      },
      "typeVersion": 2
    },
    {
      "id": "e017c643-ac67-463e-a184-1f582c73b617",
      "name": "Set urgency & action plan",
      "type": "n8n-nodes-base.code",
      "position": [
        896,
        16
      ],
      "parameters": {
        "jsCode": "return items.map(item => {\n  const d = item.json;\n\n  let urgency = \"Normal\";\n  let action = d.recommended_action;\n\n  if (d.reorder_qty > 0) {\n    if (d.days_of_stock_left <= 7) {\n      urgency = \"Critical\";\n      action = `Order ${d.reorder_qty} units immediately`;\n    } else if (d.days_of_stock_left <= 14) {\n      urgency = \"High\";\n      action = `Plan reorder of ${d.reorder_qty} units`;\n    } else {\n      urgency = \"Normal\";\n      action = `Monitor \u2013 next reorder ${d.reorder_qty} units`;\n    }\n  }\n\n  return {\n    json: {\n      ...d,\n      urgency_level: urgency,\n      final_recommended_action: action\n    }\n  };\n});\n"
      },
      "typeVersion": 2
    },
    {
      "id": "9d001ee2-d429-43d4-bd3f-e2b65d50cd1e",
      "name": "Check if alerts is needed",
      "type": "n8n-nodes-base.if",
      "position": [
        1120,
        16
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "or",
          "conditions": [
            {
              "id": "4e09bb9b-20c8-497f-b989-1059f41b0598",
              "operator": {
                "name": "filter.operator.equals",
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.urgency_level }}",
              "rightValue": "Critical"
            },
            {
              "id": "7ea8df07-ef2b-4c86-9d2c-32f7eed97b61",
              "operator": {
                "name": "filter.operator.equals",
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.urgency_level }}",
              "rightValue": "High"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "a2ca2ac5-7f83-40cc-90c2-edb99115f8eb",
      "name": "Send critical inventory alert",
      "type": "n8n-nodes-base.slack",
      "position": [
        1488,
        -256
      ],
      "parameters": {
        "text": "=** Inventory Alert ** \nProduct Name: {{ $json.product_name }}\nSKU: {{ $json.sku }} \nStatus: {{ $json.inventory_status }}\nStock:{{ $json.stock_quantity }} \nAction: {{ $json.final_recommended_action }}\nUrgency: {{ $json.urgency_level }}\nReorder Quantity: {{ $json.reorder_qty }}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "C09S57E2JQ2",
          "cachedResultName": "n8n"
        },
        "otherOptions": {
          "includeLinkToWorkflow": false
        }
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "f649391a-afd2-4dfb-9a2d-4a260bdb0460",
      "name": "Save Inventory record to database",
      "type": "n8n-nodes-base.supabase",
      "position": [
        1504,
        224
      ],
      "parameters": {
        "tableId": "Inventory Data",
        "fieldsUi": {
          "fieldValues": [
            {
              "fieldId": "product id",
              "fieldValue": "={{ $json.product_id }}"
            },
            {
              "fieldId": "product name",
              "fieldValue": "={{ $json.product_name }}"
            },
            {
              "fieldId": "inventory status",
              "fieldValue": "={{ $json.inventory_status }}"
            },
            {
              "fieldId": "recommended action",
              "fieldValue": "={{ $json.recommended_action }}"
            },
            {
              "fieldId": "quantity",
              "fieldValue": "={{ $json.stock_quantity }}"
            }
          ]
        }
      },
      "credentials": {
        "supabaseApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "c9a776d4-28ea-4d6b-8b27-abe041f60390",
      "name": "Prepare Inventory summary",
      "type": "n8n-nodes-base.code",
      "position": [
        1792,
        224
      ],
      "parameters": {
        "jsCode": "let totalProducts = 0;\nlet atRisk = 0;\nlet reorderNeeded = 0;\n\nconst lines = [];\n\nfor (const item of items) {\n  const d = item.json;\n\n  totalProducts++;\n\n  // Count At Risk\n  if (d[\"inventory status\"] === \"At Risk\") {\n    atRisk++;\n  }\n\n  // Reorder logic (based on status since reorder flag not stored)\n  if (d[\"inventory status\"] === \"At Risk\") {\n    reorderNeeded++;\n  }\n\n  lines.push(\n    `\u2022 ${d[\"product name\"]} \u2192 ${d[\"inventory status\"]} (Stock: ${d.quantity})`\n  );\n}\n\nreturn [\n  {\n    json: {\n      totalProducts,\n      atRisk,\n      reorderNeeded,\n      summaryText: lines.join(\"\\n\")\n    }\n  }\n];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "1cdaddfa-27aa-476a-8062-1f6864d51465",
      "name": "Send Inventory summry",
      "type": "n8n-nodes-base.slack",
      "position": [
        2048,
        224
      ],
      "parameters": {
        "text": "=*Daily Inventory Summary*\n\nTotal Products Checked: {{ $json.totalProducts }}\nAt Risk Products: {{ $json.atRisk }}\nReorder Needed: {{ $json.reorderNeeded }}\n\n*Product Status Overview*\n{{ $json.summaryText }}\n\nAuto-checked by Inventory System\n",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "C09S57E2JQ2",
          "cachedResultName": "n8n"
        },
        "otherOptions": {
          "includeLinkToWorkflow": false
        }
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "f6eb8edb-6fad-4624-a1b8-11eab8629f82",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1056,
        -96
      ],
      "parameters": {
        "color": 7,
        "width": 304,
        "height": 240,
        "content": "Runs this inventory check automatically every day at the scheduled time."
      },
      "typeVersion": 1
    },
    {
      "id": "2674fb8d-b56d-420b-9461-39969e55d109",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -720,
        -192
      ],
      "parameters": {
        "color": 7,
        "width": 800,
        "height": 464,
        "content": "## Collect Product & Sales Data\nThis step gathers all products from the store, checks how much stock is available, looks at sales from the last 30 days, and combines everything to understand how fast each product is selling."
      },
      "typeVersion": 1
    },
    {
      "id": "5691b0f2-c765-4b9b-9b78-0d48c4bbd28c",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        128,
        -192
      ],
      "parameters": {
        "color": 7,
        "width": 1152,
        "height": 464,
        "content": "## Inventory Evaluation, Planning & Decision\nThis step combines product and sales data, checks stock health based on demand, categorizes products by performance, calculates safety stock and reorder quantity, assigns urgency levels, and finally decides which products need immediate attention and alerts."
      },
      "typeVersion": 1
    },
    {
      "id": "63e20f6e-4fa5-4a4a-8ebc-7c81fd123f75",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1376,
        48
      ],
      "parameters": {
        "color": 7,
        "width": 912,
        "height": 384,
        "content": "## Inventory Record, Summarize & Notify Inventory Status\n\nThis step saves the latest inventory results into the system, creates a daily summary of stock health and risk items, and sends a clear report to the team on Slack so everyone stays informed."
      },
      "typeVersion": 1
    },
    {
      "id": "d7f9f15e-3390-4ad5-a6ae-5149aae36ec7",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1376,
        -352
      ],
      "parameters": {
        "color": 7,
        "width": 320,
        "height": 288,
        "content": "Sends instant Slack alerts for products that require urgent action or immediate reorder."
      },
      "typeVersion": 1
    },
    {
      "id": "c1364a66-d9d8-405c-bad4-95b26bab80fd",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1712,
        -832
      ],
      "parameters": {
        "width": 528,
        "height": 736,
        "content": "## How it works\n\nThis workflow automatically checks your store\u2019s inventory every day and helps you avoid stock issues.\n\nFirst, it pulls all active products and recent completed orders from WooCommerce. Using sales from the last 30 days, it calculates how fast each product is selling.\nNext, it compares current stock with demand to understand how healthy your inventory is.\n\nEach product is then classified into clear categories like Top Performer, Steady, At Risk, or Consider Discontinue. Based on this, the system calculates how much safety stock is needed, when to reorder, and how many units should be ordered.\n\nProducts that need attention are given an urgency level (Normal, High, or Critical).\nImportant items trigger alerts, while all results are saved for reporting. Finally, a daily inventory summary is sent to Slack so the team can quickly review overall stock health without checking multiple systems.\n\nThis process runs automatically and requires no manual effort once set up.\n\n\n## Setup steps\n\n**1.** Connect your WooCommerce account (products and orders).\n\n**2.** Connect Supabase to store inventory records.\n\n**3.** Connect Slack to receive alerts and daily summaries.\n\n**4.** Set the schedule time for daily checks.\n\n**5.** Review stock thresholds (lead time, safety days) if needed.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "37bc4092-a6ed-44ca-b19e-a090f2ee4c5a",
      "name": "Fetch order",
      "type": "n8n-nodes-base.wooCommerce",
      "position": [
        -592,
        96
      ],
      "parameters": {
        "options": {
          "after": "={{$now.minus({ days: 30 }).toISO()}}",
          "status": "completed"
        },
        "resource": "order",
        "operation": "getAll",
        "returnAll": true
      },
      "credentials": {
        "wooCommerceApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "f392dfe3-bba4-4ab3-9c16-94680645466d",
  "connections": {
    "Fetch order": {
      "main": [
        [
          {
            "node": "Calculate product sales",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fecth Products": {
      "main": [
        [
          {
            "node": "Combine products & sales ",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Calculate product sales": {
      "main": [
        [
          {
            "node": "Combine products & sales ",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Inventory Classification": {
      "main": [
        [
          {
            "node": "Calculate reorder quantity",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Run Daily Invetory check": {
      "main": [
        [
          {
            "node": "Fecth Products",
            "type": "main",
            "index": 0
          },
          {
            "node": "Fetch order",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check if alerts is needed": {
      "main": [
        [
          {
            "node": "Send critical inventory alert",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Save Inventory record to database",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Combine products & sales ": {
      "main": [
        [
          {
            "node": "Attach sales data to products",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Inventory summary": {
      "main": [
        [
          {
            "node": "Send Inventory summry",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set urgency & action plan": {
      "main": [
        [
          {
            "node": "Check if alerts is needed",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Calculate reorder quantity": {
      "main": [
        [
          {
            "node": "Set urgency & action plan",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Attach sales data to products": {
      "main": [
        [
          {
            "node": "Inventory Classification",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Save Inventory record to database": {
      "main": [
        [
          {
            "node": "Prepare Inventory summary",
            "type": "main",
            "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 automatically monitors your WooCommerce store inventory, calculates stock health based on recent sales, classifies products, computes reorder quantities, assigns urgency levels and sends actionable alerts to Slack.

Source: https://n8n.io/workflows/14192/ — original creator credit. Request a take-down →

More E-commerce workflows → · Browse all categories →

Related workflows

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

E-commerce

This workflow automatically monitors WooCommerce orders, evaluates them for fraud using multiple checks (address mismatch, high-value orders, suspicious emails, admin orders), calculates a fraud score

WooCommerce, Slack
E-commerce

Automatically track product sales and inventory levels in WooCommerce and trigger reorder notifications when stock runs low or sales spike.

WooCommerce, Gmail, Slack
E-commerce

This workflow automates inventory management and predictive reordering for Shopify stores. It integrates Shopify, Google Sheets, and Slack to monitor inventory levels, calculate dynamic reorder points

Shopify, Google Sheets, Gmail +2
E-commerce

Never miss a revenue-impacting failure. This n8n workflow monitors your Shopify store and triggers an alert if X minutes pass without a single new order. By automatically detecting unexpected drops in

Stop And Error, Slack, Gmail +1
E-commerce

E-commerce store owners and sales managers who want AI-powered insights from their Shopify data without manually crunching numbers every week.

Shopify, HTTP Request, Slack +2