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"}}
]
}
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}})"}}
]
}
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."}}
]
}
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"}}
]
}
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>"}}
]
}
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)