This workflow corresponds to n8n.io template #6133 — we link there as the canonical source.
This workflow follows the Gmail → Google Calendar 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": "oRUhVLfKvrxvUSky",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "Daily Briefing- Tasks & Events",
"tags": [],
"nodes": [
{
"id": "9f7abaa2-1d99-488d-a2f6-ce63af3dd509",
"name": "Message a model",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
400,
-20
],
"parameters": {
"modelId": {
"__rl": true,
"mode": "list",
"value": "chatgpt-4o-latest",
"cachedResultName": "CHATGPT-4O-LATEST"
},
"options": {},
"messages": {
"values": [
{
"content": "=Here's my plan for today:\n\n\ud83d\uddc2\ufe0f **Tasks**\n{{ $json.formattedTasks }}\n\n\ud83d\udcc5 **Calendar**\n{{ $json.formattedEvents }}\n\n---\n\n\u2705 Structure the reply in this exact markdown format:\n\n**Daily Summary** \n[one-sentence summary of the day]\n\n\\n\\n\n\n\ud83c\udfaf **Top Priorities** \n1. \u2705 [Task 1] \u2013 \u23f0 [Time] \n2. \u2705 [Task 2] \u2013 \u23f0 [Time] \n...\n\n\\n\\n\n\n\ud83d\udca1 **Focus Mantra** \n\"[motivational quote]\"\n\n\\n\\n\n\nAdd **line breaks** between each section and each task, so it's email-friendly and easy to scan.\nAvoid long paragraphs. Keep it clean and structured."
}
]
}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.8
},
{
"id": "3bccfb3e-2e86-4c0b-8bce-891b6ad3b969",
"name": "Send a message",
"type": "n8n-nodes-base.gmail",
"position": [
980,
-20
],
"parameters": {
"sendTo": "emailPlaceholder",
"message": "={{ $json.htmlBody }}",
"options": {},
"subject": "Morning Briefings"
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "e21eed99-cc0b-4224-b7f0-e85f62dd6c78",
"name": "Get many tasks",
"type": "n8n-nodes-base.todoist",
"position": [
-320,
80
],
"parameters": {
"filters": {
"projectId": "2357038842"
},
"operation": "getAll",
"returnAll": true
},
"credentials": {
"todoistApi": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "009b1143-306d-4bad-bea7-47df8771b499",
"name": "Get many events",
"type": "n8n-nodes-base.googleCalendar",
"position": [
-320,
-120
],
"parameters": {
"options": {},
"calendar": {
"__rl": true,
"mode": "list",
"value": "emailPlaceholder",
"cachedResultName": "emailPlaceholder"
},
"operation": "getAll"
},
"credentials": {
"googleCalendarOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1.3,
"alwaysOutputData": true
},
{
"id": "27d34f96-ca61-44bf-8989-bbca2bee0069",
"name": "Code",
"type": "n8n-nodes-base.code",
"position": [
200,
-20
],
"parameters": {
"jsCode": "const calendarEvents = [];\nconst todoistTasks = [];\n\nfor (const item of items) {\n if (item.json?.start?.dateTime) {\n calendarEvents.push(item.json);\n } else if (item.json?.content) {\n todoistTasks.push(item.json);\n }\n}\n\nconst formattedEvents = calendarEvents.map((event, i) => {\n const time = new Date(event.start.dateTime).toLocaleTimeString('en-IN', { hour: '2-digit', minute: '2-digit' });\n return `${i + 1}. ${event.summary} at ${time}`;\n}).join('\\n');\n\nconst formattedTasks = todoistTasks.map((task, i) => {\n const time = task.due?.datetime\n ? new Date(task.due.datetime).toLocaleTimeString('en-IN', { hour: '2-digit', minute: '2-digit' })\n : 'No time set';\n return `${i + 1}. ${task.content} (Due at ${time})`;\n}).join('\\n');\n\nreturn [\n {\n json: {\n formattedEvents: formattedEvents || 'No calendar events today.',\n formattedTasks: formattedTasks || 'No tasks today.'\n }\n }\n];"
},
"typeVersion": 2
},
{
"id": "987c7654-7edc-4aea-b2be-f0ce846cf6fd",
"name": "Merge",
"type": "n8n-nodes-base.merge",
"position": [
-20,
-20
],
"parameters": {},
"typeVersion": 3.2
},
{
"id": "2b69ae00-18c0-4778-9702-23a18e300573",
"name": "Convert OpenAI Text to HTML",
"type": "n8n-nodes-base.code",
"position": [
760,
-20
],
"parameters": {
"jsCode": "const raw = $json.message?.content || 'No message';\n\n// Convert markdown-style bold to <strong>\nlet html = raw\n .replace(/\\*\\*(.*?)\\*\\*/g, '<strong>$1</strong>')\n\n// Convert newlines and spacing\n .replace(/\\n{2,}/g, '<br><br>') // double newlines \u2192 double <br>\n .replace(/\\n/g, '<br>') // single newline fallback\n\n// Optional: emoji replacement (can leave as-is if you like)\n .replace(/\u2705/g, '\u2705')\n .replace(/\ud83c\udfaf/g, '\ud83c\udfaf')\n .replace(/\ud83d\udca1/g, '\ud83d\udca1')\n .replace(/\ud83d\udcc5/g, '\ud83d\udcc5')\n .replace(/\ud83d\uddc2\ufe0f/g, '\ud83d\uddc2\ufe0f');\n\nreturn [\n {\n json: {\n htmlBody: `<div style=\"font-family: Arial, sans-serif; font-size: 14px; line-height: 1.6;\">${html}</div>`\n }\n }\n];"
},
"typeVersion": 2
},
{
"id": "2651477d-bad3-4fc7-9666-4a11a87bc4f8",
"name": "Schedule Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-640,
-20
],
"parameters": {
"rule": {
"interval": [
{
"triggerAtHour": 6
}
]
}
},
"typeVersion": 1.2
},
{
"id": "d032cb5e-11bb-445c-ab31-b357ba8c3044",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1100,
-180
],
"parameters": {
"color": 5,
"width": 380,
"height": 440,
"content": "## \ud83d\udccc **Daily Briefing Automation**\n\nThis workflow fetches today's calendar events and tasks from Google Calendar and Todoist, formats them using GPT-4o, converts the summary to HTML, and emails it automatically at 6:00 AM daily.\n\nUse this to start your day focused and aligned with your top priorities.\n\n**Highlights:**\n- Auto-scheduled morning brief\n- Task & calendar merging\n- Natural language summary by GPT\n- HTML email output (readable & styled)\n"
},
"typeVersion": 1
},
{
"id": "20aa46f5-e9e9-4259-8658-a369938e7d04",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-680,
-180
],
"parameters": {
"color": 2,
"width": 180,
"height": 440,
"content": "\u23f0 Triggers the workflow at 6:00 AM daily.\nUse this to automate your morning routine prep.\n"
},
"typeVersion": 1
},
{
"id": "00f26917-3006-40a8-b798-63d4d741f360",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
-360,
-260
],
"parameters": {
"color": 6,
"width": 180,
"height": 180,
"content": "\ud83d\udcc5 Fetches all Google Calendar events for the day.\nFilters are configured using your linked Gmail calendar.\n"
},
"typeVersion": 1
},
{
"id": "f1b0537b-06f8-4840-9a18-b748da7d2076",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
-360,
160
],
"parameters": {
"color": 6,
"width": 180,
"height": 220,
"content": "\n\n\n\n\n\n\n\ud83d\udcdd Fetches all Todoist tasks under a specified project.\nMake sure `projectId` is up-to-date.\n"
},
"typeVersion": 1
},
{
"id": "5e0e9272-1834-4108-ad04-be81be4d32c6",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
-60,
200
],
"parameters": {
"color": 7,
"width": 180,
"height": 140,
"content": "\ud83d\udd00 Merges calendar events and tasks.\nRequired to feed both datasets into a single Code node.\n"
},
"typeVersion": 1
},
{
"id": "e6c7821c-1c24-4dc3-aef9-387efc2f9ec5",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
160,
200
],
"parameters": {
"color": 7,
"width": 180,
"height": 140,
"content": "\ud83e\udde0 Separates & formats calendar events and tasks.\nReturns structured strings for GPT to summarize.\n"
},
"typeVersion": 1
},
{
"id": "c2de93aa-9e1c-4dd4-984f-72de1f4323bd",
"name": "Sticky Note6",
"type": "n8n-nodes-base.stickyNote",
"position": [
420,
200
],
"parameters": {
"color": 7,
"width": 180,
"height": 140,
"content": "\ud83e\udd16 Sends task and calendar summary to GPT-4o.\nPrompt includes layout guidance and markdown formatting.\n"
},
"typeVersion": 1
},
{
"id": "e0b8b41b-75bd-4455-b94e-919fb3be5d9a",
"name": "Sticky Note7",
"type": "n8n-nodes-base.stickyNote",
"position": [
720,
200
],
"parameters": {
"color": 7,
"width": 180,
"height": 140,
"content": "\ud83e\uddf1 Converts markdown-style GPT output into clean HTML.\nEnsures line breaks, bold headings, and emojis are email-friendly.\n"
},
"typeVersion": 1
},
{
"id": "4b6ae3f4-8490-4097-87d7-5b1bfbcf90ad",
"name": "Sticky Note8",
"type": "n8n-nodes-base.stickyNote",
"position": [
960,
200
],
"parameters": {
"color": 7,
"width": 180,
"height": 140,
"content": "\ud83d\udce7 Sends the final HTML email to your inbox.\nEmail subject: \u201cMorning Briefings\u201d\n"
},
"typeVersion": 1
},
{
"id": "8eb46a16-e528-488e-be02-fdd00d1220c0",
"name": "Sticky Note9",
"type": "n8n-nodes-base.stickyNote",
"position": [
-80,
-80
],
"parameters": {
"color": 7,
"width": 1280,
"height": 440,
"content": ""
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "8eb56c93-5df7-4748-b658-c69a8ba1123e",
"connections": {
"Code": {
"main": [
[
{
"node": "Message a model",
"type": "main",
"index": 0
}
]
]
},
"Merge": {
"main": [
[
{
"node": "Code",
"type": "main",
"index": 0
}
]
]
},
"Get many tasks": {
"main": [
[
{
"node": "Merge",
"type": "main",
"index": 1
}
]
]
},
"Get many events": {
"main": [
[
{
"node": "Merge",
"type": "main",
"index": 0
}
]
]
},
"Message a model": {
"main": [
[
{
"node": "Convert OpenAI Text to HTML",
"type": "main",
"index": 0
}
]
]
},
"Schedule Trigger": {
"main": [
[
{
"node": "Get many events",
"type": "main",
"index": 0
},
{
"node": "Get many tasks",
"type": "main",
"index": 0
}
]
]
},
"Convert OpenAI Text to HTML": {
"main": [
[
{
"node": "Send a message",
"type": "main",
"index": 0
}
]
]
}
}
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
gmailOAuth2googleCalendarOAuth2ApiopenAiApitodoistApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Put your productivity on autopilot with this workflow.
Source: https://n8n.io/workflows/6133/ — 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
📧 이메일 자동 분류 시스템 (Sender Filter). Uses gmail, openAi, googleSheets, googleCalendar. Scheduled trigger; 30 nodes.
Business owners and service providers who want to reduce no-show rates for appointments booked via Google Calendar.
This workflow is your personal CEO Brain. Every Saturday night, it automatically collects the past week’s activity across: 📩 Gmail: filters out spam, promos, receipts, etc. 📅 Google Calendar: grabs pa
This automated n8n workflow generates social media briefs for sales meetings by integrating with Google Calendar, enriching attendee data, and leveraging AI to summarize social media activity. The sys