{"workflow":{"id":13840,"name":"Analyze WooCommerce category sales over time with Airtable and Slack","views":110,"recentViews":1,"totalViews":110,"createdAt":"2026-03-03T12:57:57.096Z","description":"# WooCommerce Product Category Sales Performance Report\n\nThis workflow automatically analyzes sales data by product category, compares performance across time periods (daily, weekly or monthly), stores structured results in Airtable and sends a clear summary to Slack for quick decision-making.\n\nThis workflow pulls order data for two time periods (current and previous), groups sales by product category and calculates key metrics like revenue, units sold and share of total sales. Each category is then classified (Top Performer, Steady, Needs Attention, etc.) with a recommended action.\n\nThe results are saved to Airtable for tracking & history and a short, easy-to-read summary is sent to Slack so stakeholders can understand performance at a glance.\n\nYou get:\n\n*   **Automated sales comparison (daily / weekly / monthly)**\n*   **Category-wise performance classification**\n*   **Historical tracking in Airtable**\n*   **One clean Slack summary — no dashboards required**\n    \nIdeal for product, sales and operations teams who want fast, consistent insights without manual reporting.\n\n### Quick Start – Implementation Steps\n\n1.  Configure the **date granularity** (daily, weekly or monthly).\n2.  Connect your **Orders data source** (API, DB or platform node).\n3.  Connect and configure your **Airtable** base & table.\n4.  Connect your **Slack** workspace and choose a channel.\n5.  Activate the workflow — reports start running automatically.\n\n    \n## What It Does\n\nThis workflow automates category-level sales analysis:\n\n1.  Builds current and previous date ranges dynamically.\n2.  Fetches orders for both time periods.\n3.  Normalizes and aggregates orders by product category.\n4.  Calculates key metrics:\n    *   Current revenue\n    *   Previous revenue\n    *   Units sold\n    *   Share of total sales\n5.  Classifies each category (Top Performer, Steady, At Risk, etc.).\n6.  Adds a recommended business action for each category.\n7.  Saves the final results to Airtable.\n8.  Generates a short summary message.\n9.  Sends a single Slack report to stakeholders.\n    \nThis ensures consistent, repeatable insights with no manual effort.\n\n## Who’s It For\n\nThis workflow is ideal for:\n\n*   Sales & revenue teams\n*   Product managers\n*   E-commerce operations teams\n*   Business analysts\n*   Startup founders & leadership\n*   Anyone needing automated sales performance insights\n    \n\n## Requirements to Use This Workflow\n\nTo run this workflow, you need:\n\n*   **n8n instance** (cloud or self-hosted)\n*   Access to **orders data** (API, database or platform integration)\n*   **Airtable base** + Personal Access Token\n*   **Slack workspace** with API permissions\n*   Basic understanding of sales metrics (revenue, units, categories)\n    \n\n## How It Works\n\n1.  **Scheduler Trigger** – Workflow runs on a defined schedule.\n2.  **Build Date Ranges** – Calculates current and previous periods.\n3.  **Fetch Orders (Current)** – Pulls orders for the active period.\n4.  **Fetch Orders (Previous)** – Pulls orders for comparison.\n5.  **Aggregate by Category** – Groups sales and calculates metrics.\n6.  **Classify Performance** – Assigns tags and actions.\n7.  **Save to Airtable** – Stores structured results.\n8.  **Build Slack Summary** – Creates a readable summary message.\n9.  **Send to Slack** – Delivers insights to the team.\n    \n\n## Setup Steps\n\n1.  Import the provided n8n workflow JSON.\n2.  Configure the **Scheduler** timing.\n3.  Set your preferred **granularity** (daily / weekly / monthly).\n4.  Connect and map your **Orders data source**.\n5.  Connect **Airtable** and map fields:\n    *   Category ID / Name\n    *   Current Revenue\n    *   Previous Revenue\n    *   Units\n    *   Share\n    *   Tag\n    *   Recommended Action\n6.  Connect **Slack API** credentials and select a channel.\n7.  Activate the workflow — done!\n    \n\n## How To Customize Nodes\n\n### Change Time Period\n\n*   Switch between daily, weekly or monthly comparisons.\n*   Adjust rolling windows for testing or analysis.\n\n### Adjust Performance Thresholds\n\n*   Modify revenue or share thresholds.\n*   Change category labels or actions.\n\n### Customize Airtable Storage\n\nAdd optional fields such as:\n\n*   Report date\n*   Growth percentage\n*   Notes or owner\n*   Review status    \n\n### Customize Slack Summary\n\nYou may add:\n\n*   Emojis or highlights\n*   Mentions (@channel, @team)\n*   Links to Airtable records\n*   Separate sections for risks or wins\n    \n\n## Add-Ons (Optional Enhancements)\n\nYou can extend this workflow to:\n\n*   Add Teams or Email notifications\n*   Track trends over multiple periods\n*   Generate charts or dashboards\n*   Add alerts for sudden drops or spikes\n*   Include AI-based insights or explanations\n*   Export reports to Google Sheets or CSV\n    \n\n## Use Case Examples\n\n### 1\\. Weekly Sales Review\n\nAutomatically send category performance every week.\n\n### 2\\. Product Decision Support\n\nIdentify which categories to promote or discontinue.\n\n### 3\\. Leadership Updates\n\nShare clear performance summaries with management.\n\n### 4\\. E-commerce Optimization\n\nSpot declining categories before revenue drops.\n\n### 5\\. Historical Analysis\n\nTrack performance trends over time in Airtable.\n\n\n## Troubleshooting Guide\n\n| Issue                 | Possible Cause            | Solution                                |\n|-----------------------|--------------------------|------------------------------------------|\n| No Slack message      | Slack node not connected | Verify Slack credentials                 |\n| No Airtable data      | Field mapping mismatch   | Match Airtable column names              |\n| Missing current orders| Date range incorrect     | Check UTC date logic                     |\n| Empty summary         | No category data         | Verify aggregation step                  |\n| Workflow not running  | Trigger disabled         | Enable Scheduler node                    |\n\n\n## Need Help?\n\nIf you need help extending or customizing this workflow with adding alerts, dashboards, AI insights or scaling it for production then our [n8n workflow developers](https://www.weblineindia.com/hire-n8n-developers/) at **WeblineIndia** can assist with advanced automation and reporting solutions.","workflow":{"id":"r1UbQa3bXqbHTzdi","meta":{"instanceId":"14e4c77104722ab186539dfea5182e419aecc83d85963fe13f6de862c875ebfa","templateCredsSetupCompleted":true},"name":"Automated Category Sales Performance Report","tags":[],"nodes":[{"id":"f938bd6b-2b48-4b3c-9aeb-bda8b928fe0c","name":"Category Map","type":"n8n-nodes-base.code","position":[-32,176],"parameters":{"jsCode":"const map = {};\n\nfor (const item of items) {\n  const p = item.json;\n\n  if (!p.id || !p.categories?.length) continue;\n\n  map[p.id] = {\n    category_id: p.categories[0].id,\n    category_name: p.categories[0].name\n  };\n}\n\n// Fees bucket\nmap[\"fee\"] = {\n  category_id: 99,\n  category_name: \"Fees\"\n};\n\nreturn [{ json: map }];\n"},"typeVersion":2},{"id":"885fb92a-a373-4630-a9be-6f4087f743bb","name":"Run On Schedule","type":"n8n-nodes-base.scheduleTrigger","position":[-1024,-16],"parameters":{"rule":{"interval":[{}]}},"typeVersion":1.2},{"id":"5a8176d7-9d22-4a76-8c93-b34f249c78f2","name":"Report Configuration","type":"n8n-nodes-base.set","position":[-768,-16],"parameters":{"options":{},"assignments":{"assignments":[{"id":"e83b0e89-3aa5-4e07-82e1-414e4d548dad","name":"granularity","type":"string","value":"days"},{"id":"084d2db4-d7f9-469b-8142-10747817b1f0","name":"top_categories_limit","type":"number","value":8},{"id":"4b5de47e-36bb-496b-a821-5fe6abb9dd00","name":"top_performer_pct","type":"number","value":10},{"id":"f61c5995-3ea2-419b-8db6-d28e3f33a8d3","name":"momentum_pct","type":"number","value":30},{"id":"6bc07124-26c7-4b2a-a05b-728fdd139f2c","name":"steady_band","type":"number","value":10},{"id":"81b2486b-abcf-41d8-881d-767d93602bba","name":"at_risk_growth_pct","type":"number","value":-15},{"id":"77ce5d9a-823b-4afa-b5d9-2a86d05d4ed6","name":"discontinue_growth_pct","type":"number","value":-25}]}},"typeVersion":3.4},{"id":"f9885621-1e1c-45ed-8ac2-be22dc333199","name":"Calculate Reporting Periods","type":"n8n-nodes-base.code","position":[-592,-16],"parameters":{"jsCode":"// Read inputs\nconst granularity = ($json.granularity || 'days').toLowerCase();\nconst now = new Date();\n\nlet period_start, period_end;\nlet prev_period_start, prev_period_end;\n\n// Helper: start of today (UTC – morning)\nconst startOfTodayUTC = new Date(Date.UTC(\n  now.getUTCFullYear(),\n  now.getUTCMonth(),\n  now.getUTCDate(),\n  0, 0, 0\n));\n\n// DAILY – TEST MODE (UPDATED)\n// DAILY – SAFE TEST MODE (Woo-friendly)\nif (granularity === 'days') {\n\n  // Current Period = Yesterday 00:00 UTC → now\n  period_end = now;\n\n  period_start = new Date(Date.UTC(\n    now.getUTCFullYear(),\n    now.getUTCMonth(),\n    now.getUTCDate() - 1, //  buffer\n    0, 0, 0\n  ));\n\n  // Previous Period = 6 days before current start\n  prev_period_end = new Date(period_start);\n  prev_period_start = new Date(prev_period_end);\n  prev_period_start.setUTCDate(prev_period_start.getUTCDate() - 6);\n}\n\n\n// WEEKLY – calendar weeks\nelse if (granularity === 'weekly') {\n  const day = now.getUTCDay(); // 0 = Sunday\n  const diffToMonday = (day + 6) % 7;\n\n  period_end = new Date(Date.UTC(\n    now.getUTCFullYear(),\n    now.getUTCMonth(),\n    now.getUTCDate() - diffToMonday,\n    0, 0, 0\n  ));\n\n  period_start = new Date(period_end);\n  period_start.setUTCDate(period_start.getUTCDate() - 7);\n\n  prev_period_end = new Date(period_start);\n  prev_period_start = new Date(prev_period_end);\n  prev_period_start.setUTCDate(prev_period_start.getUTCDate() - 7);\n}\n\n//  MONTHLY – calendar months\nelse if (granularity === 'monthly') {\n  period_end = new Date(Date.UTC(\n    now.getUTCFullYear(),\n    now.getUTCMonth(),\n    1,\n    0, 0, 0\n  ));\n\n  period_start = new Date(period_end);\n  period_start.setUTCMonth(period_start.getUTCMonth() - 1);\n\n  prev_period_end = new Date(period_start);\n  prev_period_start = new Date(prev_period_end);\n  prev_period_start.setUTCMonth(prev_period_start.getUTCMonth() - 1);\n}\n\n// Safety\nelse {\n  throw new Error(`Unsupported granularity: ${granularity}`);\n}\n\n//  Output\nreturn [\n  {\n    json: {\n      granularity,\n      period_start: period_start.toISOString(),\n      period_end: period_end.toISOString(),\n      prev_period_start: prev_period_start.toISOString(),\n      prev_period_end: prev_period_end.toISOString(),\n      top_categories_limit: $json.top_categories_limit || 8\n    }\n  }\n];\n"},"typeVersion":2},{"id":"af7baea5-1e10-4396-8a29-97d6bc70086b","name":"Fetch Orders — Current Period","type":"n8n-nodes-base.wooCommerce","position":[-256,-208],"parameters":{"options":{"after":"={{ $json.period_start }}","status":"completed"},"resource":"order","operation":"getAll","returnAll":true},"credentials":{"wooCommerceApi":{"id":"Q5GWQzcdNturKgSg","name":"WooCommerce account 2"}},"typeVersion":1},{"id":"a854efec-4411-4216-b153-68b02026a2fc","name":"Fetch Orders — Previous Period","type":"n8n-nodes-base.wooCommerce","position":[-256,-16],"parameters":{"options":{"after":"={{ $json.prev_period_start }}","before":"={{ $json.prev_period_end }}","status":"completed"},"resource":"order","operation":"getAll"},"credentials":{"wooCommerceApi":{"id":"Q5GWQzcdNturKgSg","name":"WooCommerce account 2"}},"typeVersion":1,"alwaysOutputData":true},{"id":"5cc43700-36c5-4ffd-8ae5-52f74d797c91","name":"Fetch Products","type":"n8n-nodes-base.wooCommerce","position":[-256,176],"parameters":{"options":{},"operation":"getAll","returnAll":true},"credentials":{"wooCommerceApi":{"id":"Q5GWQzcdNturKgSg","name":"WooCommerce account 2"}},"typeVersion":1},{"id":"de3b6e71-edd1-437d-8fca-99541c2988f9","name":"Normalize Order Items — Current","type":"n8n-nodes-base.code","position":[-32,-208],"parameters":{"jsCode":"// Initialize output array\nconst newItems = [];\n\n// Loop through all items from previous node\nfor (const item of items) {\n    const order = item.json; // actual order object\n\n    const orderInfo = {\n        order_id: order.id,\n        order_number: order.number,\n        order_total: parseFloat(order.total),\n        order_date: order.date_created,\n        currency: order.currency,\n        customer_id: order.customer_id,\n        billing_name: `${order.billing.first_name} ${order.billing.last_name}`,\n        shipping_name: `${order.shipping.first_name} ${order.shipping.last_name}`,\n    };\n\n    // Use line_items if present, else fee_lines\n    const itemsList = (order.line_items && order.line_items.length > 0)\n        ? order.line_items\n        : (order.fee_lines && order.fee_lines.length > 0 ? order.fee_lines : []);\n\n    if (itemsList.length === 0) continue; // skip empty orders\n\n    for (const itemLine of itemsList) {\n        newItems.push({\n            json: {\n                ...orderInfo,\n                item_id: itemLine.id,\n                item_name: itemLine.name,\n                item_qty: itemLine.quantity || 1,\n                item_total: parseFloat(itemLine.total || itemLine.amount || 0),\n                item_price: parseFloat(itemLine.price || itemLine.amount || 0),\n                item_type: (order.line_items && order.line_items.length > 0) ? 'product' : 'fee'\n            }\n        });\n    }\n}\n\nreturn newItems;\n"},"typeVersion":2},{"id":"865c0cc0-43a8-46bc-b729-bc17c8eeb05f","name":"Normalize Order Items — Previous","type":"n8n-nodes-base.code","position":[-32,-16],"parameters":{"jsCode":"// Initialize output array\nconst newItems = [];\n\n// Loop through all items from previous node\nfor (const item of items) {\n    const order = item.json; // actual order object\n\n    const orderInfo = {\n        order_id: order.id,\n        order_number: order.number,\n        order_total: parseFloat(order.total),\n        order_date: order.date_created,\n        currency: order.currency,\n        customer_id: order.customer_id,\n        billing_name: `${order.billing.first_name} ${order.billing.last_name}`,\n        shipping_name: `${order.shipping.first_name} ${order.shipping.last_name}`,\n    };\n\n    // Use line_items if present, else fee_lines\n    const itemsList = (order.line_items && order.line_items.length > 0)\n        ? order.line_items\n        : (order.fee_lines && order.fee_lines.length > 0 ? order.fee_lines : []);\n\n    if (itemsList.length === 0) continue; // skip empty orders\n\n    for (const itemLine of itemsList) {\n        newItems.push({\n            json: {\n                ...orderInfo,\n                item_id: itemLine.id,\n                item_name: itemLine.name,\n                item_qty: itemLine.quantity || 1,\n                item_total: parseFloat(itemLine.total || itemLine.amount || 0),\n                item_price: parseFloat(itemLine.price || itemLine.amount || 0),\n                item_type: (order.line_items && order.line_items.length > 0) ? 'product' : 'fee'\n            }\n        });\n    }\n}\n\nreturn newItems;\n"},"typeVersion":2},{"id":"b79ad266-8618-40a7-b70f-ca86d27f04fd","name":"Combine Orders & Products","type":"n8n-nodes-base.merge","position":[288,-32],"parameters":{"numberInputs":3},"typeVersion":3.2},{"id":"23d57db4-1d00-4cf8-bd67-c732d55f7458","name":"Aggregate Sales by Category","type":"n8n-nodes-base.code","position":[544,-16],"parameters":{"jsCode":"/* ======================================\n   INPUTS\n   ====================================== */\n\n// Get current and previous normalized rows\nconst currentRows = $items(\"Normalize Order Items — Current\").map(i => i.json);\nconst previousRows = $items(\"Normalize Order Items — Previous\").map(i => i.json);\n\n// Get Product → Category map if exists (optional)\nconst productCategoryMapInput = $items(\"Category Map\")?.[0]?.json || {};\n\n/* ======================================\n   BUILD DYNAMIC PRODUCT → CATEGORY MAP\n   ====================================== */\n\nconst productCategoryMap = { ...productCategoryMapInput };\n\n// Scan current and previous rows for products and add unmapped ones dynamically\nfor (const row of [...currentRows, ...previousRows]) {\n  if (row.item_type === \"product\" && !productCategoryMap[row.item_id]) {\n    // Dynamically create category for unmapped product\n    // Replace this with actual logic to fetch from WooCommerce if needed\n    // For now, we use \"Unmapped\" for any missing product\n    productCategoryMap[row.item_id] = {\n      category_id: row.item_id, // temporary: use product_id as category_id\n      category_name: row.item_name // temporary: use product_name as category_name\n    };\n  }\n}\n\n// Always include fees bucket\nproductCategoryMap[\"fee\"] = { category_id: 99, category_name: \"Fees\" };\n\n/* ======================================\n   HELPER: AGGREGATE ROWS BY CATEGORY\n   ====================================== */\nfunction aggregate(rows) {\n  const agg = {};\n\n  for (const r of rows) {\n    const key = r.item_type === \"fee\" ? \"fee\" : r.item_id;\n    const cat = productCategoryMap[key] || { category_id: \"unmapped\", category_name: \"Unmapped\" };\n    const cid = String(cat.category_id);\n\n    if (!agg[cid]) {\n      agg[cid] = {\n        category_id: cid,\n        category_name: cat.category_name,\n        revenue: 0,\n        units_sold: 0,\n        orders: new Set()\n      };\n    }\n\n    agg[cid].revenue += Number(r.item_total || 0);\n    agg[cid].units_sold += Number(r.item_qty || 0);\n    agg[cid].orders.add(r.order_id);\n  }\n\n  // Convert orders Set → number\n  for (const c of Object.values(agg)) {\n    c.orders = c.orders.size;\n  }\n\n  return agg;\n}\n\n/* ======================================\n   AGGREGATE CURRENT & PREVIOUS\n   ====================================== */\nconst curAgg = aggregate(currentRows);\nconst prevAgg = aggregate(previousRows);\n\n// Combine all category IDs\nconst allCategoryIds = new Set([...Object.keys(curAgg), ...Object.keys(prevAgg)]);\n\n// Total current revenue for share_of_total\nconst totalCurrentRevenue = Object.values(curAgg).reduce((s, c) => s + c.revenue, 0);\n\n/* ======================================\n   BUILD FINAL OUTPUT\n   ====================================== */\nconst result = [];\n\nfor (const cid of allCategoryIds) {\n  const cur = curAgg[cid] || { revenue: 0, units_sold: 0, orders: 0, category_name: prevAgg[cid]?.category_name || \"Unmapped\" };\n  const prev = prevAgg[cid] || { revenue: 0, units_sold: 0, orders: 0, category_name: cur.category_name };\n\n  const abs_change = cur.revenue - prev.revenue;\n  const pct_change = prev.revenue === 0 ? \"n/a\" : ((abs_change / prev.revenue) * 100).toFixed(2);\n  const share_of_total = totalCurrentRevenue === 0 ? \"0.00\" : ((cur.revenue / totalCurrentRevenue) * 100).toFixed(2);\n\n  result.push({\n    category_id: cid,\n    category_name: cur.category_name,\n    revenue_current: cur.revenue,\n    revenue_prev: prev.revenue,\n    abs_change,\n    pct_change,\n    units_sold: cur.units_sold,\n    orders_current: cur.orders,\n    share_of_total\n  });\n}\n\n/* ======================================\n   RETURN ITEMS FOR N8N\n   ====================================== */\nreturn result.map(r => ({ json: r }));\n"},"typeVersion":2},{"id":"8aedb373-070a-4188-886c-bf85e6071168","name":"Classify Category Performance","type":"n8n-nodes-base.code","position":[736,-16],"parameters":{"jsCode":"const categories = $items(\"Aggregate Sales by Category\").map(i => i.json);\n\n// Sort categories by revenue_current descending\ncategories.sort((a, b) => b.revenue_current - a.revenue_current);\n\n// Only categories with positive current revenue\nconst positiveRevenueCategories = categories.filter(c => c.revenue_current > 0);\nconst totalPositive = positiveRevenueCategories.length;\n\n// Generate rank map\nconst rankMap = {};\npositiveRevenueCategories.forEach((c, idx) => {\n    rankMap[c.category_id] = idx;\n});\n\n// Dynamic thresholds\nconst thresholds = {\n    top: 0.2,      // top 20%\n    momentum: 0.5, // top 50%\n    steady: 0.8    // top 80%\n};\n\ncategories.forEach(cat => {\n    let tag = \"\";\n    let recommended_action = \"\";\n\n    if (cat.revenue_current === 0 && cat.revenue_prev > 0) {\n        // Category had revenue before but 0 now\n        tag = \"Consider Discontinue\";\n        recommended_action = \"Investigate returns or delisting\";\n    } else if (cat.revenue_current === 0 && cat.revenue_prev === 0) {\n        // Category never sold\n        tag = \"At Risk\";\n        recommended_action = \"Promotions or marketing\";\n    } else {\n        // Category has revenue now (revenue_current > 0)\n        const rank = rankMap[cat.category_id];\n        const rankPercent = totalPositive > 1 ? (rank + 1) / totalPositive : 0;\n\n        if (rankPercent <= thresholds.top) {\n            tag = \"Top Performer\";\n            recommended_action = \"Feature on homepage\";\n        } else if (rankPercent <= thresholds.momentum) {\n            tag = \"Momentum\";\n            recommended_action = \"Investigate increasing stock\";\n        } else if (rankPercent <= thresholds.steady) {\n            tag = \"Steady\";\n            recommended_action = \"Maintain current strategy\";\n        } else {\n            tag = \"At Risk\";\n            recommended_action = \"Promotions or marketing\";\n        }\n    }\n\n    cat.tag = tag;\n    cat.recommended_action = recommended_action;\n});\n\nreturn categories.map(c => ({ json: c }));\n"},"typeVersion":2},{"id":"fc6b5a47-97f3-4b45-a867-d2ba473833ca","name":"Prepare Fields for Reporting","type":"n8n-nodes-base.set","position":[944,-16],"parameters":{"options":{},"assignments":{"assignments":[{"id":"72e7696b-0045-4f17-90c3-e41b4e3dd8a2","name":"category_id","type":"string","value":"={{ $json.category_id }}"},{"id":"83ef1840-c74c-4dd8-9d1f-843696194a1d","name":"revenue_current","type":"number","value":"={{ $json.revenue_current }}"},{"id":"cdd10e1b-7030-4053-9824-7d9ae1c0d792","name":"revenue_prev","type":"number","value":"={{ $json.revenue_prev }}"},{"id":"6b10bdd7-7a77-4d6a-8d1e-e098018402b3","name":"units_sold","type":"number","value":"={{ $json.units_sold }}"},{"id":"f0208637-1721-4008-803d-fe7ff7a9a4e9","name":"share_of_total","type":"string","value":"={{ $json.share_of_total }}"},{"id":"9e65e3dc-0b3e-4243-8382-babc08dbc799","name":"tag","type":"string","value":"={{ $json.tag }}"},{"id":"75acd458-0373-40dc-b99a-7c5761c54901","name":"recommended_action","type":"string","value":"={{ $json.recommended_action }}"}]}},"typeVersion":3.4},{"id":"5151087f-6f04-4d13-955e-4f8fe67d8b8f","name":"Save Results to Airtable","type":"n8n-nodes-base.airtable","position":[1184,-16],"parameters":{"base":{"__rl":true,"mode":"list","value":"appF2iYPgVqqyXDC1","cachedResultUrl":"https://airtable.com/appF2iYPgVqqyXDC1","cachedResultName":"n8n Demo"},"table":{"__rl":true,"mode":"list","value":"tbloZJJZU0wCvi2qd","cachedResultUrl":"https://airtable.com/appF2iYPgVqqyXDC1/tbloZJJZU0wCvi2qd","cachedResultName":"Category Performance"},"columns":{"value":{"Tag":"={{ $json.tag }}","Share":"={{ $json.share_of_total }}","Units":"={{ $json.units_sold }}","Action ":"={{ $json.recommended_action }}","Category Id":"={{ $json.category_id }}","Current Revenue":"={{ $json.revenue_current }}","Previous Revenue":"={{ $json.revenue_prev }}"},"schema":[{"id":"Category Id","type":"number","display":true,"removed":false,"readOnly":false,"required":false,"displayName":"Category Id","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Current Revenue","type":"number","display":true,"removed":false,"readOnly":false,"required":false,"displayName":"Current Revenue","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Previous Revenue","type":"number","display":true,"removed":false,"readOnly":false,"required":false,"displayName":"Previous Revenue","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Units","type":"number","display":true,"removed":false,"readOnly":false,"required":false,"displayName":"Units","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Share","type":"number","display":true,"removed":false,"readOnly":false,"required":false,"displayName":"Share","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Tag","type":"string","display":true,"removed":false,"readOnly":false,"required":false,"displayName":"Tag","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Action ","type":"string","display":true,"removed":false,"readOnly":false,"required":false,"displayName":"Action ","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":[],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{},"operation":"create"},"credentials":{"airtableTokenApi":{"id":"yAKqmhLRuSdbo2T8","name":"Airtable Personal Access Token account 10"}},"typeVersion":2.1},{"id":"7735c6ef-f872-487b-8f38-f377452dd0ac","name":"Build Slack Summary","type":"n8n-nodes-base.code","position":[1424,-16],"parameters":{"jsCode":"// Airtable rows come as: item.fields\nconst rows = items.map(i => i.json.fields);\n\n// Helpers\nconst formatMoney = (v) =>\n  typeof v === \"number\" ? `₹${v.toLocaleString(\"en-IN\")}` : \"₹0\";\n\n// Split categories\nconst top = rows\n  .filter(r => r[\"Current Revenue\"] > 0)\n  .sort((a, b) => b[\"Current Revenue\"] - a[\"Current Revenue\"])\n  .slice(0, 5);\n\nconst risk = rows.filter(r =>\n  [\"At Risk\", \"Consider Discontinue\"].includes(r[\"Tag\"])\n);\n\n// Build text\nlet text = `*Category Performance Summary*\\n\\n`;\n\ntext += `*Top Categories*\\n`;\nif (top.length === 0) {\n  text += `• No sales in current period\\n`;\n} else {\n  for (const r of top) {\n    const prev = r[\"Previous Revenue\"];\n    const curr = r[\"Current Revenue\"];\n\n    const pct =\n      prev > 0\n        ? `${(((curr - prev) / prev) * 100).toFixed(1)}%`\n        : \"n/a\";\n\n    text += `• *Category ${r[\"Category Id\"]}* — ${formatMoney(curr)} (${pct}) | ${r[\"Tag\"]}\\n`;\n  }\n}\n\nif (risk.length) {\n  text += `\\n *Needs Attention*\\n`;\n  for (const r of risk) {\n    text += `• *Category ${r[\"Category Id\"]}* — ${formatMoney(\n      r[\"Current Revenue\"]\n    )} | ${r[\"Action \"]}\\n`;\n  }\n}\n\ntext += `\\n Full report available in Airtable.`;\n\nreturn [{ json: { text } }];\n"},"typeVersion":2},{"id":"2173ef7a-fbf2-4d79-afa2-c9b6ff4d975c","name":"Send Report to Slack","type":"n8n-nodes-base.slack","position":[1664,-16],"webhookId":"dc0cb4e6-72e1-4b0e-9372-adb06a10f893","parameters":{"text":"={{ $json.text }}","select":"channel","channelId":{"__rl":true,"mode":"list","value":"C09S57E2JQ2","cachedResultName":"n8n"},"otherOptions":{"includeLinkToWorkflow":false}},"credentials":{"slackApi":{"id":"NwllndcJLwnQYcFB","name":"Slack account 15"}},"typeVersion":2.3},{"id":"3ccb02a4-6ad4-4765-94c9-bda0ba405603","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-1088,-112],"parameters":{"color":7,"height":240,"content":"Starts the workflow automatically on a fixed schedule (daily / weekly)."},"typeVersion":1},{"id":"e7ef5742-3f3d-4a04-9529-e57addc8ed2b","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-816,-128],"parameters":{"color":7,"width":368,"height":272,"content":"Sets the report rules and automatically calculates current and previous date ranges for sales comparison."},"typeVersion":1},{"id":"01bd5059-3216-40d5-8edb-41dc1ac5dd90","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[-416,-432],"parameters":{"color":7,"width":848,"height":784,"content":"## Fetch & Normalize \n\n**Fetch Orders — Current Period:** Fetches completed WooCommerce orders from the current time period.\n**Fetch Orders — Previous Period:** Fetches completed WooCommerce orders from the previous comparison period.\n**Fetch Products:** Loads product and category details from WooCommerce.\n**Normalize Order Items — Current:** Breaks current orders into individual product-level sales rows.\n**Normalize Order Items — Previous:** Breaks previous orders into individual product-level sales rows. \n**Category Map:** Maps each product to its category for accurate category reporting.\n**Combine Orders & Products:** Combines current and previous sales data into a single stream."},"typeVersion":1},{"id":"22726a24-2718-4616-8324-382065a42298","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[480,-288],"parameters":{"color":7,"width":1376,"height":496,"content":"## Category Performance Analysis & Reporting \n\n**Aggregate Sales by Category:** Calculates total revenue, units sold and orders per category.\n**Classify Category Performance:** Labels categories as Top Performer, Momentum, Steady or At Risk.\n**Prepare Fields for Reporting:** Formats and selects final fields needed for reports and storage.\n**Save Results to Airtable:** Saves category performance results to Airtable for tracking and history.\n**Build Slack Summary:** Creates a short, readable summary of category performance.\n**Send Report to Slack:** Sends the final performance summary to the Slack channel."},"typeVersion":1},{"id":"63bd8b58-2c0a-48f9-9b8a-e53837882118","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[-1776,-864],"parameters":{"width":576,"height":864,"content":"# How it Works\n\n### This workflow automatically analyzes sales data by product category and compares current performance with the previous period (weekly or monthly).\n### It pulls orders for two time periods (current and previous), groups sales by category and calculates key metrics such as revenue, units sold and share of total sales.\n### Based on these results, each category is classified (for example: Top Performer, Steady or Needs Attention) along with a recommended action.\n ### The final results are saved to Airtable for tracking, reporting and historical comparison.\n### A short, easy-to-read summary is generated and sent to Slack, allowing stakeholders to quickly see what’s performing well and what needs attention—without opening dashboards or detailed reports.\n### This workflow runs automatically and ensures everyone receives consistent, up-to-date performance insights.\n\n\n# Setup steps\n\n**1.** Configure the date range (current period and previous days) in the date range node.\n\n**2.** Connect your order source (e.g., WooCommerce or API) for both current and previous periods.\n\n**3.** Make sure categories and revenue fields match your order data structure.\n\n**4.** Connect Airtable and map fields for category metrics and actions.\n\n**5.** Connect Slack and select the channel where summaries should be posted.\n\n**6.** Test once with recent data, then activate the workflow."},"typeVersion":1}],"active":false,"pinData":{},"settings":{"executionOrder":"v1"},"versionId":"40a78233-f5fa-4cdc-8093-6d4276c84deb","connections":{"Category Map":{"main":[[{"node":"Combine Orders & Products","type":"main","index":2}]]},"Fetch Products":{"main":[[{"node":"Category Map","type":"main","index":0}]]},"Run On Schedule":{"main":[[{"node":"Report Configuration","type":"main","index":0}]]},"Build Slack Summary":{"main":[[{"node":"Send Report to Slack","type":"main","index":0}]]},"Report Configuration":{"main":[[{"node":"Calculate Reporting Periods","type":"main","index":0}]]},"Save Results to Airtable":{"main":[[{"node":"Build Slack Summary","type":"main","index":0}]]},"Combine Orders & Products":{"main":[[{"node":"Aggregate Sales by Category","type":"main","index":0}]]},"Aggregate Sales by Category":{"main":[[{"node":"Classify Category Performance","type":"main","index":0}]]},"Calculate Reporting Periods":{"main":[[{"node":"Fetch Orders — Previous Period","type":"main","index":0},{"node":"Fetch Orders — Current Period","type":"main","index":0},{"node":"Fetch Products","type":"main","index":0}]]},"Prepare Fields for Reporting":{"main":[[{"node":"Save Results to Airtable","type":"main","index":0}]]},"Classify Category Performance":{"main":[[{"node":"Prepare Fields for Reporting","type":"main","index":0}]]},"Fetch Orders — Current Period":{"main":[[{"node":"Normalize Order Items — Current","type":"main","index":0}]]},"Fetch Orders — Previous Period":{"main":[[{"node":"Normalize Order Items — Previous","type":"main","index":0}]]},"Normalize Order Items — Current":{"main":[[{"node":"Combine Orders & Products","type":"main","index":0}]]},"Normalize Order Items — Previous":{"main":[[{"node":"Combine Orders & Products","type":"main","index":1}]]}}},"lastUpdatedBy":1,"workflowInfo":{"nodeCount":21,"nodeTypes":{"n8n-nodes-base.set":{"count":2},"n8n-nodes-base.code":{"count":7},"n8n-nodes-base.merge":{"count":1},"n8n-nodes-base.slack":{"count":1},"n8n-nodes-base.airtable":{"count":1},"n8n-nodes-base.stickyNote":{"count":5},"n8n-nodes-base.wooCommerce":{"count":3},"n8n-nodes-base.scheduleTrigger":{"count":1}}},"status":"published","readyToDemo":null,"user":{"name":"WeblineIndia","username":"weblineindia","bio":"A Leading Software Engineering, Consulting & Outsourcing Services Company in USA & India serving Clients Globally since 1999.","verified":true,"links":["https://www.weblineindia.com/hire-n8n-developers/"],"avatar":"https://gravatar.com/avatar/a229d43aefca4588581583c58bb37b4773aebbdf4c1fef86a08bb1d38eae91fa?r=pg&d=retro&size=200"},"nodes":[{"id":2,"icon":"file:airtable.svg","name":"n8n-nodes-base.airtable","codex":{"data":{"resources":{"generic":[{"url":"https://n8n.io/blog/2021-goals-level-up-your-vocabulary-with-vonage-and-n8n/","icon":"🎯","label":"2021 Goals: Level Up Your Vocabulary With Vonage and n8n"},{"url":"https://n8n.io/blog/2021-the-year-to-automate-the-new-you-with-n8n/","icon":"☀️","label":"2021: The Year to Automate the New You with n8n"},{"url":"https://n8n.io/blog/how-to-build-a-low-code-self-hosted-url-shortener/","icon":"🔗","label":"How to build a low-code, self-hosted URL shortener in 3 steps"},{"url":"https://n8n.io/blog/how-to-get-started-with-crm-automation-and-no-code-workflow-ideas/","icon":"👥","label":"How to get started with CRM automation (with 3 no-code workflow ideas"},{"url":"https://n8n.io/blog/automate-google-apps-for-productivity/","icon":"💡","label":"15 Google apps you can combine and automate to increase productivity"},{"url":"https://n8n.io/blog/building-an-expense-tracking-app-in-10-minutes/","icon":"📱","label":"Building an expense tracking app in 10 minutes"},{"url":"https://n8n.io/blog/why-this-product-manager-loves-workflow-automation-with-n8n/","icon":"🧠","label":"Why this Product Manager loves workflow automation with n8n"},{"url":"https://n8n.io/blog/learn-to-build-powerful-api-endpoints-using-webhooks/","icon":"🧰","label":"Learn to Build Powerful API Endpoints Using Webhooks"},{"url":"https://n8n.io/blog/sending-sms-the-low-code-way-with-airtable-twilio-programmable-sms-and-n8n/","icon":"📱","label":"Sending SMS the Low-Code Way with Airtable, Twilio Programmable SMS, and n8n"},{"url":"https://n8n.io/blog/automating-conference-organization-processes-with-n8n/","icon":"🙋‍♀️","label":"Automating Conference Organization Processes with n8n"},{"url":"https://n8n.io/blog/benefits-of-automation-and-n8n-an-interview-with-hubspots-hugh-durkin/","icon":"🎖","label":"Benefits of automation and n8n: An interview with HubSpot's Hugh Durkin"},{"url":"https://n8n.io/blog/how-goomer-automated-their-operations-with-over-200-n8n-workflows/","icon":"🛵","label":"How Goomer automated their operations with over 200 n8n workflows"},{"url":"https://n8n.io/blog/aws-workflow-automation/","label":"7 no-code workflow automations for Amazon Web Services"}],"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.airtable/"}],"credentialDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/credentials/airtable/"}]},"categories":["Data & Storage"],"nodeVersion":"1.0","codexVersion":"1.0"}},"group":"[\"input\"]","defaults":{"name":"Airtable"},"iconData":{"type":"file","fileBuffer":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMDAgMTcwIj48cGF0aCBmaWxsPSIjZmNiNDAwIiBkPSJNODkgNC44IDE2LjIgMzQuOWMtNC4xIDEuNy00IDcuNC4xIDkuMWw3My4yIDI5YzYuNCAyLjYgMTMuNiAyLjYgMjAgMGw3My4yLTI5YzQuMS0xLjYgNC4xLTcuNC4xLTkuMWwtNzMtMzAuMUMxMDMuMiAyIDk1LjcgMiA4OSA0LjgiLz48cGF0aCBmaWxsPSIjMThiZmZmIiBkPSJNMTA1LjkgODguOXY3Mi41YzAgMy40IDMuNSA1LjggNi43IDQuNWw4MS42LTMxLjdjMS45LS43IDMuMS0yLjUgMy4xLTQuNVY1Ny4yYzAtMy40LTMuNS01LjgtNi43LTQuNUwxMDkgODQuM2MtMS45LjgtMy4xIDIuNi0zLjEgNC42Ii8+PHBhdGggZmlsbD0iI2Y4MmI2MCIgZD0ibTg2LjkgOTIuNi0yNC4yIDExLjctMi41IDEuMkw5LjEgMTMwYy0zLjIgMS42LTcuNC0uOC03LjQtNC40VjU3LjVjMC0xLjMuNy0yLjQgMS42LTMuM3EuNi0uNiAxLjItLjljMS4yLS43IDMtLjkgNC40LS4zbDc3LjUgMzAuN2M0IDEuNSA0LjMgNy4xLjUgOC45Ii8+PHBhdGggZmlsbD0iI2JhMWU0NSIgZD0ibTg2LjkgOTIuNi0yNC4yIDExLjctNTkuNC01MHEuNi0uNiAxLjItLjljMS4yLS43IDMtLjkgNC40LS4zbDc3LjUgMzAuN2M0IDEuNCA0LjMgNyAuNSA4LjgiLz48L3N2Zz4="},"displayName":"Airtable","typeVersion":2,"nodeCategories":[{"id":3,"name":"Data & Storage"}]},{"id":24,"icon":"file:merge.svg","name":"n8n-nodes-base.merge","codex":{"data":{"alias":["Join","Concatenate","Wait"],"resources":{"generic":[{"url":"https://n8n.io/blog/how-to-sync-data-between-two-systems/","icon":"🏬","label":"How to synchronize data between two systems (one-way vs. two-way sync"},{"url":"https://n8n.io/blog/supercharging-your-conference-registration-process-with-n8n/","icon":"🎫","label":"Supercharging your conference registration process with n8n"},{"url":"https://n8n.io/blog/migrating-community-metrics-to-orbit-using-n8n/","icon":"📈","label":"Migrating Community Metrics to Orbit using n8n"},{"url":"https://n8n.io/blog/build-your-own-virtual-assistant-with-n8n-a-step-by-step-guide/","icon":"👦","label":"Build your own virtual assistant with n8n: A step by step guide"},{"url":"https://n8n.io/blog/sending-automated-congratulations-with-google-sheets-twilio-and-n8n/","icon":"🙌","label":"Sending Automated Congratulations with Google Sheets, Twilio, and n8n "},{"url":"https://n8n.io/blog/aws-workflow-automation/","label":"7 no-code workflow automations for Amazon Web Services"}],"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.merge/"}]},"categories":["Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"Core Nodes":["Flow","Data Transformation"]}}},"group":"[\"transform\"]","defaults":{"name":"Merge"},"iconData":{"type":"file","fileBuffer":"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTEyIiBoZWlnaHQ9IjUxMiIgdmlld0JveD0iMCAwIDUxMiA1MTIiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMF8xMTc3XzUxOCkiPgo8cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTAgNDhDMCAyMS40OTAzIDIxLjQ5MDMgMCA0OCAwSDExMkMxMzguNTEgMCAxNjAgMjEuNDkwMyAxNjAgNDhWNTZIMTk2LjI1MkMyNDAuNDM1IDU2IDI3Ni4yNTIgOTEuODE3MiAyNzYuMjUyIDEzNlYxOTJDMjc2LjI1MiAyMTQuMDkxIDI5NC4xNjEgMjMyIDMxNi4yNTIgMjMySDM1MlYyMjRDMzUyIDE5Ny40OSAzNzMuNDkgMTc2IDQwMCAxNzZINDY0QzQ5MC41MSAxNzYgNTEyIDE5Ny40OSA1MTIgMjI0VjI4OEM1MTIgMzE0LjUxIDQ5MC41MSAzMzYgNDY0IDMzNkg0MDBDMzczLjQ5IDMzNiAzNTIgMzE0LjUxIDM1MiAyODhWMjgwSDMxNi4yNTJDMjk0LjE2MSAyODAgMjc2LjI1MiAyOTcuOTA5IDI3Ni4yNTIgMzIwVjM3NkMyNzYuMjUyIDQyMC4xODMgMjQwLjQzNSA0NTYgMTk2LjI1MiA0NTZIMTYwVjQ2NEMxNjAgNDkwLjUxIDEzOC41MSA1MTIgMTEyIDUxMkg0OEMyMS40OTAzIDUxMiAwIDQ5MC41MSAwIDQ2NFY0MDBDMCAzNzMuNDkgMjEuNDkwMyAzNTIgNDggMzUySDExMkMxMzguNTEgMzUyIDE2MCAzNzMuNDkgMTYwIDQwMFY0MDhIMTk2LjI1MkMyMTMuOTI1IDQwOCAyMjguMjUyIDM5My42NzMgMjI4LjI1MiAzNzZWMzIwQzIyOC4yNTIgMjk0Ljc4NCAyMzguODU5IDI3Mi4wNDQgMjU1Ljg1MyAyNTZDMjM4Ljg1OSAyMzkuOTU2IDIyOC4yNTIgMjE3LjIxNiAyMjguMjUyIDE5MlYxMzZDMjI4LjI1MiAxMTguMzI3IDIxMy45MjUgMTA0IDE5Ni4yNTIgMTA0SDE2MFYxMTJDMTYwIDEzOC41MSAxMzguNTEgMTYwIDExMiAxNjBINDhDMjEuNDkwMyAxNjAgMCAxMzguNTEgMCAxMTJWNDhaTTEwNCA0OEMxMDguNDE4IDQ4IDExMiA1MS41ODE3IDExMiA1NlYxMDRDMTEyIDEwOC40MTggMTA4LjQxOCAxMTIgMTA0IDExMkg1NkM1MS41ODE3IDExMiA0OCAxMDguNDE4IDQ4IDEwNFY1NkM0OCA1MS41ODE3IDUxLjU4MTcgNDggNTYgNDhIMTA0Wk00NTYgMjI0QzQ2MC40MTggMjI0IDQ2NCAyMjcuNTgyIDQ2NCAyMzJWMjgwQzQ2NCAyODQuNDE4IDQ2MC40MTggMjg4IDQ1NiAyODhINDA4QzQwMy41ODIgMjg4IDQwMCAyODQuNDE4IDQwMCAyODBWMjMyQzQwMCAyMjcuNTgyIDQwMy41ODIgMjI0IDQwOCAyMjRINDU2Wk0xMTIgNDA4QzExMiA0MDMuNTgyIDEwOC40MTggNDAwIDEwNCA0MDBINTZDNTEuNTgxNyA0MDAgNDggNDAzLjU4MiA0OCA0MDhWNDU2QzQ4IDQ2MC40MTggNTEuNTgxNyA0NjQgNTYgNDY0SDEwNEMxMDguNDE4IDQ2NCAxMTIgNDYwLjQxOCAxMTIgNDU2VjQwOFoiIGZpbGw9IiM1NEI4QzkiLz4KPC9nPgo8ZGVmcz4KPGNsaXBQYXRoIGlkPSJjbGlwMF8xMTc3XzUxOCI+CjxyZWN0IHdpZHRoPSI1MTIiIGhlaWdodD0iNTEyIiBmaWxsPSJ3aGl0ZSIvPgo8L2NsaXBQYXRoPgo8L2RlZnM+Cjwvc3ZnPgo="},"displayName":"Merge","typeVersion":3,"nodeCategories":[{"id":9,"name":"Core Nodes"}]},{"id":38,"icon":"fa:pen","name":"n8n-nodes-base.set","codex":{"data":{"alias":["Set","JS","JSON","Filter","Transform","Map"],"resources":{"generic":[{"url":"https://n8n.io/blog/learn-to-automate-your-factorys-incident-reporting-a-step-by-step-guide/","icon":"🏭","label":"Learn to Automate Your Factory's Incident Reporting: A Step by Step Guide"},{"url":"https://n8n.io/blog/2021-the-year-to-automate-the-new-you-with-n8n/","icon":"☀️","label":"2021: The Year to Automate the New You with n8n"},{"url":"https://n8n.io/blog/automatically-pulling-and-visualizing-data-with-n8n/","icon":"📈","label":"Automatically pulling and visualizing data with n8n"},{"url":"https://n8n.io/blog/database-monitoring-and-alerting-with-n8n/","icon":"📡","label":"Database Monitoring and Alerting with n8n"},{"url":"https://n8n.io/blog/automatically-adding-expense-receipts-to-google-sheets-with-telegram-mindee-twilio-and-n8n/","icon":"🧾","label":"Automatically Adding Expense Receipts to Google Sheets with Telegram, Mindee, Twilio, and n8n"},{"url":"https://n8n.io/blog/no-code-ecommerce-workflow-automations/","icon":"store","label":"6 e-commerce workflows to power up your Shopify s"},{"url":"https://n8n.io/blog/how-to-build-a-low-code-self-hosted-url-shortener/","icon":"🔗","label":"How to build a low-code, self-hosted URL shortener in 3 steps"},{"url":"https://n8n.io/blog/automate-your-data-processing-pipeline-in-9-steps-with-n8n/","icon":"⚙️","label":"Automate your data processing pipeline in 9 steps"},{"url":"https://n8n.io/blog/how-to-get-started-with-crm-automation-and-no-code-workflow-ideas/","icon":"👥","label":"How to get started with CRM automation (with 3 no-code workflow ideas"},{"url":"https://n8n.io/blog/5-tasks-you-can-automate-with-notion-api/","icon":"⚡️","label":"5 tasks you can automate with the new Notion API "},{"url":"https://n8n.io/blog/automate-google-apps-for-productivity/","icon":"💡","label":"15 Google apps you can combine and automate to increase productivity"},{"url":"https://n8n.io/blog/how-uproc-scraped-a-multi-page-website-with-a-low-code-workflow/","icon":" 🕸️","label":"How uProc scraped a multi-page website with a low-code workflow"},{"url":"https://n8n.io/blog/building-an-expense-tracking-app-in-10-minutes/","icon":"📱","label":"Building an expense tracking app in 10 minutes"},{"url":"https://n8n.io/blog/the-ultimate-guide-to-automate-your-video-collaboration-with-whereby-mattermost-and-n8n/","icon":"📹","label":"The ultimate guide to automate your video collaboration with Whereby, Mattermost, and n8n"},{"url":"https://n8n.io/blog/5-workflow-automations-for-mattermost-that-we-love-at-n8n/","icon":"🤖","label":"5 workflow automations for Mattermost that we love at n8n"},{"url":"https://n8n.io/blog/learn-to-build-powerful-api-endpoints-using-webhooks/","icon":"🧰","label":"Learn to Build Powerful API Endpoints Using Webhooks"},{"url":"https://n8n.io/blog/how-a-membership-development-manager-automates-his-work-and-investments/","icon":"📈","label":"How a Membership Development Manager automates his work and investments"},{"url":"https://n8n.io/blog/a-low-code-bitcoin-ticker-built-with-questdb-and-n8n-io/","icon":"📈","label":"A low-code bitcoin ticker built with QuestDB and n8n.io"},{"url":"https://n8n.io/blog/how-to-set-up-a-ci-cd-pipeline-with-no-code/","icon":"🎡","label":"How to set up a no-code CI/CD pipeline with GitHub and TravisCI"},{"url":"https://n8n.io/blog/benefits-of-automation-and-n8n-an-interview-with-hubspots-hugh-durkin/","icon":"🎖","label":"Benefits of automation and n8n: An interview with HubSpot's Hugh Durkin"},{"url":"https://n8n.io/blog/how-goomer-automated-their-operations-with-over-200-n8n-workflows/","icon":"🛵","label":"How Goomer automated their operations with over 200 n8n workflows"},{"url":"https://n8n.io/blog/aws-workflow-automation/","label":"7 no-code workflow automations for Amazon Web Services"}],"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.set/"}]},"categories":["Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"Core Nodes":["Data Transformation"]}}},"group":"[\"input\"]","defaults":{"name":"Edit Fields"},"iconData":{"icon":"pen","type":"icon"},"displayName":"Edit Fields (Set)","typeVersion":3,"nodeCategories":[{"id":9,"name":"Core Nodes"}]},{"id":40,"icon":"file:slack.svg","name":"n8n-nodes-base.slack","codex":{"data":{"alias":["human","form","wait","hitl","approval"],"resources":{"generic":[{"url":"https://n8n.io/blog/no-code-ecommerce-workflow-automations/","icon":"store","label":"6 e-commerce workflows to power up your Shopify s"},{"url":"https://n8n.io/blog/automate-your-data-processing-pipeline-in-9-steps-with-n8n/","icon":"⚙️","label":"Automate your data processing pipeline in 9 steps"},{"url":"https://n8n.io/blog/how-to-get-started-with-crm-automation-and-no-code-workflow-ideas/","icon":"👥","label":"How to get started with CRM automation (with 3 no-code workflow ideas"},{"url":"https://n8n.io/blog/5-tasks-you-can-automate-with-notion-api/","icon":"⚡️","label":"5 tasks you can automate with the new Notion API "},{"url":"https://n8n.io/blog/build-your-own-virtual-assistant-with-n8n-a-step-by-step-guide/","icon":"👦","label":"Build your own virtual assistant with n8n: A step by step guide"},{"url":"https://n8n.io/blog/how-to-automatically-give-kudos-to-contributors-with-github-slack-and-n8n/","icon":"👏","label":"How to automatically give kudos to contributors with GitHub, Slack, and n8n"},{"url":"https://n8n.io/blog/automations-for-activists/","icon":"✨","label":"How Common Knowledge use workflow automation for activism"}],"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.slack/"}],"credentialDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/credentials/slack/"}]},"categories":["Communication","HITL"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"HITL":["Human in the Loop"]}}},"group":"[\"output\"]","defaults":{"name":"Slack"},"iconData":{"type":"file","fileBuffer":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiBmaWxsPSIjZmZmIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiB2aWV3Qm94PSIwIDAgMTUwLjg1MiAxNTAuODUyIj48dXNlIHhsaW5rOmhyZWY9IiNhIiB4PSIuOTI2IiB5PSIuOTI2Ii8+PHN5bWJvbCBpZD0iYSIgb3ZlcmZsb3c9InZpc2libGUiPjxnIHN0cm9rZS13aWR0aD0iMS44NTIiPjxwYXRoIGZpbGw9IiNlMDFlNWEiIHN0cm9rZT0iI2UwMWU1YSIgZD0iTTQwLjc0MSA5My41NWMwLTguNzM1IDYuNjA3LTE1Ljc3MiAxNC44MTUtMTUuNzcyczE0LjgxNSA3LjAzNyAxNC44MTUgMTUuNzcydjM4LjgyNGMwIDguNzM3LTYuNjA3IDE1Ljc3NC0xNC44MTUgMTUuNzc0cy0xNC44MTUtNy4wMzctMTQuODE1LTE1Ljc3MnoiLz48cGF0aCBmaWxsPSIjZWNiMjJkIiBzdHJva2U9IiNlY2IyMmQiIGQ9Ik05My41NSAxMDcuNDA4Yy04LjczNSAwLTE1Ljc3Mi02LjYwNy0xNS43NzItMTQuODE1czcuMDM3LTE0LjgxNSAxNS43NzItMTQuODE1aDM4LjgyNmM4LjczNSAwIDE1Ljc3MiA2LjYwNyAxNS43NzIgMTQuODE1cy03LjAzNyAxNC44MTUtMTUuNzcyIDE0LjgxNXoiLz48cGF0aCBmaWxsPSIjMmZiNjdjIiBzdHJva2U9IiMyZmI2N2MiIGQ9Ik03Ny43NzggMTUuNzcyQzc3Ljc3OCA3LjAzNyA4NC4zODUgMCA5Mi41OTMgMHMxNC44MTUgNy4wMzcgMTQuODE1IDE1Ljc3MnYzOC44MjZjMCA4LjczNS02LjYwNyAxNS43NzItMTQuODE1IDE1Ljc3MnMtMTQuODE1LTcuMDM3LTE0LjgxNS0xNS43NzJ6Ii8+PHBhdGggZmlsbD0iIzM2YzVmMSIgc3Ryb2tlPSIjMzZjNWYxIiBkPSJNMTUuNzcyIDcwLjM3MUM3LjAzNyA3MC4zNzEgMCA2My43NjMgMCA1NS41NTZzNy4wMzctMTQuODE1IDE1Ljc3Mi0xNC44MTVoMzguODI2YzguNzM1IDAgMTUuNzcyIDYuNjA3IDE1Ljc3MiAxNC44MTVzLTcuMDM3IDE0LjgxNS0xNS43NzIgMTQuODE1eiIvPjxnIHN0cm9rZS1saW5lam9pbj0ibWl0ZXIiPjxwYXRoIGZpbGw9IiNlY2IyMmQiIHN0cm9rZT0iI2VjYjIyZCIgZD0iTTc3Ljc3OCAxMzMuMzMzYzAgOC4yMDggNi42MDcgMTQuODE1IDE0LjgxNSAxNC44MTVzMTQuODE1LTYuNjA3IDE0LjgxNS0xNC44MTUtNi42MDctMTQuODE1LTE0LjgxNS0xNC44MTVINzcuNzc4eiIvPjxwYXRoIGZpbGw9IiMyZmI2N2MiIHN0cm9rZT0iIzJmYjY3YyIgZD0iTTEzMy4zMzQgNzAuMzcxaC0xNC44MTVWNTUuNTU2YzAtOC4yMDcgNi42MDctMTQuODE1IDE0LjgxNS0xNC44MTVzMTQuODE1IDYuNjA3IDE0LjgxNSAxNC44MTUtNi42MDcgMTQuODE1LTE0LjgxNSAxNC44MTV6Ii8+PHBhdGggZmlsbD0iI2UwMWU1YSIgc3Ryb2tlPSIjZTAxZTVhIiBkPSJNMTQuODE1IDc3Ljc3OEgyOS42M3YxNC44MTVjMCA4LjIwNy02LjYwNyAxNC44MTUtMTQuODE1IDE0LjgxNVMwIDEwMC44IDAgOTIuNTkzczYuNjA3LTE0LjgxNSAxNC44MTUtMTQuODE1eiIvPjxwYXRoIGZpbGw9IiMzNmM1ZjEiIHN0cm9rZT0iIzM2YzVmMSIgZD0iTTcwLjM3MSAxNC44MTVWMjkuNjNINTUuNTU2Yy04LjIwNyAwLTE0LjgxNS02LjYwNy0xNC44MTUtMTQuODE1UzQ3LjM0OCAwIDU1LjU1NiAwczE0LjgxNSA2LjYwNyAxNC44MTUgMTQuODE1eiIvPjwvZz48L2c+PC9zeW1ib2w+PC9zdmc+"},"displayName":"Slack","typeVersion":2,"nodeCategories":[{"id":6,"name":"Communication"},{"id":28,"name":"HITL"}]},{"id":298,"icon":"file:wooCommerce.svg","name":"n8n-nodes-base.wooCommerce","codex":{"data":{"resources":{"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.woocommerce/"}],"credentialDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/credentials/woocommerce/"}]},"categories":["Sales"],"nodeVersion":"1.0","codexVersion":"1.0"}},"group":"[\"output\"]","defaults":{"name":"WooCommerce"},"iconData":{"type":"file","fileBuffer":"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAyOC4yLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iTGF5ZXJfMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiDQoJIHZpZXdCb3g9IjAgMCAxODMuNiA0Ny41IiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCAxODMuNiA0Ny41OyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+DQo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPg0KCS5zdDB7ZmlsbC1ydWxlOmV2ZW5vZGQ7Y2xpcC1ydWxlOmV2ZW5vZGQ7ZmlsbDojODczRUZGO30NCgkuc3Qxe2ZpbGwtcnVsZTpldmVub2RkO2NsaXAtcnVsZTpldmVub2RkO30NCgkuc3Qye2ZpbGw6Izg3M0VGRjt9DQoJLnN0M3tmaWxsLXJ1bGU6ZXZlbm9kZDtjbGlwLXJ1bGU6ZXZlbm9kZDtmaWxsOiNGRkZGRkY7fQ0KCS5zdDR7ZmlsbDojRkZGRkZGO30NCjwvc3R5bGU+DQo8Zz4NCgk8cGF0aCBjbGFzcz0ic3QwIiBkPSJNNzcuNCwwYy00LjMsMC03LjEsMS40LTkuNiw2LjFMNTYuNCwyNy42VjguNWMwLTUuNy0yLjctOC41LTcuNy04LjVzLTcuMSwxLjctOS42LDYuNUwyOC4zLDI3LjZWOC43DQoJCWMwLTYuMS0yLjUtOC43LTguNi04LjdINy4zQzIuNiwwLDAsMi4yLDAsNi4yczIuNSw2LjQsNy4xLDYuNGg1LjF2MjQuMWMwLDYuOCw0LjYsMTAuOCwxMS4yLDEwLjhzOS42LTIuNiwxMi45LTguN2w3LjItMTMuNXYxMS40DQoJCWMwLDYuNyw0LjQsMTAuOCwxMS4xLDEwLjhzOS4yLTIuMywxMy04LjdsMTYuNi0yOEM4Ny44LDQuNyw4NS4zLDAsNzcuMywwQzc3LjMsMCw3Ny4zLDAsNzcuNCwweiIvPg0KCTxwYXRoIGNsYXNzPSJzdDAiIGQ9Ik0xMDguNiwwQzk1LDAsODQuNywxMC4xLDg0LjcsMjMuOHMxMC40LDIzLjcsMjMuOSwyMy43czIzLjgtMTAuMSwyMy45LTIzLjdDMTMyLjUsMTAuMSwxMjIuMSwwLDEwOC42LDB6DQoJCSBNMTA4LjYsMzIuOWMtNS4xLDAtOC42LTMuOC04LjYtOS4xczMuNS05LjIsOC42LTkuMnM4LjYsMy45LDguNiw5LjJTMTEzLjgsMzIuOSwxMDguNiwzMi45eiIvPg0KCTxwYXRoIGNsYXNzPSJzdDAiIGQ9Ik0xNTkuNywwYy0xMy41LDAtMjMuOSwxMC4xLTIzLjksMjMuOHMxMC40LDIzLjcsMjMuOSwyMy43czIzLjktMTAuMSwyMy45LTIzLjdTMTczLjIsMCwxNTkuNywweiBNMTU5LjcsMzIuOQ0KCQljLTUuMiwwLTguNS0zLjgtOC41LTkuMXMzLjQtOS4yLDguNS05LjJzOC42LDMuOSw4LjYsOS4yUzE2NC45LDMyLjksMTU5LjcsMzIuOXoiLz4NCjwvZz4NCjwvc3ZnPg0K"},"displayName":"WooCommerce","typeVersion":1,"nodeCategories":[{"id":2,"name":"Sales"}]},{"id":565,"icon":"fa:sticky-note","name":"n8n-nodes-base.stickyNote","codex":{"data":{"alias":["Comments","Notes","Sticky"],"categories":["Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"Core Nodes":["Helpers"]}}},"group":"[\"input\"]","defaults":{"name":"Sticky Note","color":"#FFD233"},"iconData":{"icon":"sticky-note","type":"icon"},"displayName":"Sticky Note","typeVersion":1,"nodeCategories":[{"id":9,"name":"Core Nodes"}]},{"id":834,"icon":"file:code.svg","name":"n8n-nodes-base.code","codex":{"data":{"alias":["cpde","Javascript","JS","Python","Script","Custom Code","Function"],"details":"The Code node allows you to execute JavaScript in your workflow.","resources":{"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.code/"}]},"categories":["Development","Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"Core Nodes":["Helpers","Data Transformation"]}}},"group":"[\"transform\"]","defaults":{"name":"Code"},"iconData":{"type":"file","fileBuffer":"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTEyIiBoZWlnaHQ9IjUxMiIgdmlld0JveD0iMCAwIDUxMiA1MTIiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMF8xMTcxXzQ0MSkiPgo8cGF0aCBkPSJNMTcwLjI4MyA0OEgxOTYuNUMyMDMuMTI3IDQ4IDIwOC41IDQyLjYyNzQgMjA4LjUgMzZWMTJDMjA4LjUgNS4zNzI1OCAyMDMuMTI3IDAgMTk2LjUgMEgxNzAuMjgzQzEyNi4xIDAgOTAuMjgzIDM1LjgxNzIgOTAuMjgzIDgwVjE3NkM5MC4yODMgMjA2LjkyOCA2NS4yMTA5IDIzMiAzNC4yODMgMjMySDIzQzE2LjM3MjYgMjMyIDExIDIzNy4zNzIgMTEgMjQ0VjI2OEMxMSAyNzQuNjI3IDE2LjM3MjQgMjgwIDIyLjk5OTYgMjgwTDM0LjI4MyAyODBDNjUuMjEwOSAyODAgOTAuMjgzIDMwNS4wNzIgOTAuMjgzIDMzNlY0NDBDOTAuMjgzIDQ3OS43NjQgMTIyLjUxOCA1MTIgMTYyLjI4MyA1MTJIMTk2LjVDMjAzLjEyNyA1MTIgMjA4LjUgNTA2LjYyNyAyMDguNSA1MDBWNDc2QzIwOC41IDQ2OS4zNzMgMjAzLjEyNyA0NjQgMTk2LjUgNDY0SDE2Mi4yODNDMTQ5LjAyOCA0NjQgMTM4LjI4MyA0NTMuMjU1IDEzOC4yODMgNDQwVjMzNkMxMzguMjgzIDMwOS4wMjIgMTI4LjAxMSAyODQuNDQzIDExMS4xNjQgMjY1Ljk2MUMxMDYuMTA5IDI2MC40MTYgMTA2LjEwOSAyNTEuNTg0IDExMS4xNjQgMjQ2LjAzOUMxMjguMDExIDIyNy41NTcgMTM4LjI4MyAyMDIuOTc4IDEzOC4yODMgMTc2VjgwQzEzOC4yODMgNjIuMzI2OSAxNTIuNjEgNDggMTcwLjI4MyA0OFoiIGZpbGw9IiNGRjk5MjIiLz4KPHBhdGggZD0iTTMwNSAzNkMzMDUgNDIuNjI3NCAzMTAuMzczIDQ4IDMxNyA0OEgzNDIuOTc5QzM2MC42NTIgNDggMzc0Ljk3OCA2Mi4zMjY5IDM3NC45NzggODBWMTc2QzM3NC45NzggMjAyLjk3OCAzODUuMjUxIDIyNy41NTcgNDAyLjA5OCAyNDYuMDM5QzQwNy4xNTMgMjUxLjU4NCA0MDcuMTUzIDI2MC40MTYgNDAyLjA5OCAyNjUuOTYxQzM4NS4yNTEgMjg0LjQ0MyAzNzQuOTc4IDMwOS4wMjIgMzc0Ljk3OCAzMzZWNDMyQzM3NC45NzggNDQ5LjY3MyAzNjAuNjUyIDQ2NCAzNDIuOTc5IDQ2NEgzMTdDMzEwLjM3MyA0NjQgMzA1IDQ2OS4zNzMgMzA1IDQ3NlY1MDBDMzA1IDUwNi42MjcgMzEwLjM3MyA1MTIgMzE3IDUxMkgzNDIuOTc5QzM4Ny4xNjEgNTEyIDQyMi45NzggNDc2LjE4MyA0MjIuOTc4IDQzMlYzMzZDNDIyLjk3OCAzMDUuMDcyIDQ0OC4wNTEgMjgwIDQ3OC45NzkgMjgwSDQ5MEM0OTYuNjI3IDI4MCA1MDIgMjc0LjYyOCA1MDIgMjY4VjI0NEM1MDIgMjM3LjM3MyA0OTYuNjI4IDIzMiA0OTAgMjMyTDQ3OC45NzkgMjMyQzQ0OC4wNTEgMjMyIDQyMi45NzggMjA2LjkyOCA0MjIuOTc4IDE3NlY4MEM0MjIuOTc4IDM1LjgxNzIgMzg3LjE2MSAwIDM0Mi45NzkgMEgzMTdDMzEwLjM3MyAwIDMwNSA1LjM3MjU4IDMwNSAxMlYzNloiIGZpbGw9IiNGRjk5MjIiLz4KPC9nPgo8ZGVmcz4KPGNsaXBQYXRoIGlkPSJjbGlwMF8xMTcxXzQ0MSI+CjxyZWN0IHdpZHRoPSI1MTIiIGhlaWdodD0iNTEyIiBmaWxsPSJ3aGl0ZSIvPgo8L2NsaXBQYXRoPgo8L2RlZnM+Cjwvc3ZnPgo="},"displayName":"Code","typeVersion":2,"nodeCategories":[{"id":5,"name":"Development"},{"id":9,"name":"Core Nodes"}]},{"id":839,"icon":"fa:clock","name":"n8n-nodes-base.scheduleTrigger","codex":{"data":{"alias":["Time","Scheduler","Polling","Cron","Interval"],"resources":{"generic":[],"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.scheduletrigger/"}]},"categories":["Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0"}},"group":"[\"trigger\",\"schedule\"]","defaults":{"name":"Schedule Trigger","color":"#31C49F"},"iconData":{"icon":"clock","type":"icon"},"displayName":"Schedule Trigger","typeVersion":1,"nodeCategories":[{"id":9,"name":"Core Nodes"}]}],"categories":[{"id":39,"name":"CRM"},{"id":49,"name":"AI Summarization"}],"image":[]}}