This workflow corresponds to n8n.io template #17099 — 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": "vsFES8AsUaW8Itkh",
"name": "Template 9 - Daily Digest to Audio Briefing",
"tags": [],
"nodes": [
{
"id": "cebf963c-e554-43e0-8758-505f7224504f",
"name": "Schedule - Every Weekday 7AM",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
144,
-96
],
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 7 * * 1-5"
}
]
}
},
"typeVersion": 1.2
},
{
"id": "ce0f2526-bf07-440d-b466-899b9938f677",
"name": "Gmail - Fetch Unread Emails",
"type": "n8n-nodes-base.gmail",
"position": [
368,
-96
],
"parameters": {
"limit": 10,
"filters": {
"q": "is:unread newer_than:1d"
},
"operation": "getAll"
},
"typeVersion": 2
},
{
"id": "8677b449-8041-4cc5-9cfd-8391812519e0",
"name": "Code - Build Digest Text",
"type": "n8n-nodes-base.code",
"position": [
592,
-96
],
"parameters": {
"jsCode": "const items = $input.all();\n\nif (!items || items.length === 0) {\n return [{ json: { digest: 'No new emails found for today.', email_count: 0 } }];\n}\n\nconst skipPatterns = [\n /job alert/i,\n /jobs across/i,\n /looking for job/i,\n /linkedin job/i,\n /jobalerts/i,\n /pakistan ki jobs/i,\n /reshare jobs/i,\n /hrpp updates/i,\n /recruitment:/i,\n /people, policy/i,\n /skool\\.com/i,\n /notification since/i\n];\n\nconst urgent = [];\nconst newsletters = [];\nconst other = [];\n\nfor (let i = 0; i < items.length; i++) {\n const item = items[i].json;\n\n const from = item.From || item.from || 'Unknown sender';\n const subject = item.Subject || item.subject || 'No subject';\n const snippet = (item.snippet || '')\n .replace(/\u034f/g, '')\n .replace(/\\s{2,}/g, ' ')\n .replace(/\\n+/g, ' ')\n .trim()\n .substring(0, 200);\n\n const shouldSkip = skipPatterns.some(p =>\n p.test(subject) || p.test(from)\n );\n if (shouldSkip) continue;\n\n const entry = `From: ${from}\\nSubject: ${subject}\\nPreview: ${snippet}`;\n\n if (/warning|past due|invoice|action required|deprovisioned|deleted/i.test(subject + snippet)) {\n urgent.push(entry);\n } else if (/newsletter|weekly|digest|insights|dispatch|update/i.test(subject + from)) {\n newsletters.push(entry);\n } else {\n other.push(entry);\n }\n}\n\nconst sections = [];\nif (urgent.length > 0) sections.push('=== URGENT ===\\n' + urgent.join('\\n\\n'));\nif (newsletters.length > 0) sections.push('=== NEWSLETTERS ===\\n' + newsletters.join('\\n\\n'));\nif (other.length > 0) sections.push('=== OTHER ===\\n' + other.join('\\n\\n'));\n\nconst digest = sections.length > 0\n ? sections.join('\\n\\n')\n : 'No significant emails found today.';\n\nreturn [{ json: { digest, email_count: items.length } }];"
},
"typeVersion": 2
},
{
"id": "6a692360-63cf-485b-b363-33b2d7cb19fc",
"name": "AI Agent - Write Briefing Script",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
880,
-96
],
"parameters": {
"text": "={{ $json.digest }}",
"options": {
"systemMessage": "You are a professional morning briefing narrator for a busy digital marketing agency professional.\n\nYou will receive categorized emails under headings: URGENT, NEWSLETTERS, and OTHER.\n\nFollow these rules strictly:\n\n1. Start with exactly: \"Good morning! Here is your daily briefing for today.\"\n\n2. URGENT section first \u2014 for each urgent email, clearly state who it is from, what action is needed, and flag it as requiring immediate attention today. Be direct and clear.\n\n3. NEWSLETTERS section \u2014 summarize each newsletter in one natural sentence. Mention the sender and the core topic only.\n\n4. OTHER section \u2014 mention only if present and genuinely relevant.\n\n5. End with exactly: \"That's your morning briefing. Have a productive day!\"\n\n6. Keep total output strictly under 500 words and under 3000 characters. This is a hard limit \u2014 do not exceed it under any circumstances.\n\n7. Write in a warm, clear, conversational tone \u2014 this will be read aloud by a text-to-speech engine so it must sound natural when spoken.\n\n8. Do NOT include any JSON, markdown, bullet points, headers, symbols, or formatting of any kind.\n\n9. Return ONLY the final plain text spoken script. Nothing before it, nothing after it."
},
"promptType": "define"
},
"typeVersion": 1.7
},
{
"id": "0c93f188-408a-4a0a-a014-c137e44f0a1d",
"name": "Google Gemini Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
880,
112
],
"parameters": {
"options": {}
},
"typeVersion": 1
},
{
"id": "8c6a4095-26f8-4245-b223-d8d308d1adc4",
"name": "Code - Truncate for TTS",
"type": "n8n-nodes-base.code",
"position": [
1168,
-96
],
"parameters": {
"jsCode": "const text = $input.first().json.output || '';\n\n// 3500 chars \u2248 500 words, safely under Smallest AI 8000 char limit\nconst MAX_CHARS = 3500;\n\nconst truncated = text.length > MAX_CHARS\n ? text.substring(0, MAX_CHARS).replace(/\\s+\\S*$/, '') + '...'\n : text;\n\nreturn [{ json: { tts_text: truncated } }];"
},
"typeVersion": 2
},
{
"id": "4c8384fd-0352-4265-a018-3f57921bf67a",
"name": "Smallest AI - Synthesize Speech",
"type": "n8n-nodes-smallestai.smallestai",
"position": [
1472,
-96
],
"parameters": {
"text": "={{ $json.tts_text }}",
"output_format": "mp3",
"additionalOptions": {
"language": "en"
}
},
"credentials": {},
"typeVersion": 1
},
{
"id": "1e7ccdbf-387f-413d-b802-2ba942c9d8ad",
"name": "Google Drive - Upload Audio",
"type": "n8n-nodes-base.googleDrive",
"position": [
1776,
-96
],
"parameters": {
"name": "=Daily_Briefing_{{ $now.toFormat('yyyy-MM-dd') }}.mp3",
"driveId": {
"__rl": true,
"mode": "list",
"value": "My Drive"
},
"options": {},
"folderId": {
"__rl": true,
"mode": "list",
"value": "root"
}
},
"typeVersion": 3
},
{
"id": "4e33f4d0-22e0-4136-be1f-4faec602d8b7",
"name": "Google Drive - Make Public",
"type": "n8n-nodes-base.googleDrive",
"position": [
2000,
-96
],
"parameters": {
"fileId": {
"__rl": true,
"mode": "id",
"value": "={{ $json.id }}"
},
"options": {},
"operation": "share",
"permissionsUi": {
"permissionsValues": {
"role": "reader",
"type": "anyone"
}
}
},
"typeVersion": 3
},
{
"id": "32e80319-fed9-4938-8689-ed6afb2da2c5",
"name": "Gmail - Send Briefing Email",
"type": "n8n-nodes-base.gmail",
"position": [
2208,
-96
],
"parameters": {
"sendTo": "user@example.com",
"message": "=<p>Good morning!</p><p>Your audio briefing for {{ $now.toFormat('dd MMM yyyy') }} is ready:</p><p><a href=\"{{ $('Google Drive - Upload Audio').item.json.webViewLink }}\">\ud83c\udfa7 Listen to your briefing</a></p><hr><p style=\"color:#666;font-size:13px;\">{{ $('Code - Truncate for TTS').first().json.tts_text }}</p>",
"options": {},
"subject": "=\ud83c\udfa7 Your Daily Briefing \u2014 {{ $now.toFormat('dd MMM yyyy') }}"
},
"typeVersion": 2
},
{
"id": "eea6cb23-4d1b-4114-abb9-deaa3c5590f4",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-624,
-320
],
"parameters": {
"width": 592,
"height": 656,
"content": "## Daily Digest to Audio Briefing\n\n### How it works\nThis workflow automates your morning routine by turning your unread emails into a personalized, spoken-word audio briefing. Every weekday morning at 7 AM, the workflow triggers and fetches your unread emails from the past 24 hours via Gmail.\n\n### Setup steps\n* The trigger is pre-configured to run **Every Weekday at 7 AM** (adjust the cron expression if you prefer a different time).\n* Connect your **Gmail** account to authorize email fetching and delivery.\n* Authenticate your **Google Gemini** configuration inside the LangChain Chat Model node.\n* Connect your **Smallest.ai** API credentials to power the speech synthesis engine.\n* Link your **Google Drive** account to host the generated audio briefing.\n\n### Customization\nYou can update the search query filter inside the **Gmail - Fetch Unread Emails** node to target specific labels, star markers, or senders. "
},
"typeVersion": 1
},
{
"id": "c2e99f0e-461e-4e56-96d1-bf6ba63ce7a1",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
48,
-224
],
"parameters": {
"color": 7,
"width": 720,
"height": 384,
"content": "## Schedule Trigger & Email Ingestion\n"
},
"typeVersion": 1
},
{
"id": "0622f623-a77e-411a-8491-ede29e082578",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
800,
-224
],
"parameters": {
"color": 7,
"width": 848,
"height": 576,
"content": "## Intelligence & Voice Synthesis\nPasses the email text blocks to a Gemini-fueled LangChain Agent to filter out clutter and write a morning script, ensures characters stay within safe TTS boundaries, and synthesizes speech into an MP3 via Smallest.ai."
},
"typeVersion": 1
},
{
"id": "d9f6a92a-90d5-41da-b56d-15c3e72604ae",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
1696,
-224
],
"parameters": {
"color": 7,
"width": 720,
"height": 368,
"content": "## Cloud Storage & Inbox Delivery\n"
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"binaryMode": "separate",
"executionOrder": "v1"
},
"versionId": "73a8c8cf-f191-43d4-af74-ce87932e435c",
"nodeGroups": [],
"connections": {
"Code - Truncate for TTS": {
"main": [
[
{
"node": "Smallest AI - Synthesize Speech",
"type": "main",
"index": 0
}
]
]
},
"Code - Build Digest Text": {
"main": [
[
{
"node": "AI Agent - Write Briefing Script",
"type": "main",
"index": 0
}
]
]
},
"Google Gemini Chat Model": {
"ai_languageModel": [
[
{
"node": "AI Agent - Write Briefing Script",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Google Drive - Make Public": {
"main": [
[
{
"node": "Gmail - Send Briefing Email",
"type": "main",
"index": 0
}
]
]
},
"Gmail - Fetch Unread Emails": {
"main": [
[
{
"node": "Code - Build Digest Text",
"type": "main",
"index": 0
}
]
]
},
"Google Drive - Upload Audio": {
"main": [
[
{
"node": "Google Drive - Make Public",
"type": "main",
"index": 0
}
]
]
},
"Schedule - Every Weekday 7AM": {
"main": [
[
{
"node": "Gmail - Fetch Unread Emails",
"type": "main",
"index": 0
}
]
]
},
"Smallest AI - Synthesize Speech": {
"main": [
[
{
"node": "Google Drive - Upload Audio",
"type": "main",
"index": 0
}
]
]
},
"AI Agent - Write Briefing Script": {
"main": [
[
{
"node": "Code - Truncate for TTS",
"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 runs every weekday at 7 AM to fetch up to 10 unread Gmail messages from the last day, summarize them into a narrated script with Google Gemini, convert the script to an MP3 using Smallest.ai, upload it to Google Drive, and email you a public listening link. Runs on…
Source: https://n8n.io/workflows/17099/ — 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.
LinkedIn_Job_Hunt_and_Cover_Letter. Uses outputParserStructured, outputParserAutofixing, googleDrive, agent. Scheduled trigger; 85 nodes.
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 helps you find and evaluate job opportunities automatically, without spending hours searching and comparing roles. It uses your resume to look for relevant jobs on LinkedIn, checks how w
When I was applying for roles, I learned the hard way that a one-size-fits-all resume never wins. I obsessively tailored my resume for each posting, reflecting the exact scope, impact, and stack the t
This n8n template automates the tedious process of searching for jobs on LinkedIn. By integrating with tools for web scraping and leveraging AI (Google Gemini) for intelligent matching, this workflow