DEV Community

Alex Kane
Alex Kane

Posted on

n8n for Pet Industry B2B: 5 Automations for Wholesale Distributors and Pet Brands (Free Workflow JSON)

If you run wholesale distribution, a pet food brand, or a veterinary supply company, you already know the chaos: retailer reorders coming in by email, compliance deadlines scattered across spreadsheets, AR aging reports built manually every Friday.

n8n is a self-hostable workflow automation platform that lets you wire these together — and because it runs on your own server, your pricing contracts, ingredient formulas, and retailer data never touch a third-party cloud.

Here are 5 workflows that B2B pet industry teams are using to cut ops overhead. Full importable JSON included.


1. Retailer Low-Stock Alert & Reorder Draft

The problem: Key retail accounts run out of your product. You find out when they stop ordering.

The workflow:

  • Schedule trigger: daily 8 AM
  • Google Sheets: read retailer inventory levels (sync from EDI or manual update)
  • Code node: flag SKUs below reorder threshold per account tier
  • IF node: if high-value account (>$50k/year) → Slack alert to #key-accounts
  • Gmail node: draft reorder suggestion email to retailer buying team
{
  "nodes": [
    {"type": "n8n-nodes-base.scheduleTrigger", "parameters": {"rule": {"interval": [{"field": "hours", "hoursInterval": 24}]}}},
    {"type": "n8n-nodes-base.googleSheets", "parameters": {"operation": "readRows", "sheetId": "YOUR_SHEET_ID", "range": "Inventory!A:F"}},
    {"type": "n8n-nodes-base.code", "parameters": {"jsCode": "return items.filter(i => i.json.current_stock < i.json.reorder_point).map(i => ({json: {...i.json, tier: i.json.annual_revenue > 50000 ? 'KEY' : 'STANDARD'}}))"}},
    {"type": "n8n-nodes-base.if", "parameters": {"conditions": {"string": [{"value1": "={{$json.tier}}", "value2": "KEY"}]}}},
    {"type": "n8n-nodes-base.slack", "parameters": {"channel": "#key-accounts", "text": "=Low stock alert: {{$json.retailer_name}} — {{$json.sku}} at {{$json.current_stock}} units"}},
    {"type": "n8n-nodes-base.gmail", "parameters": {"operation": "sendEmail", "subject": "=Reorder reminder: {{$json.sku}}", "message": "=Hi {{$json.buyer_name}},\n\nYour {{$json.sku}} inventory is at {{$json.current_stock}} units (reorder point: {{$json.reorder_point}}). Ready to place a reorder?\n\nBest,\nSales Team"}}
  ]
}
Enter fullscreen mode Exit fullscreen mode

2. New Retailer Account Onboarding Sequence

The problem: A new wholesale account signs up and gets a welcome email. Then silence for 3 weeks until they finally call with a question.

The workflow:

  • Trigger: Google Sheets row added (new account row from your CRM export)
  • Gmail: Day 1 welcome + portal access link + account manager intro
  • Wait 3 days
  • Gmail: Day 4 — full product catalog PDF + pricing tiers + minimum order info
  • Wait 4 days
  • Gmail: Day 8 — "how's onboarding going?" check-in + FAQ link
  • Slack: notify CSM/account manager each step
{
  "nodes": [
    {"type": "n8n-nodes-base.googleSheetsTrigger", "parameters": {"sheetId": "YOUR_ACCOUNTS_SHEET", "range": "Accounts!A:G", "events": ["rowAdded"]}},
    {"type": "n8n-nodes-base.gmail", "parameters": {"subject": "=Welcome to our wholesale program, {{$json.company_name}}", "message": "=Hi {{$json.contact_name}},\n\nWelcome! Your account manager {{$json.am_name}} will be your point of contact.\n\nPortal: https://portal.yourcompany.com"}},
    {"type": "n8n-nodes-base.wait", "parameters": {"unit": "days", "amount": 3}},
    {"type": "n8n-nodes-base.gmail", "parameters": {"subject": "Your product catalog + pricing", "message": "=Hi {{$json.contact_name}},\n\nAttached: full catalog + wholesale pricing by tier. MOQ is 24 units per SKU."}},
    {"type": "n8n-nodes-base.wait", "parameters": {"unit": "days", "amount": 4}},
    {"type": "n8n-nodes-base.gmail", "parameters": {"subject": "Checking in — any questions?", "message": "=Hi {{$json.contact_name}},\n\nJust checking in — anything I can help with as you explore the catalog?"}},
    {"type": "n8n-nodes-base.slack", "parameters": {"channel": "#wholesale-accounts", "text": "=New account onboarding complete: {{$json.company_name}} ({{$json.contact_name}})"}}
  ]
}
Enter fullscreen mode Exit fullscreen mode

