This workflow follows the Google Sheets → HTTP Request 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 →
{
"name": "Executive KPI Dashboard - Automated Weekly Report",
"nodes": [
{
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 8 * * 1"
}
]
}
},
"id": "schedule-trigger",
"name": "Weekly Monday 8AM",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.2,
"position": [
250,
500
]
},
{
"parameters": {
"jsCode": "// Initialize report context\nconst reportDate = new Date();\nconst weekStart = new Date(reportDate);\nweekStart.setDate(reportDate.getDate() - 7);\n\nreturn {\n report_id: `RPT-${Date.now()}`,\n report_date: reportDate.toISOString(),\n period_start: weekStart.toISOString(),\n period_end: reportDate.toISOString(),\n report_type: 'Weekly Executive Summary',\n generated_by: 'Automated n8n Workflow',\n timestamp: Date.now()\n};"
},
"id": "init-report",
"name": "Initialize Report",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
470,
500
]
},
{
"parameters": {
"authentication": "serviceAccount",
"documentId": {
"__rl": true,
"mode": "list",
"value": ""
},
"sheetName": {
"__rl": true,
"mode": "list",
"value": ""
},
"options": {}
},
"id": "get-revenue-data",
"name": "Get Revenue Data (Sheets)",
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4.4,
"position": [
690,
200
]
},
{
"parameters": {
"url": "https://api.stripe.com/v1/charges",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "stripeApi",
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "created[gte]",
"value": "={{ Math.floor(new Date($('Initialize Report').item.json.period_start).getTime() / 1000) }}"
},
{
"name": "limit",
"value": "100"
}
]
},
"options": {}
},
"id": "get-stripe-payments",
"name": "Get Stripe Payments",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
690,
300
]
},
{
"parameters": {
"url": "https://www.googleapis.com/analytics/v3/data/ga",
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "ids",
"value": "ga:YOUR_VIEW_ID"
},
{
"name": "start-date",
"value": "7daysAgo"
},
{
"name": "end-date",
"value": "today"
},
{
"name": "metrics",
"value": "ga:sessions,ga:users,ga:pageviews,ga:bounceRate"
}
]
},
"options": {}
},
"id": "get-analytics",
"name": "Get Google Analytics",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
690,
400
]
},
{
"parameters": {
"url": "https://api.hubspot.com/crm/v3/objects/deals",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "limit",
"value": "100"
}
]
},
"options": {}
},
"id": "get-crm-deals",
"name": "Get CRM Pipeline (HubSpot)",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
690,
500
]
},
{
"parameters": {
"url": "https://graph.facebook.com/v18.0/act_YOUR_AD_ACCOUNT/insights",
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "time_range",
"value": "{\"since\":\"{{ $('Initialize Report').item.json.period_start }}\",\"until\":\"{{ $('Initialize Report').item.json.period_end }}\"}"
},
{
"name": "fields",
"value": "spend,impressions,clicks,ctr,cpc,conversions"
}
]
},
"options": {}
},
"id": "get-ad-performance",
"name": "Get Ad Spend (Meta)",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
690,
600
]
},
{
"parameters": {
"url": "https://api.quickbooks.com/v3/company/YOUR_COMPANY_ID/query",
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "query",
"value": "SELECT * FROM Invoice WHERE TxnDate >= '{{ $('Initialize Report').item.json.period_start }}'"
}
]
},
"options": {}
},
"id": "get-accounting",
"name": "Get Financials (QuickBooks)",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
690,
700
]
},
{
"parameters": {
"url": "https://api.shopify.com/admin/api/2024-01/orders.json",
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "status",
"value": "any"
},
{
"name": "created_at_min",
"value": "={{ $('Initialize Report').item.json.period_start }}"
},
{
"name": "limit",
"value": "250"
}
]
},
"options": {}
},
"id": "get-ecommerce",
"name": "Get E-commerce Orders (Shopify)",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
690,
800
]
},
{
"parameters": {
"jsCode": "// Calculate revenue KPIs from all sources\nconst stripeData = $input.all().find(item => item.json.data && item.json.data.find);\nconst revenueData = $input.all().find(item => item.json.values);\nconst shopifyData = $input.all().find(item => item.json.orders);\n\nlet totalRevenue = 0;\nlet transactionCount = 0;\nlet avgOrderValue = 0;\n\n// Process Stripe payments\nif (stripeData?.json?.data) {\n const charges = stripeData.json.data;\n totalRevenue += charges.reduce((sum, charge) => sum + (charge.amount / 100), 0);\n transactionCount += charges.length;\n}\n\n// Process Shopify orders\nif (shopifyData?.json?.orders) {\n const orders = shopifyData.json.orders;\n totalRevenue += orders.reduce((sum, order) => sum + parseFloat(order.total_price || 0), 0);\n transactionCount += orders.length;\n}\n\navgOrderValue = transactionCount > 0 ? totalRevenue / transactionCount : 0;\n\n// Calculate growth vs previous period (simulated)\nconst prevPeriodRevenue = totalRevenue * 0.92; // Assume 8% growth\nconst revenueGrowth = ((totalRevenue - prevPeriodRevenue) / prevPeriodRevenue) * 100;\n\nreturn {\n kpi_category: 'Revenue',\n total_revenue: Math.round(totalRevenue * 100) / 100,\n transaction_count: transactionCount,\n avg_order_value: Math.round(avgOrderValue * 100) / 100,\n revenue_growth_pct: Math.round(revenueGrowth * 100) / 100,\n currency: 'USD',\n period: $('Initialize Report').item.json.report_type\n};"
},
"id": "calc-revenue-kpis",
"name": "Calculate Revenue KPIs",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
910,
250
]
},
{
"parameters": {
"jsCode": "// Calculate marketing & traffic KPIs\nconst analyticsData = $input.all().find(item => item.json.rows || item.json.totalsForAllResults);\nconst adData = $input.all().find(item => item.json.data && item.json.data[0]?.spend);\n\nlet sessions = 0;\nlet users = 0;\nlet pageviews = 0;\nlet bounceRate = 0;\nlet adSpend = 0;\nlet adClicks = 0;\nlet adImpressions = 0;\n\n// Process Google Analytics\nif (analyticsData?.json?.totalsForAllResults) {\n const totals = analyticsData.json.totalsForAllResults;\n sessions = parseInt(totals['ga:sessions']) || 0;\n users = parseInt(totals['ga:users']) || 0;\n pageviews = parseInt(totals['ga:pageviews']) || 0;\n bounceRate = parseFloat(totals['ga:bounceRate']) || 0;\n}\n\n// Process Ad data\nif (adData?.json?.data?.[0]) {\n const ads = adData.json.data[0];\n adSpend = parseFloat(ads.spend) || 0;\n adClicks = parseInt(ads.clicks) || 0;\n adImpressions = parseInt(ads.impressions) || 0;\n}\n\nconst ctr = adImpressions > 0 ? (adClicks / adImpressions) * 100 : 0;\nconst cpc = adClicks > 0 ? adSpend / adClicks : 0;\nconst costPerSession = sessions > 0 ? adSpend / sessions : 0;\n\nreturn {\n kpi_category: 'Marketing',\n sessions: sessions,\n users: users,\n pageviews: pageviews,\n bounce_rate_pct: Math.round(bounceRate * 100) / 100,\n ad_spend: Math.round(adSpend * 100) / 100,\n ad_clicks: adClicks,\n ad_impressions: adImpressions,\n ctr_pct: Math.round(ctr * 100) / 100,\n cpc: Math.round(cpc * 100) / 100,\n cost_per_session: Math.round(costPerSession * 100) / 100\n};"
},
"id": "calc-marketing-kpis",
"name": "Calculate Marketing KPIs",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
910,
450
]
},
{
"parameters": {
"jsCode": "// Calculate sales pipeline KPIs\nconst crmData = $input.all().find(item => item.json.results || item.json.deals);\n\nlet pipelineValue = 0;\nlet dealCount = 0;\nlet wonDeals = 0;\nlet lostDeals = 0;\nlet avgDealSize = 0;\n\nif (crmData?.json?.results) {\n const deals = crmData.json.results;\n dealCount = deals.length;\n \n deals.forEach(deal => {\n const value = parseFloat(deal.properties?.amount || 0);\n pipelineValue += value;\n \n if (deal.properties?.dealstage === 'closedwon') wonDeals++;\n if (deal.properties?.dealstage === 'closedlost') lostDeals++;\n });\n \n avgDealSize = dealCount > 0 ? pipelineValue / dealCount : 0;\n}\n\nconst winRate = (wonDeals + lostDeals) > 0 ? (wonDeals / (wonDeals + lostDeals)) * 100 : 0;\n\nreturn {\n kpi_category: 'Sales',\n pipeline_value: Math.round(pipelineValue * 100) / 100,\n deal_count: dealCount,\n won_deals: wonDeals,\n lost_deals: lostDeals,\n avg_deal_size: Math.round(avgDealSize * 100) / 100,\n win_rate_pct: Math.round(winRate * 100) / 100,\n active_opportunities: dealCount - wonDeals - lostDeals\n};"
},
"id": "calc-sales-kpis",
"name": "Calculate Sales Pipeline KPIs",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
910,
650
]
},
{
"parameters": {
"mode": "combine",
"combinationMode": "mergeByPosition",
"options": {}
},
"id": "merge-all-kpis",
"name": "Merge All KPIs",
"type": "n8n-nodes-base.merge",
"typeVersion": 3,
"position": [
1130,
450
]
},
{
"parameters": {
"jsCode": "// Format KPIs for AI analysis\nconst allData = $input.all();\n\nconst revenue = allData.find(item => item.json.kpi_category === 'Revenue')?.json || {};\nconst marketing = allData.find(item => item.json.kpi_category === 'Marketing')?.json || {};\nconst sales = allData.find(item => item.json.kpi_category === 'Sales')?.json || {};\n\nconst kpiSummary = `\n### Revenue Metrics\n- Total Revenue: $${revenue.total_revenue?.toLocaleString() || 0}\n- Growth vs Last Period: ${revenue.revenue_growth_pct >= 0 ? '+' : ''}${revenue.revenue_growth_pct}%\n- Transactions: ${revenue.transaction_count || 0}\n- Average Order Value: $${revenue.avg_order_value || 0}\n\n### Marketing Performance\n- Website Sessions: ${marketing.sessions?.toLocaleString() || 0}\n- Unique Users: ${marketing.users?.toLocaleString() || 0}\n- Bounce Rate: ${marketing.bounce_rate_pct}%\n- Ad Spend: $${marketing.ad_spend?.toLocaleString() || 0}\n- Cost Per Click: $${marketing.cpc}\n- Click-Through Rate: ${marketing.ctr_pct}%\n- Cost Per Session: $${marketing.cost_per_session}\n\n### Sales Pipeline\n- Pipeline Value: $${sales.pipeline_value?.toLocaleString() || 0}\n- Active Opportunities: ${sales.active_opportunities || 0}\n- Average Deal Size: $${sales.avg_deal_size?.toLocaleString() || 0}\n- Win Rate: ${sales.win_rate_pct}%\n- Deals Won This Period: ${sales.won_deals || 0}\n- Deals Lost This Period: ${sales.lost_deals || 0}\n`;\n\nreturn {\n kpi_summary: kpiSummary,\n revenue_data: revenue,\n marketing_data: marketing,\n sales_data: sales,\n report_period: $('Initialize Report').item.json.report_type\n};"
},
"id": "format-for-ai",
"name": "Format KPIs for AI",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1350,
450
]
},
{
"parameters": {
"url": "https://api.anthropic.com/v1/messages",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "anthropic-version",
"value": "2023-06-01"
},
{
"name": "content-type",
"value": "application/json"
}
]
},
"sendBody": true,
"contentType": "json",
"body": "={\n \"model\": \"claude-3-5-sonnet-20241022\",\n \"max_tokens\": 2048,\n \"messages\": [\n {\n \"role\": \"user\",\n \"content\": \"You are a business analyst creating an executive summary. Analyze these weekly KPIs and provide:\\n\\n1. Key Highlights (3-4 bullet points of what's working well)\\n2. Areas of Concern (2-3 items that need attention)\\n3. Strategic Recommendations (3-4 actionable next steps)\\n4. Week-over-Week Trends (what changed and why it matters)\\n\\nBe concise, data-driven, and focus on insights that drive decisions. Use a professional but conversational tone.\\n\\n{{ $json.kpi_summary }}\"\n }\n ]\n}",
"options": {}
},
"id": "ai-analysis",
"name": "AI Analysis (Claude)",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1570,
450
]
},
{
"parameters": {
"jsCode": "// Parse AI response and create formatted report\nconst aiResponse = $input.item.json;\nconst kpiData = $('Format KPIs for AI').item.json;\nconst reportMeta = $('Initialize Report').item.json;\n\nconst aiInsights = aiResponse.content?.[0]?.text || 'AI analysis unavailable';\n\nconst htmlReport = `\n<!DOCTYPE html>\n<html>\n<head>\n <style>\n body { font-family: Arial, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; }\n h1 { color: #2c3e50; border-bottom: 3px solid #3498db; padding-bottom: 10px; }\n h2 { color: #34495e; margin-top: 30px; }\n .kpi-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 15px; margin: 20px 0; }\n .kpi-card { background: #f8f9fa; padding: 15px; border-radius: 8px; border-left: 4px solid #3498db; }\n .kpi-value { font-size: 24px; font-weight: bold; color: #2c3e50; }\n .kpi-label { font-size: 12px; color: #7f8c8d; text-transform: uppercase; }\n .ai-section { background: #e8f4f8; padding: 20px; border-radius: 8px; margin: 20px 0; }\n .positive { color: #27ae60; }\n .negative { color: #e74c3c; }\n .footer { margin-top: 40px; padding-top: 20px; border-top: 1px solid #ddd; color: #7f8c8d; font-size: 12px; }\n </style>\n</head>\n<body>\n <h1>\ud83d\udcca Executive Weekly Report</h1>\n <p><strong>Period:</strong> ${new Date(reportMeta.period_start).toLocaleDateString()} - ${new Date(reportMeta.period_end).toLocaleDateString()}</p>\n <p><strong>Generated:</strong> ${new Date(reportMeta.report_date).toLocaleString()}</p>\n \n <h2>\ud83d\udcb0 Revenue Overview</h2>\n <div class=\"kpi-grid\">\n <div class=\"kpi-card\">\n <div class=\"kpi-label\">Total Revenue</div>\n <div class=\"kpi-value\">$${kpiData.revenue_data.total_revenue?.toLocaleString() || 0}</div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-label\">Growth</div>\n <div class=\"kpi-value ${kpiData.revenue_data.revenue_growth_pct >= 0 ? 'positive' : 'negative'}\">\n ${kpiData.revenue_data.revenue_growth_pct >= 0 ? '+' : ''}${kpiData.revenue_data.revenue_growth_pct}%\n </div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-label\">Avg Order Value</div>\n <div class=\"kpi-value\">$${kpiData.revenue_data.avg_order_value || 0}</div>\n </div>\n </div>\n \n <h2>\ud83d\udcc8 Marketing Performance</h2>\n <div class=\"kpi-grid\">\n <div class=\"kpi-card\">\n <div class=\"kpi-label\">Sessions</div>\n <div class=\"kpi-value\">${kpiData.marketing_data.sessions?.toLocaleString() || 0}</div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-label\">Ad Spend</div>\n <div class=\"kpi-value\">$${kpiData.marketing_data.ad_spend?.toLocaleString() || 0}</div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-label\">Cost Per Session</div>\n <div class=\"kpi-value\">$${kpiData.marketing_data.cost_per_session || 0}</div>\n </div>\n </div>\n \n <h2>\ud83e\udd1d Sales Pipeline</h2>\n <div class=\"kpi-grid\">\n <div class=\"kpi-card\">\n <div class=\"kpi-label\">Pipeline Value</div>\n <div class=\"kpi-value\">$${kpiData.sales_data.pipeline_value?.toLocaleString() || 0}</div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-label\">Win Rate</div>\n <div class=\"kpi-value\">${kpiData.sales_data.win_rate_pct}%</div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-label\">Active Opps</div>\n <div class=\"kpi-value\">${kpiData.sales_data.active_opportunities || 0}</div>\n </div>\n </div>\n \n <div class=\"ai-section\">\n <h2>\ud83e\udd16 AI-Generated Insights</h2>\n <div style=\"white-space: pre-wrap;\">${aiInsights}</div>\n </div>\n \n <div class=\"footer\">\n <p>Report ID: ${reportMeta.report_id} | Generated by: ${reportMeta.generated_by}</p>\n <p>This report was automatically generated and analyzed by AI. For questions, contact your operations team.</p>\n </div>\n</body>\n</html>\n`;\n\nreturn {\n report_html: htmlReport,\n report_subject: `\ud83d\udcca Weekly Executive Report - ${new Date(reportMeta.period_end).toLocaleDateString()}`,\n report_summary: aiInsights,\n report_id: reportMeta.report_id\n};"
},
"id": "generate-report",
"name": "Generate HTML Report",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1790,
450
]
},
{
"parameters": {
"fromEmail": "reports@company.com",
"toEmail": "leadership@company.com",
"subject": "={{ $json.report_subject }}",
"emailFormat": "html",
"html": "={{ $json.report_html }}",
"options": {
"senderName": "Automated Reports"
}
},
"id": "send-email",
"name": "Send Email Report",
"type": "n8n-nodes-base.sendGrid",
"typeVersion": 1,
"position": [
2010,
350
]
},
{
"parameters": {
"select": "channel",
"channelId": {
"__rl": true,
"mode": "list",
"value": ""
},
"text": "=\ud83d\udcca **Weekly Executive Report**\n\n*Period:* {{ new Date($('Initialize Report').item.json.period_end).toLocaleDateString() }}\n\n{{ $('Generate HTML Report').item.json.report_summary.substring(0, 2000) }}\n\n_Full detailed report sent via email._",
"otherOptions": {}
},
"id": "send-slack",
"name": "Post to Slack",
"type": "n8n-nodes-base.slack",
"typeVersion": 2.2,
"position": [
2010,
550
]
},
{
"parameters": {
"operation": "appendOrUpdate",
"documentId": {
"__rl": true,
"mode": "list",
"value": ""
},
"sheetName": {
"__rl": true,
"mode": "list",
"value": ""
},
"columns": {
"mappingMode": "defineBelow",
"value": {
"Report Date": "={{ $('Initialize Report').item.json.report_date }}",
"Total Revenue": "={{ $('Format KPIs for AI').item.json.revenue_data.total_revenue }}",
"Revenue Growth %": "={{ $('Format KPIs for AI').item.json.revenue_data.revenue_growth_pct }}",
"Sessions": "={{ $('Format KPIs for AI').item.json.marketing_data.sessions }}",
"Ad Spend": "={{ $('Format KPIs for AI').item.json.marketing_data.ad_spend }}",
"Pipeline Value": "={{ $('Format KPIs for AI').item.json.sales_data.pipeline_value }}",
"Win Rate %": "={{ $('Format KPIs for AI').item.json.sales_data.win_rate_pct }}"
}
},
"options": {}
},
"id": "log-to-sheets",
"name": "Log to Historical Tracking Sheet",
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4.4,
"position": [
2010,
750
]
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict"
},
"conditions": [
{
"id": "anomaly-check",
"leftValue": "={{ $('Format KPIs for AI').item.json.revenue_data.revenue_growth_pct }}",
"rightValue": -10,
"operator": {
"type": "number",
"operation": "lt"
}
}
],
"combinator": "or"
},
"options": {}
},
"id": "check-anomalies",
"name": "Check for Anomalies",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
1570,
650
]
},
{
"parameters": {
"fromEmail": "alerts@company.com",
"toEmail": "leadership@company.com",
"subject": "\u26a0\ufe0f ALERT: Significant Revenue Drop Detected",
"text": "=\ud83d\udea8 **Anomaly Detected in Weekly Report**\n\nRevenue Growth: {{ $('Format KPIs for AI').item.json.revenue_data.revenue_growth_pct }}%\n\nThis represents a significant deviation from normal patterns. Immediate review recommended.\n\nFull report: {{ $('Generate HTML Report').item.json.report_id }}",
"options": {
"senderName": "Automated Alerts"
}
},
"id": "send-alert",
"name": "Send Alert Email",
"type": "n8n-nodes-base.sendGrid",
"typeVersion": 1,
"position": [
1790,
750
]
}
],
"connections": {
"Weekly Monday 8AM": {
"main": [
[
{
"node": "Initialize Report",
"type": "main",
"index": 0
}
]
]
},
"Initialize Report": {
"main": [
[
{
"node": "Get Revenue Data (Sheets)",
"type": "main",
"index": 0
},
{
"node": "Get Stripe Payments",
"type": "main",
"index": 0
},
{
"node": "Get Google Analytics",
"type": "main",
"index": 0
},
{
"node": "Get CRM Pipeline (HubSpot)",
"type": "main",
"index": 0
},
{
"node": "Get Ad Spend (Meta)",
"type": "main",
"index": 0
},
{
"node": "Get Financials (QuickBooks)",
"type": "main",
"index": 0
},
{
"node": "Get E-commerce Orders (Shopify)",
"type": "main",
"index": 0
}
]
]
},
"Get Revenue Data (Sheets)": {
"main": [
[
{
"node": "Calculate Revenue KPIs",
"type": "main",
"index": 0
}
]
]
},
"Get Stripe Payments": {
"main": [
[
{
"node": "Calculate Revenue KPIs",
"type": "main",
"index": 0
}
]
]
},
"Get E-commerce Orders (Shopify)": {
"main": [
[
{
"node": "Calculate Revenue KPIs",
"type": "main",
"index": 0
}
]
]
},
"Get Google Analytics": {
"main": [
[
{
"node": "Calculate Marketing KPIs",
"type": "main",
"index": 0
}
]
]
},
"Get Ad Spend (Meta)": {
"main": [
[
{
"node": "Calculate Marketing KPIs",
"type": "main",
"index": 0
}
]
]
},
"Get CRM Pipeline (HubSpot)": {
"main": [
[
{
"node": "Calculate Sales Pipeline KPIs",
"type": "main",
"index": 0
}
]
]
},
"Calculate Revenue KPIs": {
"main": [
[
{
"node": "Merge All KPIs",
"type": "main",
"index": 0
}
]
]
},
"Calculate Marketing KPIs": {
"main": [
[
{
"node": "Merge All KPIs",
"type": "main",
"index": 1
}
]
]
},
"Calculate Sales Pipeline KPIs": {
"main": [
[
{
"node": "Merge All KPIs",
"type": "main",
"index": 2
}
]
]
},
"Merge All KPIs": {
"main": [
[
{
"node": "Format KPIs for AI",
"type": "main",
"index": 0
}
]
]
},
"Format KPIs for AI": {
"main": [
[
{
"node": "AI Analysis (Claude)",
"type": "main",
"index": 0
},
{
"node": "Check for Anomalies",
"type": "main",
"index": 0
}
]
]
},
"AI Analysis (Claude)": {
"main": [
[
{
"node": "Generate HTML Report",
"type": "main",
"index": 0
}
]
]
},
"Generate HTML Report": {
"main": [
[
{
"node": "Send Email Report",
"type": "main",
"index": 0
},
{
"node": "Post to Slack",
"type": "main",
"index": 0
},
{
"node": "Log to Historical Tracking Sheet",
"type": "main",
"index": 0
}
]
]
},
"Check for Anomalies": {
"main": [
[
{
"node": "Send Alert Email",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1"
},
"staticData": null,
"tags": [],
"triggerCount": 1,
"versionId": null
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Executive KPI Dashboard - Automated Weekly Report. Uses googleSheets, httpRequest, sendGrid, slack. Scheduled trigger; 21 nodes.
Source: https://gist.github.com/gridrelay-max/6a0a23406c33633ed880b0a297905424 — 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.
E-commerce store owners, product managers, marketplace sellers, and pricing analysts who want to automatically track competitor pricing and get actionable alerts when their products are overpriced or
AI Document Processor - Intelligent Data Extraction. Uses httpRequest, readPDF, googleSheets, slack. Webhook trigger; 20 nodes.
This template is ideal for developers, agencies, hosting providers, and website owners who need real-time alerts when a website goes down. It helps teams react quickly to downtime by sending multi-cha
This workflow runs daily to check SSL certificate expiry for domains listed in Google Sheets, using ssl-checker.io to fetch certificate details, then creating Jira issues and sending Slack and Gmail a
Schedule Slack. Uses scheduleTrigger, googleSheets, slack, gmail. Scheduled trigger; 15 nodes.