This workflow corresponds to n8n.io template #12901 — 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 →
{
"id": "h2yMJwW58C1twKNv",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "Daily WooCommerce Sales Snapshot \u2192 Slack",
"tags": [],
"nodes": [
{
"id": "76bb2c69-3f36-4bb3-bea1-b259c6995488",
"name": "Daily Schedule",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
32,
352
],
"parameters": {
"rule": {
"interval": [
{
"triggerAtHour": 9
}
]
}
},
"typeVersion": 1.2
},
{
"id": "d97ab0ad-59bd-40c7-9c00-ad4cd7d90cab",
"name": "Fetch WooCommerce Orders",
"type": "n8n-nodes-base.wooCommerce",
"position": [
368,
224
],
"parameters": {
"options": {},
"resource": "order",
"operation": "getAll",
"returnAll": true
},
"credentials": {
"wooCommerceApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "6f674f94-af6f-44b5-88b1-cd7a86716cf0",
"name": "Filter Paid Orders",
"type": "n8n-nodes-base.filter",
"position": [
544,
224
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "or",
"conditions": [
{
"id": "87e8c91d-6544-4b2e-b9ea-3838805e5444",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.status }}",
"rightValue": "processing"
},
{
"id": "b3d4838c-b0da-4ce1-b75c-2855a0760268",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.status }}",
"rightValue": "completed"
}
]
}
},
"typeVersion": 2
},
{
"id": "3cdf966f-4f5e-42e9-a2b5-c57bbbcedb8c",
"name": "Last 24h Orders",
"type": "n8n-nodes-base.code",
"position": [
720,
224
],
"parameters": {
"jsCode": "// Filter orders from last 24 hours\nconst cutoff = new Date(Date.now() - 24 * 60 * 60 * 1000);\n\nreturn items.filter(i => new Date(i.json.date_created) >= cutoff);"
},
"typeVersion": 2
},
{
"id": "f4274439-a7f5-4301-b61f-cc46cbad7cfa",
"name": "Calculate Revenue + AOV",
"type": "n8n-nodes-base.code",
"position": [
1056,
368
],
"parameters": {
"jsCode": "let revenue = 0;\nlet count = items.length;\nlet currency = null;\n\nfor (const i of items) {\n revenue += parseFloat(i.json.total || 0);\n if (!currency) currency = i.json.currency;\n}\n\nconst aov = count > 0 ? revenue / count : 0;\n\nreturn [{ json: { totalRevenue: revenue.toFixed(2), orderCount: count, aov: aov.toFixed(2), currency } }];"
},
"typeVersion": 2
},
{
"id": "a7f0c8e1-380a-4bf2-9e02-a1e5d4ceec9e",
"name": "Calculate Top Products",
"type": "n8n-nodes-base.code",
"position": [
1056,
80
],
"parameters": {
"jsCode": "const productMap = {};\n\nfor (const item of items) {\n for (const line of item.json.line_items || []) {\n productMap[line.name] = (productMap[line.name] || 0) + line.quantity;\n }\n}\n\nconst topProducts = Object.entries(productMap)\n .sort((a,b) => b[1] - a[1])\n .slice(0,5);\n\nreturn [{ json: { topProducts } }];"
},
"typeVersion": 2
},
{
"id": "daf871ef-d441-4de3-971a-1a111c8092ca",
"name": "Merge Metrics",
"type": "n8n-nodes-base.merge",
"position": [
1264,
224
],
"parameters": {
"mode": "combine",
"options": {},
"combineBy": "combineByPosition",
"numberInputs": 3
},
"typeVersion": 3
},
{
"id": "36d98d38-5e6b-45eb-81cb-2821db5a950a",
"name": "Finalize Data",
"type": "n8n-nodes-base.code",
"position": [
1536,
240
],
"parameters": {
"jsCode": "let result = {};\n\nfor (const i of items) {\n result = { ...result, ...i.json };\n}\n\nreturn [{ json: result }];"
},
"typeVersion": 2
},
{
"id": "765c05d9-2998-4942-9e78-d9066129cee9",
"name": "Send Slack Summary",
"type": "n8n-nodes-base.slack",
"position": [
1776,
336
],
"parameters": {
"text": "=\ud83d\udcca *Daily Sales Snapshot*\n\n\ud83e\uddfe Orders: {{$json.orderCount}}\n\ud83d\udcb0 Revenue: {{$json.currency}} {{$json.totalRevenue}}\n\ud83d\udcc8 AOV: {{$json.currency}} {{$json.aov}}\n\n\ud83d\udd25 *Top Products*\n{{$json.topProducts.map(p => `\u2022 ${p[0]} (${p[1]})`).join('\\n')}}",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "list",
"value": "C0A3WQEKQ58",
"cachedResultName": "n8n-demo"
},
"otherOptions": {}
},
"credentials": {
"slackApi": {
"name": "<your credential>"
}
},
"typeVersion": 2
},
{
"id": "a7f2d14e-842b-45e5-8cda-dc539d260ecc",
"name": "Append or update row in sheet",
"type": "n8n-nodes-base.googleSheets",
"position": [
1760,
112
],
"parameters": {
"columns": {
"value": {
"aov": "={{ $json.aov }}",
"currency": "={{ $json.currency }}",
"timezone": "={{ $json.Timezone }}",
"timestamp": "={{ $json.timestamp }}",
"orderCount": "={{ $json.orderCount }}",
"topProducts": "={{ $json.topProducts }}",
"totalRevenue": "={{ $json.totalRevenue }}"
},
"schema": [
{
"id": "topProducts",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "topProducts",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "totalRevenue",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "totalRevenue",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "orderCount",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "orderCount",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "aov",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "aov",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "currency",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "currency",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "timestamp",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "timestamp",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "timezone",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "timezone",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"timestamp"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "appendOrUpdate",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "",
"cachedResultName": "Sheet1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1YNP9imIU1o1PkFFp0uXEmf4JdHsBd5X5gXW9_3FHSiQ",
"cachedResultUrl": "",
"cachedResultName": "Daily WooCommerce Sales Snapshot \u2192 Slack"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.7
},
{
"id": "55e17d5d-f6be-438c-954b-9da5be78f927",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-32,
48
],
"parameters": {
"color": 7,
"width": 304,
"height": 480,
"content": "## Daily Workflow Trigger\n\nStarts the workflow automatically each day using a Schedule Trigger.\nIt ensures daily sales data is collected, processed and reported\nconsistently without any manual intervention.\n"
},
"typeVersion": 1
},
{
"id": "eb621894-23ea-479a-b891-5bf0ea41c154",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
320,
48
],
"parameters": {
"color": 7,
"width": 544,
"height": 480,
"content": "## Fetch & Filter Orders\nThis section fetches orders from WooCommerce, keeps only paid orders and filters them to include orders from the last 24 hours. This helps ensure that only valid and recent sales data is used for revenue calculation."
},
"typeVersion": 1
},
{
"id": "a80064d1-b88c-44aa-92fd-653631eacda7",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
928,
-160
],
"parameters": {
"color": 7,
"width": 528,
"height": 720,
"content": "## Sales Metrics Calculation & Merge\n\nHere the workflow calculates key metrics using separate Code nodes:\n\u2022 Total Revenue\n\u2022 Order Count\n\u2022 Average Order Value (AOV)\n\u2022 Top Selling Products\n\nAll results are merged and normalized into a single object\nfor easy reuse in alerts, reports or future extensions."
},
"typeVersion": 1
},
{
"id": "d3f2b0de-7c53-45cd-917d-8ec9902a9ac9",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
1536,
-208
],
"parameters": {
"color": 7,
"width": 528,
"height": 768,
"content": "## Sales Summary & Logging\n\nThis section sends a clean, human-readable sales summary to Slack\nand records the same data in Google Sheets.\n\nIncludes:\n\u2022 Total revenue\n\u2022 Number of orders\n\u2022 Average order value (AOV)\n\u2022 Top selling products\n\nSlack provides instant visibility into daily performance,\nwhile Google Sheets maintains a historical log for tracking\ntrends and reporting\u2014without logging into dashboards.\n"
},
"typeVersion": 1
},
{
"id": "9f7a66c5-67a8-4823-a9f1-a1faebfb4b80",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
-688,
-288
],
"parameters": {
"width": 560,
"height": 1040,
"content": "## How This Workflow Works\n\n1. The workflow runs automatically once every day using a Schedule Trigger (Cron).\n\n2. It fetches recent orders from WooCommerce as the source sales data.\n\n3. Only paid orders (Completed / Processing) are considered to ensure accurate reporting.\n\n4. Orders created within the last 24 hours are filtered using a Code node.\n\n5. Separate Code nodes calculate key sales metrics such as:\n \u2022 Total Revenue\n \u2022 Order Count\n \u2022 Average Order Value (AOV)\n \u2022 Top Selling Products\n\n6. All calculated metrics are merged and formatted into a single consolidated object.\n\n7. A clean and readable daily sales summary is sent to a Slack channel,\n giving the team instant visibility into sales performance.\n\n8. The same sales data is also appended as a new row in Google Sheets,\n creating a daily log for tracking trends and historical analysis.\n\n---\n\n## How to Set Up This Workflow\n\nAdd a Schedule Trigger to run the workflow daily.\n\nAdd a WooCommerce node to fetch all orders.\n\nFilter orders by Completed / Processing status.\n\nUse a Code node to keep only orders from the last 24 hours.\n\nAdd separate Code nodes to calculate revenue, order count, AOV and top products.\n\nUse a Merge node to combine all calculated metrics.\n\nAdd a final Code node to normalize the merged data into one object.\n\nConnect a Slack node to send the daily sales summary.\n\nConnect a Google Sheets node to append the daily metrics as a new row.\n\nTest the workflow and activate it.\n"
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "738e9f95-ae4a-4453-9c92-1d95dfef1997",
"connections": {
"Finalize Data": {
"main": [
[
{
"node": "Append or update row in sheet",
"type": "main",
"index": 0
},
{
"node": "Send Slack Summary",
"type": "main",
"index": 0
}
]
]
},
"Merge Metrics": {
"main": [
[
{
"node": "Finalize Data",
"type": "main",
"index": 0
}
]
]
},
"Daily Schedule": {
"main": [
[
{
"node": "Fetch WooCommerce Orders",
"type": "main",
"index": 0
},
{
"node": "Merge Metrics",
"type": "main",
"index": 2
}
]
]
},
"Last 24h Orders": {
"main": [
[
{
"node": "Calculate Revenue + AOV",
"type": "main",
"index": 0
},
{
"node": "Calculate Top Products",
"type": "main",
"index": 0
}
]
]
},
"Filter Paid Orders": {
"main": [
[
{
"node": "Last 24h Orders",
"type": "main",
"index": 0
}
]
]
},
"Calculate Top Products": {
"main": [
[
{
"node": "Merge Metrics",
"type": "main",
"index": 0
}
]
]
},
"Calculate Revenue + AOV": {
"main": [
[
{
"node": "Merge Metrics",
"type": "main",
"index": 1
}
]
]
},
"Fetch WooCommerce Orders": {
"main": [
[
{
"node": "Filter Paid Orders",
"type": "main",
"index": 0
}
]
]
},
"Append or update row in sheet": {
"main": [
[]
]
}
}
}
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.
googleSheetsOAuth2ApislackApiwooCommerceApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow automatically collects WooCommerce sales data every day, calculates key sales metrics, sends a clean summary to Slack and logs the same data into Google Sheets for historical tracking. It helps teams stay informed about daily performance without manually checking…
Source: https://n8n.io/workflows/12901/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
This workflow automatically aggregates sales data, calculates performance trends (Revenue & Orders) against previous months and years, identifies the top-selling SKU and sends a strictly formatted, pr
This workflow continuously monitors the TikTok Ads Library for new creatives from specific advertisers or keyword searches, scrapes them via Apify, logs them into Google Sheets, and sends concise noti
This workflow contains community nodes that are only compatible with the self-hosted version of n8n.
Simplify financial oversight with this automated n8n workflow. Triggered daily, it fetches cash flow and expense data from a Google Sheet, analyzes inflows and outflows, validates records, and generat
This workflow is essential for e-commerce store owners, product strategists, and marketing teams who need real-time insight into what their competitors are selling.