3. Regulatory & Compliance Deadline Tracker

The problem: AAFCO labeling updates, EU Pet Food Regulation changes, state-level feed law deadlines. These land as fines.

The workflow:

  • Schedule: daily 7 AM
  • Google Sheets: read compliance deadlines sheet (regulation name, jurisdiction, due date, owner)
  • Code node: compute days remaining, assign tier: OVERDUE / CRITICAL (≤7d) / URGENT (≤14d) / WARNING (≤30d) / NOTICE (≤60d)
  • Switch: route by tier
  • Slack: OVERDUE/CRITICAL → #regulatory with @here
  • Gmail: email to owner and compliance lead
{
  "nodes": [
    {"type": "n8n-nodes-base.scheduleTrigger", "parameters": {"rule": {"interval": [{"field": "hours", "hoursInterval": 24}]}}},
    {"type": "n8n-nodes-base.googleSheets", "parameters": {"operation": "readRows", "sheetId": "YOUR_COMPLIANCE_SHEET"}},
    {"type": "n8n-nodes-base.code", "parameters": {"jsCode": "return items.map(i => {\n  const days = Math.floor((new Date(i.json.due_date) - new Date()) / 86400000);\n  const tier = days < 0 ? 'OVERDUE' : days <= 7 ? 'CRITICAL' : days <= 14 ? 'URGENT' : days <= 30 ? 'WARNING' : days <= 60 ? 'NOTICE' : null;\n  return tier ? {json: {...i.json, days_remaining: days, tier}} : null;\n}).filter(Boolean)"}},
    {"type": "n8n-nodes-base.switch", "parameters": {"dataPropertyName": "tier", "rules": [{"value": "OVERDUE"}, {"value": "CRITICAL"}, {"value": "URGENT"}, {"value": "WARNING"}, {"value": "NOTICE"}]}},
    {"type": "n8n-nodes-base.slack", "parameters": {"channel": "#regulatory", "text": "=<!here> {{$json.tier}}: {{$json.regulation}} ({{$json.jurisdiction}}) due in {{$json.days_remaining}} days — owner: {{$json.owner}}"}},
    {"type": "n8n-nodes-base.gmail", "parameters": {"subject": "={{$json.tier}}: {{$json.regulation}} due in {{$json.days_remaining}} days", "message": "={{$json.regulation}} in {{$json.jurisdiction}} is due {{$json.due_date}}. Please confirm status."}}
  ]
}
Enter fullscreen mode Exit fullscreen mode

4. AR Aging & Dunning Escalation

The problem: Wholesale invoices go unpaid for 60+ days. Your AR team manually emails each account every week.

The workflow:

  • Schedule: daily 9 AM weekdays
  • Google Sheets: read AR aging sheet (account, invoice number, amount, invoice date, days overdue)
  • Code node: bucket by 30/45/60/90+ days
  • Gmail: staged dunning emails — Day 30 gentle reminder, Day 45 firm, Day 60 escalation + late fee notice, Day 90 collections warning
  • Slack: flag 60d+ accounts to #accounts-receivable with account manager CC
{
  "nodes": [
    {"type": "n8n-nodes-base.scheduleTrigger", "parameters": {"rule": {"interval": [{"field": "cronExpression", "expression": "0 9 * * 1-5"}]}}},
    {"type": "n8n-nodes-base.googleSheets", "parameters": {"operation": "readRows", "sheetId": "YOUR_AR_SHEET"}},
    {"type": "n8n-nodes-base.code", "parameters": {"jsCode": "return items.filter(i => parseInt(i.json.days_overdue) >= 30).map(i => {\n  const d = parseInt(i.json.days_overdue);\n  const bucket = d >= 90 ? 90 : d >= 60 ? 60 : d >= 45 ? 45 : 30;\n  return {json: {...i.json, bucket}};\n})"}},
    {"type": "n8n-nodes-base.switch", "parameters": {"dataPropertyName": "bucket", "rules": [{"value": 30}, {"value": 45}, {"value": 60}, {"value": 90}]}},
    {"type": "n8n-nodes-base.gmail", "parameters": {"subject": "=Invoice #{{$json.invoice_number}} — payment reminder", "message": "=Hi {{$json.contact_name}},\n\nFriendly reminder: Invoice #{{$json.invoice_number}} for ${{$json.amount}} is now {{$json.days_overdue}} days past due. Please remit at your earliest convenience."}},
    {"type": "n8n-nodes-base.slack", "parameters": {"channel": "#accounts-receivable", "text": "=ESCALATION: {{$json.company_name}} — Invoice #{{$json.invoice_number}} ${{$json.amount}} is {{$json.days_overdue}} days overdue"}}
  ]
}
Enter fullscreen mode Exit fullscreen mode

