AutomationFlowsSlack & Telegram › Route Low-stock Inventory Alerts From Google Sheets to Slack

Route Low-stock Inventory Alerts From Google Sheets to Slack

ByKanishka Shrivastava @kanishka-shrivastava on n8n.io

This workflow runs every morning to read inventory levels from Google Sheets and post low-stock or out-of-stock alerts to a Slack channel, including supplier contact details, then updates the sheet to avoid repeating the same alert on the same day. Runs daily at the scheduled…

Cron / scheduled trigger★★★★☆ complexity14 nodesGoogle SheetsSlack
Slack & Telegram Trigger: Cron / scheduled Nodes: 14 Complexity: ★★★★☆ Added:

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

This workflow follows the Google Sheets → Slack 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": "YVrB6Y4FQPgeABQY",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Route low-stock inventory alerts to Slack",
  "tags": [],
  "nodes": [
    {
      "id": "b561da51-9632-49aa-ae15-124b7d35dd3f",
      "name": "Template Overview",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -64,
        -48
      ],
      "parameters": {
        "color": 4,
        "width": 680,
        "height": 1012,
        "content": "## \ud83d\udce6 Route Low-Stock Inventory Alerts to Slack\n\n## Who's it for\nSmall retailers, D2C brands, or restaurants tracking inventory in a Google Sheet who want their team notified in Slack when something's running low or has completely run out, with the supplier's contact info right there so reordering doesn't require a separate lookup.\n\n## How it works\nOnce a day, the workflow checks your inventory sheet and classifies every item as healthy, low stock, or out of stock. Items that already got an alert today are skipped, so the channel doesn't get the same item repeated every run. Out-of-stock items get an urgent Slack alert, low-stock items get a less urgent one, both include the supplier's contact so whoever sees it can act immediately. Every alert sent updates the sheet so it isn't repeated.\n\n## How to set up\n1. Connect your Google Sheets credentials and point the workflow at your Inventory sheet.\n2. Connect your Slack credentials and note the channel ID you want alerts posted to.\n3. Make sure your sheet has these columns: row_id, item_name, current_stock, reorder_threshold, unit, supplier_name, supplier_contact, last_alert_date.\n4. Open the Set Configuration node and fill in your Sheet ID and Slack channel ID.\n5. Set your preferred check time in the Schedule Trigger.\n6. Activate the workflow.\n\n## Requirements\n- Google Sheets account\n- Slack workspace with a bot token\n\n## How to customize\nAdjust reorder_threshold per item in your sheet to control what counts as \"low\" for each product. Edit the alert message templates to match how your team likes to communicate."
      },
      "typeVersion": 1
    },
    {
      "id": "6b9c217e-57ef-4b63-9af9-8ccecc6e592e",
      "name": "Section - Trigger and Setup",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        688,
        304
      ],
      "parameters": {
        "color": 7,
        "width": 680,
        "height": 340,
        "content": "## 1\ufe0f\u20e3 2\ufe0f\u20e3 3\ufe0f\u20e3 Trigger + Configuration + Fetch\nRuns daily, pulls every inventory row. Required columns: row_id, item_name, current_stock, reorder_threshold, unit, supplier_name, supplier_contact, last_alert_date."
      },
      "typeVersion": 1
    },
    {
      "id": "d24e1aaa-7c02-46cd-b000-b1cd57050566",
      "name": "Section - Classify and Filter",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1408,
        272
      ],
      "parameters": {
        "color": 7,
        "width": 500,
        "height": 360,
        "content": "## 4\ufe0f\u20e3 5\ufe0f\u20e3 Classify + Filter\nEach item gets a status (healthy, low_stock, out_of_stock). The filter drops healthy items and anything already alerted today, so the channel doesn't get the same item repeated on every run."
      },
      "typeVersion": 1
    },
    {
      "id": "b7b7f125-a054-49f7-9321-37a9c644b9f3",
      "name": "Section - Urgency Branch",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1952,
        208
      ],
      "parameters": {
        "color": 7,
        "width": 700,
        "height": 604,
        "content": "## 6\ufe0f\u20e3 Branch by Urgency\nOut of stock gets a more urgent-looking alert than low stock, both include the supplier's contact so someone can act on it right away without a separate lookup."
      },
      "typeVersion": 1
    },
    {
      "id": "b454cb16-b50f-444d-a325-206fc415d960",
      "name": "Section - Mark Alerted",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2688,
        288
      ],
      "parameters": {
        "color": 7,
        "width": 320,
        "height": 376,
        "content": "## 7\ufe0f\u20e3 Log the Alert\nBoth branches land here. Updates last_alert_date so this item won't be alerted on again until tomorrow."
      },
      "typeVersion": 1
    },
    {
      "id": "22584e96-293e-4ebc-bb9c-ec2930eedf5c",
      "name": "Every Morning",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        720,
        480
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "triggerAtHour": 8
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "93adffb8-46b5-4b6e-acb9-144e99d6fba6",
      "name": "Set Configuration",
      "type": "n8n-nodes-base.set",
      "position": [
        960,
        480
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "cfg-1",
              "name": "sheet_id",
              "type": "string",
              "value": "REPLACE_WITH_GOOGLE_SHEET_ID"
            },
            {
              "id": "cfg-2",
              "name": "inventory_sheet_name",
              "type": "string",
              "value": "Inventory"
            },
            {
              "id": "cfg-3",
              "name": "slack_channel_id",
              "type": "string",
              "value": "REPLACE_WITH_SLACK_CHANNEL_ID"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "f3d47c7c-0fd7-4a46-b109-ade98d287ea5",
      "name": "Fetch Inventory",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1232,
        480
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $('Set Configuration').item.json.inventory_sheet_name }}"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Set Configuration').item.json.sheet_id }}"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "8a674404-9224-4e0b-b156-0de5e1ab95ed",
      "name": "Compute Stock Status",
      "type": "n8n-nodes-base.code",
      "position": [
        1472,
        480
      ],
      "parameters": {
        "jsCode": "const todayStr = new Date().toISOString().slice(0, 10);\n\nreturn $input.all().map(item => {\n  const m = item.json;\n  const stock = Number(m.current_stock);\n  const threshold = Number(m.reorder_threshold);\n\n  let status = 'healthy';\n  if (stock <= 0) {\n    status = 'out_of_stock';\n  } else if (stock <= threshold) {\n    status = 'low_stock';\n  }\n\n  const alreadyAlertedToday = m.last_alert_date === todayStr;\n\n  return {\n    json: {\n      ...m,\n      status,\n      already_alerted_today: alreadyAlertedToday,\n      today_date: todayStr\n    }\n  };\n});"
      },
      "typeVersion": 2
    },
    {
      "id": "4b7f15e3-dd6a-4ee1-8fe0-f782e97ccc65",
      "name": "Filter Needs Alert",
      "type": "n8n-nodes-base.filter",
      "position": [
        1728,
        480
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "0190e727-d9e2-4be6-a1ec-1bbebdad45ce",
              "operator": {
                "type": "string",
                "operation": "notEquals"
              },
              "leftValue": "={{ $json.status }}",
              "rightValue": "healthy"
            },
            {
              "id": "00d77e20-4080-4a3b-9e43-2fc87d96c155",
              "operator": {
                "type": "boolean",
                "operation": "notEquals"
              },
              "leftValue": "={{ $json.already_alerted_today }}",
              "rightValue": true
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "acab49e5-ef77-465d-a3d6-570d1ee7fa62",
      "name": "Is Out of Stock?",
      "type": "n8n-nodes-base.if",
      "position": [
        2032,
        480
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "8aa8039d-0a7f-4c6b-8c36-f29d9b88d64b",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.status }}",
              "rightValue": "out_of_stock"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "68ae24fa-9ace-4678-b812-764b3ee83315",
      "name": "Send Urgent Slack Alert",
      "type": "n8n-nodes-base.slack",
      "position": [
        2336,
        384
      ],
      "parameters": {
        "text": "=\ud83d\udd34 OUT OF STOCK: {{ $json.item_name }} (0 {{ $json.unit }} left). Reorder from {{ $json.supplier_name }} ({{ $json.supplier_contact }}) today.",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Set Configuration').item.json.slack_channel_id }}"
        },
        "otherOptions": {}
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "9682a090-7895-45f0-8517-1db837f1fb97",
      "name": "Send Low Stock Slack Alert",
      "type": "n8n-nodes-base.slack",
      "position": [
        2352,
        608
      ],
      "parameters": {
        "text": "=\ud83d\udfe1 Running low: {{ $json.item_name }} ({{ $json.current_stock }} {{ $json.unit }} left, reorder threshold is {{ $json.reorder_threshold }}). Supplier: {{ $json.supplier_name }} ({{ $json.supplier_contact }}).",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Set Configuration').item.json.slack_channel_id }}"
        },
        "otherOptions": {}
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "9cd25876-0c93-4540-ade6-7f830d316337",
      "name": "Update Sheet - Mark Alerted",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2736,
        480
      ],
      "parameters": {
        "columns": {
          "value": {
            "row_id": "={{ $json.row_id }}",
            "last_alert_date": "={{ $json.today_date }}"
          },
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "row_id"
          ]
        },
        "options": {},
        "operation": "update",
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $('Set Configuration').item.json.inventory_sheet_name }}"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Set Configuration').item.json.sheet_id }}"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.5
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "availableInMCP": false,
    "executionOrder": "v1"
  },
  "versionId": "004ffeb8-cf89-47d4-b90a-1e020f867995",
  "nodeGroups": [],
  "connections": {
    "Every Morning": {
      "main": [
        [
          {
            "node": "Set Configuration",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Inventory": {
      "main": [
        [
          {
            "node": "Compute Stock Status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Is Out of Stock?": {
      "main": [
        [
          {
            "node": "Send Urgent Slack Alert",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Send Low Stock Slack Alert",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Configuration": {
      "main": [
        [
          {
            "node": "Fetch Inventory",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter Needs Alert": {
      "main": [
        [
          {
            "node": "Is Out of Stock?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Compute Stock Status": {
      "main": [
        [
          {
            "node": "Filter Needs Alert",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Urgent Slack Alert": {
      "main": [
        [
          {
            "node": "Update Sheet - Mark Alerted",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Low Stock Slack Alert": {
      "main": [
        [
          {
            "node": "Update Sheet - Mark Alerted",
            "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 runs every morning to read inventory levels from Google Sheets and post low-stock or out-of-stock alerts to a Slack channel, including supplier contact details, then updates the sheet to avoid repeating the same alert on the same day. Runs daily at the scheduled…

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

More Slack & Telegram workflows → · Browse all categories →

Related workflows

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

Slack & Telegram

This workflow continuously monitors the Meta Ads Library for new creatives from a specific competitor pages, logs them into Google Sheets, and sends a concise Telegram notification with the number of

HTTP Request, Telegram, Google Sheets +1
Slack & Telegram

Enhance financial oversight with this automated n8n workflow. Triggered every 5 minutes, it fetches real-time bank transactions via an API, enriches and transforms the data, and applies smart logic to

HTTP Request, Email Send, Google Sheets +1
Slack & Telegram

This workflow automates competitive price intelligence using Bright Data's enterprise web scraping API. On a scheduled basis (default: daily at 9 AM), the system loops through configured competitor pr

HTTP Request, Google Sheets, Slack +1
Slack & Telegram

Ensure your customer SLAs never slip with this n8n automation template. The workflow runs on a schedule, fetching open tickets from Zendesk, calculating SLA time remaining, and sending proactive alert

Zendesk, Slack, Google Sheets
Slack & Telegram

&gt; n8n, Binance API, Google Sheets, Slack, Telegram, Jira & Email

HTTP Request, Google Sheets, Slack +3