This workflow corresponds to n8n.io template #12018 — we link there as the canonical source.
This workflow follows the Google Calendar → Google Sheets 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": "d1r3wX8d9mCd5ewk",
"name": "Analyze productivity metrics and send AI reports to Slack",
"tags": [],
"nodes": [
{
"id": "9363e48d-fead-4841-b97d-b02164f19fa4",
"name": "Schedule Daily Execution",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
6064,
-336
],
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 8 * * 1-5"
}
]
}
},
"typeVersion": 1.2
},
{
"id": "47c2bc93-fd2b-4cae-aa2e-9d100caa0112",
"name": "Get Current Date",
"type": "n8n-nodes-base.dateTime",
"position": [
6368,
-336
],
"parameters": {
"date": "={{ $json.timestamp }}",
"format": "yyyy-MM-dd",
"options": {},
"operation": "formatDate",
"outputFieldName": "dateFormatted"
},
"typeVersion": 2
},
{
"id": "52012b69-f01f-4fa7-9583-fc176841601e",
"name": "Fetch Calendar Events",
"type": "n8n-nodes-base.googleCalendar",
"position": [
6656,
-336
],
"parameters": {
"options": {
"timeMax": "={{ $json.dateFormatted }}T23:59:59Z",
"timeMin": "={{ $json.dateFormatted }}T00:00:00Z"
},
"calendar": {
"__rl": true,
"mode": "list",
"value": "primary"
},
"operation": "getAll",
"returnAll": true
},
"typeVersion": 1
},
{
"id": "6f75190d-8789-44b5-be28-3ca0b88e92ef",
"name": "Fetch Todoist Tasks",
"type": "n8n-nodes-base.httpRequest",
"position": [
6960,
-336
],
"parameters": {
"url": "https://api.todoist.com/rest/v2/tasks",
"options": {},
"sendQuery": true,
"authentication": "predefinedCredentialType",
"queryParameters": {
"parameters": [
{
"name": "filter",
"value": "today | overdue"
}
]
},
"nodeCredentialType": "todoistApi"
},
"typeVersion": 4.2
},
{
"id": "41b6ff7c-49a3-41f9-85e2-c78f330134d5",
"name": "Fetch Slack Messages",
"type": "n8n-nodes-base.slack",
"position": [
7264,
-336
],
"parameters": {
"operation": "getAll"
},
"typeVersion": 2.1
},
{
"id": "b8e53d8a-fa16-42b0-8ab8-a00749f75899",
"name": "Aggregate Data",
"type": "n8n-nodes-base.code",
"position": [
7568,
-336
],
"parameters": {
"jsCode": "// Aggregate and format data from all sources\nconst dateInfo = items[0].json;\nconst calendarEvents = $input.item(1).json.items || [];\nconst tasks = $input.item(2).json || [];\nconst slackMessages = $input.item(3).json.messages || [];\n\n// Classify meetings by day\nconst meetingsToday = calendarEvents.filter(e => {\n const start = new Date(e.start.dateTime || e.start.date);\n return start.toDateString() === new Date(dateInfo.dateFormatted).toDateString();\n});\n\n// Categorize tasks by priority\nconst highPriorityTasks = tasks.filter(t => t.priority >= 3);\nconst normalTasks = tasks.filter(t => t.priority < 3);\n\n// Calculate Slack usage by hour\nconst slackByHour = {};\nslackMessages.forEach(msg => {\n const hour = new Date(msg.ts * 1000).getHours();\n slackByHour[hour] = (slackByHour[hour] || 0) + 1;\n});\n\nreturn {\n date: dateInfo.dateFormatted,\n weekday: new Date(dateInfo.dateFormatted).getDay(),\n meetingsToday: meetingsToday,\n meetingsTomorrow: [],\n tasks: {\n highPriority: highPriorityTasks,\n normal: normalTasks\n },\n slackUsage: {\n totalMessages: slackMessages.length,\n byHour: slackByHour\n }\n};"
},
"typeVersion": 2
},
{
"id": "7d70268d-d7f9-47d3-85b2-b450b9d5a19b",
"name": "AI Analysis - Productivity Insights",
"type": "n8n-nodes-base.openAi",
"position": [
7856,
-336
],
"parameters": {
"resource": "chat",
"operation": "message",
"requestOptions": {}
},
"typeVersion": 1
},
{
"id": "884dfba0-6d58-4126-9e26-e28877ebf1a0",
"name": "Log Daily Metrics",
"type": "n8n-nodes-base.googleSheets",
"position": [
8160,
-336
],
"parameters": {
"columns": {
"value": {
"date": "={{ $json.date }}",
"tasksCount": "={{ $json.tasks.highPriority.length + $json.tasks.normal.length }}",
"meetingHours": "={{ $json.meetingsToday.length * 0.5 }}",
"slackMessages": "={{ $json.slackUsage.totalMessages }}"
},
"mappingMode": "defineBelow"
},
"options": {},
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "Sheet1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": ""
}
},
"typeVersion": 4.4
},
{
"id": "8c1960fd-5a0e-4b03-9c9c-496156444012",
"name": "Generate Daily Summary",
"type": "n8n-nodes-base.openAi",
"position": [
8448,
-336
],
"parameters": {
"resource": "chat",
"operation": "message",
"requestOptions": {}
},
"typeVersion": 1
},
{
"id": "eb47be1a-85e9-4412-a631-a7c3d1a3076f",
"name": "Send Daily Summary to Slack",
"type": "n8n-nodes-base.slack",
"position": [
8736,
-336
],
"parameters": {
"text": "=\ud83d\udcca **Daily Productivity Summary** - {{ $node['Aggregate Data'].json.date }}\n\n{{ $json.choices[0].message.content }}",
"otherOptions": {}
},
"typeVersion": 2.1
},
{
"id": "537a65e8-b939-4ce0-9480-3d28a5c75972",
"name": "Check if Friday",
"type": "n8n-nodes-base.if",
"position": [
9040,
-336
],
"parameters": {
"options": {},
"conditions": {
"options": {
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "friday-check",
"operator": {
"type": "number",
"operation": "equals"
},
"leftValue": "={{ $json.weekday }}",
"rightValue": 5
}
]
}
},
"typeVersion": 2
},
{
"id": "107f8904-a0c8-46e3-bd3b-192670987538",
"name": "Fetch Last 7 Days Data",
"type": "n8n-nodes-base.googleSheets",
"position": [
9360,
-336
],
"parameters": {
"operation": "getAll",
"documentId": {
"__rl": true,
"mode": "list",
"value": ""
}
},
"typeVersion": 4.4
},
{
"id": "b843fbb8-af28-4ac4-8f04-fd8f8a57a68d",
"name": "Calculate Weekly Stats",
"type": "n8n-nodes-base.code",
"position": [
9664,
-336
],
"parameters": {
"jsCode": "// Calculate weekly aggregates\nconst weeklyData = items;\n\nconst totalMeetingHours = weeklyData.reduce((sum, d) => sum + parseFloat(d.json.meetingHours || 0), 0);\nconst avgMeetingHours = totalMeetingHours / weeklyData.length;\nconst totalSlackMessages = weeklyData.reduce((sum, d) => sum + (d.json.slackMessages || 0), 0);\nconst totalTasks = weeklyData.reduce((sum, d) => sum + (d.json.tasksCount || 0), 0);\n\nreturn {\n weekRange: `${weeklyData[0].json.date} - ${weeklyData[weeklyData.length-1].json.date}`,\n dailyMetrics: weeklyData.map(d => d.json),\n weeklySummary: {\n totalMeetingHours: totalMeetingHours.toFixed(1),\n avgMeetingHoursPerDay: avgMeetingHours.toFixed(1),\n totalTasks: totalTasks,\n totalSlackMessages: totalSlackMessages,\n avgSlackMessagesPerDay: (totalSlackMessages / weeklyData.length).toFixed(0)\n }\n};"
},
"typeVersion": 2
},
{
"id": "ce10bde8-1070-489e-b92d-a8cd7cc220fc",
"name": "Generate Weekly Report",
"type": "n8n-nodes-base.openAi",
"position": [
9968,
-336
],
"parameters": {
"resource": "chat",
"operation": "message",
"requestOptions": {}
},
"typeVersion": 1
},
{
"id": "7ae05ba9-f312-4457-b2b7-af6d2a7fb2c0",
"name": "Send Weekly Report to Slack",
"type": "n8n-nodes-base.slack",
"position": [
10256,
-336
],
"parameters": {
"text": "=\ud83d\udcc8 **Weekly Productivity Report** - {{ $node['Calculate Weekly Stats'].json.weekRange }}\n\n{{ $json.choices[0].message.content }}\n\n@channel",
"otherOptions": {}
},
"typeVersion": 2.1
},
{
"id": "118f11c4-8fd6-4a4d-a497-e35c00211255",
"name": "Main Description",
"type": "n8n-nodes-base.stickyNote",
"position": [
5136,
-1104
],
"parameters": {
"width": 500,
"height": 586,
"content": "## \ud83e\udd16 Productivity Analyst AI\nThis workflow acts as a productivity coach, tracking your work habits and using AI to provide daily and weekly insights.\n\n### \u2699\ufe0f How it works\n1. **Collects Data**: Fetches meetings (Google Calendar), tasks (Todoist), and chat activity (Slack).\n2. **AI Analysis**: Analyzes time usage to find focus blocks and overload risks.\n3. **Daily Report**: Sends a morning briefing to Slack with specific advice.\n4. **Weekly Review**: On Fridays, generates a comprehensive strategic review based on historical data.\n\n### \ud83d\udcdd Requirements\n- **Services**: Google Calendar, Todoist, Slack, Google Sheets\n- **AI**: OpenAI API Key (GPT-4 recommended)\n\n### \ud83d\udee0 Setup\n1. Configure credentials for all services in n8n.\n2. Set up a **Google Sheet** with columns: `date`, `meetingHours`, `tasksCount`, `slackMessages`.\n3. Update the **Sheet ID** in the \"Log Daily Metrics\" and \"Fetch Last 7 Days Data\" nodes.\n4. Activate the workflow."
},
"typeVersion": 1
},
{
"id": "dc0641c6-1a97-4b26-9ad2-f95007a62cb4",
"name": "Step 1",
"type": "n8n-nodes-base.stickyNote",
"position": [
6000,
-672
],
"parameters": {
"color": 7,
"width": 1448,
"height": 620,
"content": "## 1. Trigger & Data Collection\nRuns every weekday at 8 AM. \nFetches data from Calendar, Todoist, and Slack to build a productivity snapshot."
},
"typeVersion": 1
},
{
"id": "73421f38-e995-49f2-a9ac-91029025eaac",
"name": "Step 2",
"type": "n8n-nodes-base.stickyNote",
"position": [
7504,
-672
],
"parameters": {
"color": 7,
"width": 548,
"height": 620,
"content": "## 2. Aggregation & AI Analysis\nConsolidates data points and uses OpenAI to analyze patterns and generate actionable insights."
},
"typeVersion": 1
},
{
"id": "c2d8c459-ba65-42d6-94be-2c4b82ff8953",
"name": "Step 3",
"type": "n8n-nodes-base.stickyNote",
"position": [
8096,
-672
],
"parameters": {
"color": 7,
"width": 844,
"height": 620,
"content": "## 3. Daily Logging & Reporting\nSaves metrics to Google Sheets for historical tracking and sends today's summary to Slack."
},
"typeVersion": 1
},
{
"id": "d9967c1c-44e0-4e4a-88c2-851207d0dec0",
"name": "Step 4",
"type": "n8n-nodes-base.stickyNote",
"position": [
8976,
-672
],
"parameters": {
"color": 7,
"width": 1484,
"height": 556,
"content": "## 4. Weekly Strategic Review\nChecks if it's Friday. If so, fetches the last 7 days of data to generate a broader weekly report."
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"callerPolicy": "workflowsFromSameOwner",
"availableInMCP": false,
"executionOrder": "v1"
},
"versionId": "fc9dac7c-ef03-44ae-9e5f-263d8344a916",
"connections": {
"Aggregate Data": {
"main": [
[
{
"node": "AI Analysis - Productivity Insights",
"type": "main",
"index": 0
}
]
]
},
"Check if Friday": {
"main": [
[
{
"node": "Fetch Last 7 Days Data",
"type": "main",
"index": 0
}
]
]
},
"Get Current Date": {
"main": [
[
{
"node": "Fetch Calendar Events",
"type": "main",
"index": 0
}
]
]
},
"Log Daily Metrics": {
"main": [
[
{
"node": "Generate Daily Summary",
"type": "main",
"index": 0
}
]
]
},
"Fetch Todoist Tasks": {
"main": [
[
{
"node": "Fetch Slack Messages",
"type": "main",
"index": 0
}
]
]
},
"Fetch Slack Messages": {
"main": [
[
{
"node": "Aggregate Data",
"type": "main",
"index": 0
}
]
]
},
"Fetch Calendar Events": {
"main": [
[
{
"node": "Fetch Todoist Tasks",
"type": "main",
"index": 0
}
]
]
},
"Calculate Weekly Stats": {
"main": [
[
{
"node": "Generate Weekly Report",
"type": "main",
"index": 0
}
]
]
},
"Fetch Last 7 Days Data": {
"main": [
[
{
"node": "Calculate Weekly Stats",
"type": "main",
"index": 0
}
]
]
},
"Generate Daily Summary": {
"main": [
[
{
"node": "Send Daily Summary to Slack",
"type": "main",
"index": 0
}
]
]
},
"Generate Weekly Report": {
"main": [
[
{
"node": "Send Weekly Report to Slack",
"type": "main",
"index": 0
}
]
]
},
"Schedule Daily Execution": {
"main": [
[
{
"node": "Get Current Date",
"type": "main",
"index": 0
}
]
]
},
"Send Daily Summary to Slack": {
"main": [
[
{
"node": "Check if Friday",
"type": "main",
"index": 0
}
]
]
},
"AI Analysis - Productivity Insights": {
"main": [
[
{
"node": "Log Daily Metrics",
"type": "main",
"index": 0
}
]
]
}
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow acts as an automated personal productivity coach. It aggregates data from your daily tools (Google Calendar, Todoist, and Slack) to provide AI-driven insights into your work habits. It runs daily to log metrics to Google Sheets and sends a summary to Slack.…
Source: https://n8n.io/workflows/12018/ — 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.
Stop wasting billable hours on manual time-tracking. AutoTimesheet Pro uses AI to collect emails, meetings, and GitHub work, then writes a clean timesheet straight into Google Sheets. Perfect for deve
Imagine a dedicated financial expert tirelessly working behind the scenes, sifting through every transaction, every investment move, and every accounting entry. That's exactly what this automated syst
Automate your social media content pipeline from idea to scheduled post. This workflow reads content ideas from a Google Sheet, uses OpenAI to generate platform-optimized posts for LinkedIn, X (Twitte
Automate your landscaping business’s lead follow-up and booking with this AI-powered GoHighLevel workflow. Designed by Hyrum Hurst, AI Automation Engineer at QuarterSmart, this template takes every ne
Who is this for This workflow is perfect for busy professionals, consultants, and anyone who frequently travels between meetings. If you want to make the most of your free time between appointments an