This workflow corresponds to n8n.io template #4893 — we link there as the canonical source.
This workflow follows the Agent → Gmail 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": "Ucu10DYuMwYdLLVk",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "Scheduled Daily Email Pulse",
"tags": [],
"nodes": [
{
"id": "908a85db-7b15-4ece-8dab-19398e0c1871",
"name": "Schedule Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-80,
-80
],
"parameters": {
"rule": {
"interval": [
{
"triggerAtHour": 18
}
]
}
},
"typeVersion": 1.2
},
{
"id": "8cadc5e6-193e-42e9-b2fc-54a2025191c2",
"name": "Gmail",
"type": "n8n-nodes-base.gmail",
"position": [
360,
-80
],
"parameters": {
"simple": false,
"filters": {
"receivedAfter": "={{ $json.today}}",
"receivedBefore": "={{ $json.tomorrow }}"
},
"options": {},
"operation": "getAll"
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.1,
"alwaysOutputData": true
},
{
"id": "62ab4e36-b42f-4aff-8ec5-4456f4827ca3",
"name": "Date Transformer",
"type": "n8n-nodes-base.code",
"position": [
140,
-80
],
"parameters": {
"jsCode": "const now = new Date();\nconst today = new Date(now.getFullYear(), now.getMonth(), now.getDate());\nconst tomorrow = new Date(today);\ntomorrow.setDate(today.getDate() + 1);\n\nconst isoDate = (d) => d.toISOString().split('.')[0] + 'Z';\n\nreturn [\n {\n json: {\n today: isoDate(today),\n tomorrow: isoDate(tomorrow),\n },\n },\n];\n"
},
"typeVersion": 2
},
{
"id": "c25a964f-6d41-4c97-b90f-f5ce15cadaa7",
"name": "AI Agent",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
1020,
160
],
"parameters": {
"text": "You are an AI Chief of Staff for a small business owner. Your job is to review a day\u2019s worth of emails, texts, and calls and produce a concise, structured summary that helps them stay focused and effective.\n\nYou must only surface tasks, people, and opportunities that appear in the message content. Do not invent next steps, leads, or strategy notes.\n\nIf a section has no relevant content, leave it out entirely. It\u2019s better to report nothing than to guess.",
"options": {
"systemMessage": "=Below is a transcript of today\u2019s messages \u2014 including email, text, and call summaries.\n\nAnalyze the content and generate a markdown-formatted **Daily Business Pulse**, using only what appears in the messages. Do not assume, extrapolate, or fabricate any details.\n\nMessages:\n{{ $json.combinedText }}\n\nUse the structure below. Omit any section that has no relevant content.\n\n---\n\n\ud83d\udc4b **Here\u2019s what matters from your day**\n\n---\n\n\ud83d\udcdd **Open Loops / Pending Follow-Ups** \n_List any conversations that require a response or action._\n\n---\n\n\ud83d\ude80 **Next Steps You've Committed To** \n_List anything the user said they would do._\n\n---\n\n\ud83e\uddf2 **Leads or Conversations Worth Following Up On** \n_Only include if the person expressed interest or asked for help._\n\n---\n\n\ud83d\uded1 **Conversations That Aren\u2019t Leading Anywhere** \n_Include if there are back-and-forths with no progress, spam, or promotional threads._\n\n---\n\n\ud83e\udde0 **Strategy Notes** \n_Only add notes if there are clear, recurring themes or opportunities based on the content._\n\n---\n\n\u2705 **Top 3 Tasks for Tomorrow** \n_If tasks were mentioned and clearly matter, list the top 3. Otherwise, leave this out._"
},
"promptType": "define"
},
"typeVersion": 2
},
{
"id": "fe2552ce-48be-44bd-b975-cde379b46b51",
"name": "OpenAI Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
1020,
360
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "gpt-4o-mini"
},
"options": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "d2410164-fde8-46f1-8df1-6cbf3874d397",
"name": "Aggregate",
"type": "n8n-nodes-base.aggregate",
"position": [
580,
60
],
"parameters": {
"options": {},
"fieldsToAggregate": {
"fieldToAggregate": [
{
"fieldToAggregate": "headers.from"
},
{
"fieldToAggregate": "headers.subject"
},
{
"fieldToAggregate": "text"
}
]
}
},
"typeVersion": 1
},
{
"id": "9c3c28f5-35d5-4164-a694-8a9bc26354d5",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-120,
-120
],
"parameters": {
"color": 4,
"width": 620,
"height": 200,
"content": ""
},
"typeVersion": 1
},
{
"id": "476d2f5a-c0da-4683-89a2-9cbe9d93c638",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
520,
40
],
"parameters": {
"color": 6,
"width": 420,
"content": ""
},
"typeVersion": 1
},
{
"id": "f9301bfa-2cd7-4eaf-9798-729604a6b49a",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
980,
140
],
"parameters": {
"width": 540,
"content": ""
},
"typeVersion": 1
},
{
"id": "5cdda71c-ba41-41ba-aae1-66d39caf75c9",
"name": "Email Cleanup",
"type": "n8n-nodes-base.code",
"position": [
780,
60
],
"parameters": {
"jsCode": "const cleanMessages = items.map(item => {\n const from = item.json.header?.from || \"Unknown sender\";\n const subject = item.json.header?.subject || \"No subject\";\n const rawBody = item.json.text || \"\"; // fall back to empty string\n const body = String(rawBody); // ensure it's a string\n\n const cleaned = body\n .replace(/<\\/?[^>]+(>|$)/g, \"\") // Remove HTML\n .replace(/(Unsubscribe|View in browser)/gi, \"\") // Strip only promo triggers\n .replace(/\\n{3,}/g, \"\\n\\n\") // Collapse excess breaks\n .trim(); // Clean up\n\n return `\ud83d\udce9 **From:** ${from}\\n**Subject:** ${subject}\\n**Preview:**\\n${cleaned}\\n\\n---\\n`;\n});\n\nreturn [{\n json: {\n combinedText: cleanMessages.join('\\n')\n }\n}];"
},
"typeVersion": 2
},
{
"id": "0807cef5-876f-433d-a94a-2db7f86d844d",
"name": "Format HTML",
"type": "n8n-nodes-base.code",
"position": [
1380,
160
],
"parameters": {
"jsCode": "const markdown = $input.all().map((item) => item.json.output);\nlet html = markdown.map((md) =>\n md\n .replace(/(\\*\\*|__)(.*?)\\1/g, \"<b>$2</b>\")\n .replace(/(\\*|_)(.*?)\\1/g, \"<i>$2</i>\")\n .replace(/~~(.*?)~~/g, \"<del>$1</del>\")\n .replace(/`([^`\\n]+)`/g, \"<code>$1</code>\")\n .replace(/!\\[([^\\]]+)\\]\\(([^\\)]+)\\)/g, '<img src=\"$2\" alt=\"$1\">')\n .replace(/\\[([^\\]]+)\\]\\(([^\\)]+)\\)/g, '<a href=\"$2\">$1</a>')\n .replace(/(\\r\\n|\\n|\\r)/gm, \"<br>\"),\n);\n\nreturn { html };\n"
},
"typeVersion": 2
},
{
"id": "bfc39659-9e36-4dde-9536-558d491f965c",
"name": "Send Message",
"type": "n8n-nodes-base.gmail",
"position": [
1580,
320
],
"parameters": {
"sendTo": "youremail@gmail.com",
"message": "={{ $json.html[0] }}",
"options": {},
"subject": "Here's Your Daily Pulse"
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
}
],
"active": true,
"settings": {
"executionOrder": "v1"
},
"versionId": "fa9af357-4a58-4540-94d4-7228678ea75b",
"connections": {
"Gmail": {
"main": [
[
{
"node": "Aggregate",
"type": "main",
"index": 0
}
]
]
},
"AI Agent": {
"main": [
[
{
"node": "Format HTML",
"type": "main",
"index": 0
}
]
]
},
"Aggregate": {
"main": [
[
{
"node": "Email Cleanup",
"type": "main",
"index": 0
}
]
]
},
"Format HTML": {
"main": [
[
{
"node": "Send Message",
"type": "main",
"index": 0
}
]
]
},
"Email Cleanup": {
"main": [
[
{
"node": "AI Agent",
"type": "main",
"index": 0
}
]
]
},
"Date Transformer": {
"main": [
[
{
"node": "Gmail",
"type": "main",
"index": 0
}
]
]
},
"Schedule Trigger": {
"main": [
[
{
"node": "Date Transformer",
"type": "main",
"index": 0
}
]
]
},
"OpenAI Chat Model": {
"ai_languageModel": [
[
{
"node": "AI Agent",
"type": "ai_languageModel",
"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.
gmailOAuth2openAiApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This agent summarizes a user's daily emails into a clean, actionable summary. It uses OpenAI to analyze content and sends a formatted "Daily Pulse" email at the end of each day.
Source: https://n8n.io/workflows/4893/ — 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.
This n8n automation workflow automates the creation, scripting, production, and posting of YouTube videos. It leverages AI (OpenAI), image generation (PIAPI), video rendering (Shotstack), and platform
Created by: Peyton Leveillee Last updated: October 2025
The Multi-Model Agency Content Engine is a high-performance editorial system designed for agencies. It solves the "blank page" problem by alternating between real-world social proof and strategic expe
This workflow automates the creation, rendering, approval, and posting of TikTok-style POV (Point of View) videos to Instagram, with cross-posting to Facebook and YouTube. It eliminates manual video p
SEO Blog Article Generation Workflow. Uses outputParserStructured, httpRequest, agent, lmChatOpenAi. Scheduled trigger; 56 nodes.