No-code automations (n8n, Make, Zapier)

The n8n templates that ship with StockAI, how to import them and what each one does, and how to build the same flows in Make or Zapier.

On this page
  1. The templates
  2. Importing a webhook template
  3. Importing the Google Drive template
  4. Make and Zapier

With webhooks and the API you can connect StockAI to Slack, Google Sheets, Jira or Google Drive without writing a program. StockAI ships three templates for n8n, in the integrations/n8n/ folder of its source code.

The templates

FileWhat it doesNeeds
order-approved-to-slack-and-sheets.jsonWhen an order is approved (purchase_order.approved), posts a message to a Slack channel and appends a row to a Google Sheet with order, warehouse, SKUs, units, value, approved amount, approver, event id and date.A StockAI webhook, Slack and Google Sheets.
stockout-imminent-to-jira.jsonWhen a SKU enters stockout risk (stockout.imminent), creates a Jira issue: "Stockout risk: SKU at warehouse (N days of cover)".A StockAI webhook and Jira.
drive-file-to-dataset.jsonWhen a new file lands in a Google Drive folder, downloads it and replaces the file of a StockAI sales source (POST /api/v1/data-sources/{id}/file). If StockAI refuses it, posts to Slack.A write key, Google Drive and Slack.

Importing a webhook template

  1. In n8n, create a new workflow and import the JSON file into it (workflow menu → import from file).
  2. Open the first node, "StockAI webhook", and copy its production URL.
  3. In StockAI, open Automation → "Automatic notices", press "Add webhook", paste that URL and tick only the template's event (purchase_order.approved or stockout.imminent). Save.
  4. Copy the "Webhook signing secret" (shown only once).
  5. In n8n, put that secret in the environment variable STOCKAI_WEBHOOK_SECRET and allow the crypto module with NODE_FUNCTION_ALLOW_BUILTIN=crypto.
  6. Pick your credentials and fill in the blanks: the Slack channel and the Sheet, or the Jira project and issue type.
  7. Activate the workflow and, in StockAI, press "Send test" on the webhook. Check "Deliveries" to see that it arrived.

Importing the Google Drive template

  1. Find your sales source's id with GET /data-sources or under My sales.
  2. Import drive-file-to-dataset.json into n8n.
  3. In the "Replace the dataset" node, replace REPLACE_WITH_DATA_SOURCE_ID with that id. If your StockAI is not app.stockai.es, change the domain too.
  4. Create an n8n "Header Auth" credential named Authorization with value Bearer sk_live_... (a write key) and assign it to that node.
  5. Pick the Drive folder in the first node and the Slack channel in "Say it failed".
  6. Activate the workflow and drop a file in the folder. The source keeps its column mapping, and if the session has a schedule, StockAI retrains on its own.

Make and Zapier

Make and Zapier do not import a file from us, so the same flow is built with their generic modules:

Receiving a StockAI event
Make: "Custom webhook". Zapier: "Catch Hook". Paste its URL when you create the webhook in StockAI.
Verifying the signature
Needs code. In Zapier, a "Code by Zapier" step with the recipe below; in Make, a module that computes HMAC-SHA256.
Calling StockAI
Make: "HTTP > Make a request". Zapier: "Webhooks by Zapier > Custom Request". URL https://app.stockai.es/api/v1/<path>, header Authorization: Bearer <key> (a write key for POST/PATCH/DELETE). A file goes as multipart/form-data with the field file.
// Code by Zapier (JavaScript). Inputs: secret, signature (the X-StockAI-Signature header), body (raw text)
const crypto = require('crypto')
const parts = Object.fromEntries(inputData.signature.split(',').map(p => p.split('=')))
const fresh = Math.abs(Date.now() / 1000 - Number(parts.t)) <= 300
const expected = crypto.createHmac('sha256', inputData.secret)
  .update(parts.t + '.' + inputData.body).digest('hex')
output = [{ valid: fresh && expected === parts.v1 }]

Mind: the code step must receive the delivery's raw body, exactly as it arrived. If the tool has already parsed it as JSON and rebuilds it, the signature will not match.