5. Weekly Wholesale Performance Report

The problem: Your VP of Sales gets a sales report every Friday afternoon — built manually in Excel.

The workflow:

  • Schedule: Friday 4 PM
  • Google Sheets: read orders sheet for the week
  • Code node: aggregate — total revenue, order count, top 10 SKUs, new accounts, reactivated accounts, WoW% change
  • HTML email: styled table with KPIs to leadership + sales team
  • Slack: one-liner to #sales-ops
{
  "nodes": [
    {"type": "n8n-nodes-base.scheduleTrigger", "parameters": {"rule": {"interval": [{"field": "cronExpression", "expression": "0 16 * * 5"}]}}},
    {"type": "n8n-nodes-base.googleSheets", "parameters": {"operation": "readRows", "sheetId": "YOUR_ORDERS_SHEET"}},
    {"type": "n8n-nodes-base.code", "parameters": {"jsCode": "const orders = items.map(i => i.json);\nconst thisWeek = orders.filter(o => new Date(o.order_date) > new Date(Date.now() - 7*86400000));\nconst revenue = thisWeek.reduce((s, o) => s + parseFloat(o.amount || 0), 0);\nconst skuMap = {};\nthisWeek.forEach(o => { skuMap[o.sku] = (skuMap[o.sku] || 0) + parseFloat(o.amount || 0); });\nconst topSkus = Object.entries(skuMap).sort((a,b) => b[1]-a[1]).slice(0,10);\nreturn [{json: {revenue: revenue.toFixed(2), order_count: thisWeek.length, top_skus: topSkus.map(([s,r]) => s+': $'+r.toFixed(0)).join(', ')}}]"}},
    {"type": "n8n-nodes-base.gmail", "parameters": {"subject": "=Weekly Wholesale Report — week of {{$today.format('YYYY-MM-DD')}}", "message": "=<h2>Weekly Wholesale Report</h2><table><tr><th>Metric</th><th>Value</th></tr><tr><td>Revenue</td><td>${{$json.revenue}}</td></tr><tr><td>Orders</td><td>{{$json.order_count}}</td></tr><tr><td>Top SKUs</td><td>{{$json.top_skus}}</td></tr></table>"}}
  ]
}
Enter fullscreen mode Exit fullscreen mode

Why self-hosted n8n fits B2B pet industry

Pet B2B involves commercially sensitive data:

  • Retailer pricing contracts — different tiers for different accounts
  • Ingredient formulas — proprietary recipes, sourcing costs
  • AAFCO/EU compliance docs — regulatory filings, test results
  • EDI data — retailer inventory and POS data shared under agreements

Routing any of this through Zapier or Make.com means it lives on third-party infrastructure. Self-hosted n8n keeps it in your own network, fully auditable.

Comparison:

Feature n8n (self-hosted) Zapier Make.com
Data stays in your infra Yes No No
Custom business logic Full Limited Limited
Monthly cost at 10k tasks $0 $49+ $29+
AAFCO/compliance audit trail Git-versioned JSON No No
EDI/ERP integration HTTP Request node Limited Limited

Get the templates

If you want these workflows pre-built and ready to import, I've packaged them up in the FlowKit template store:

stripeai.gumroad.com — individual templates from $12, or the complete bundle for $97.

Drop a comment if you have questions about adapting any of these to your stack.

Top comments (0)