Get a daily business report in your inbox every morning — automate it with n8n (free workflow JSON) Free n8n workflow that automates the creation of a daily business report. The workflow reads sales data from a Google Sheet, calculates key metrics like revenue and order count, and sends a formatted HTML email and optional Slack message every morning. It is designed to save founders the time and effort of manually checking multiple business tools each day. Every founder has some version of a morning ritual: open 4 different tabs, check Stripe, check analytics, check the spreadsheet, try to mentally add up whether yesterday was a good day. That's 15 minutes every morning. 250+ times a year. 60+ hours you'll never get back. Here's a 5-node n8n workflow that compiles your daily business metrics and delivers a clean formatted report to your inbox and Slack at 7 AM â automatically, every single day. What the workflow does Node 1 â Daily schedule trigger Fires every morning at a configurable time. No polling, no manual runs. Set it once, forget it forever. Node 2 â Google Sheets: read your metrics Reads your business data from a Google Sheet â sales rows, revenue, order counts. The default expects columns Date , Revenue , Orders but you can reshape the Code node to match whatever you already track. Node 3 â Code node: calculate KPIs Processes the raw rows and computes: - Total revenue for the period Order count Average order value - Week-over-week change yesterday vs same day last week The math is plain JavaScript â readable and easy to adjust. Node 4 â Gmail: send the HTML report Sends a clean, formatted HTML email with metric cards. Revenue in green, orders in blue, average order in purple, week-on-week trend in orange. You open your email and immediately know if yesterday was good or bad. Node 5 â Slack: post the summary Posts a concise text summary to a Slack webhook. Optional â just delete this node if you don't use Slack. Full workflow JSON { "name": "Daily Business Report Generator", "nodes": {"parameters":{"rule":{"interval": {"field":"cronExpression","expression":"0 7 "} }},"id":"dr1","name":"Every Day at 7 AM","type":"n8n-nodes-base.scheduleTrigger","typeVersion":1.2,"position": 240,300 }, {"parameters":{"documentId":{" rl":true,"value":"YOUR SHEET ID","mode":"id"},"sheetName":{" rl":true,"value":"Sales","mode":"name"},"options":{"rangeDefinition":"specifyRangeA1","range":"A:E"}},"id":"dr2","name":"Read Sales Data","type":"n8n-nodes-base.googleSheets","typeVersion":4.5,"position": 460,300 }, {"parameters":{"jsCode":"const rows = $input.all ;\nconst today = new Date .toLocaleDateString 'en-US', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' } ;\nconst sales = rows.map r = parseFloat r.json.Revenue || 0 ;\nconst totalRevenue = sales.reduce a, b = a + b, 0 ;\nconst orderCount = rows.filter r = r.json.Revenue && parseFloat r.json.Revenue 0 .length;\nconst avgOrderValue = orderCount 0 ? totalRevenue / orderCount .toFixed 2 : 0;\nconst yesterday = parseFloat rows.slice -1 0 ?.json?.Revenue || 0 ;\nconst weekAgo = parseFloat rows.slice -8, -7 0 ?.json?.Revenue || 0 ;\nconst weekChange = weekAgo 0 ? yesterday - weekAgo / weekAgo 100 .toFixed 1 : 'N/A';\nreturn { json: { date: today, totalRevenue: totalRevenue.toFixed 2 , orderCount, avgOrderValue, weekOverWeekChange: weekChange } } ;"},"id":"dr3","name":"Calculate KPIs","type":"n8n-nodes-base.code","typeVersion":2,"position": 680,300 }, {"parameters":{"sendTo":"you@yourbusiness.com","subject":"={{ '📊 Daily Report — ' + $json.date }}","emailType":"html","message":"=