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
Set Workflow. Uses googleCalendar, httpRequest, clearbit, gmail. Scheduled trigger; 21 nodes.