This workflow follows the Gmail → Gmail Trigger 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 →
{
"name": "Secretary \u2014 Gmail Manager (gelsonmascarenhas@gmail.com)",
"nodes": [
{
"id": "trig-email-n001",
"name": "New Email Received",
"type": "n8n-nodes-base.gmailTrigger",
"typeVersion": 1.2,
"position": [
240,
360
],
"parameters": {
"pollTimes": {
"item": [
{
"mode": "everyMinute"
}
]
},
"simple": false,
"filters": {}
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
}
},
{
"id": "set-email-n002",
"name": "Extract Email Fields",
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
480,
360
],
"parameters": {
"mode": "manual",
"duplicateItem": false,
"assignments": {
"assignments": [
{
"id": "ef1",
"name": "email_id",
"value": "={{ $json.id }}",
"type": "string"
},
{
"id": "ef2",
"name": "thread_id",
"value": "={{ $json.threadId }}",
"type": "string"
},
{
"id": "ef3",
"name": "from_email",
"value": "={{ $json.From || $json.from || '' }}",
"type": "string"
},
{
"id": "ef4",
"name": "subject",
"value": "={{ $json.Subject || $json.subject || '(no subject)' }}",
"type": "string"
},
{
"id": "ef5",
"name": "body_text",
"value": "={{ ($json.text || $json.snippet || '').substring(0, 2000) }}",
"type": "string"
},
{
"id": "ef6",
"name": "date_received",
"value": "={{ $json.Date || $json.date || $now.toISO() }}",
"type": "string"
},
{
"id": "ef7",
"name": "has_attachments",
"value": "={{ ($json.attachments || []).length > 0 }}",
"type": "boolean"
}
]
},
"options": {}
}
},
{
"id": "set-cls-prompt-n003",
"name": "Build Classify Prompt",
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
720,
360
],
"parameters": {
"mode": "manual",
"duplicateItem": false,
"assignments": {
"assignments": [
{
"id": "cp1",
"name": "email_id",
"value": "={{ $json.email_id }}",
"type": "string"
},
{
"id": "cp2",
"name": "thread_id",
"value": "={{ $json.thread_id }}",
"type": "string"
},
{
"id": "cp3",
"name": "from_email",
"value": "={{ $json.from_email }}",
"type": "string"
},
{
"id": "cp4",
"name": "subject",
"value": "={{ $json.subject }}",
"type": "string"
},
{
"id": "cp5",
"name": "body_text",
"value": "={{ $json.body_text }}",
"type": "string"
},
{
"id": "cp6",
"name": "has_attachments",
"value": "={{ $json.has_attachments }}",
"type": "boolean"
},
{
"id": "cp7",
"name": "prompt",
"value": "={{ 'Classify this email. Return ONLY a raw JSON object \u2014 no markdown, no backticks, no explanation.\\n{\"type\":\"meeting_request\" or \"invoice\" or \"newsletter\" or \"follow_up\" or \"general\",\"priority\":\"high\" or \"medium\" or \"low\",\"summary\":\"one sentence max\",\"requires_reply\":true or false}\\n\\nFrom: ' + $json.from_email + '\\nSubject: ' + $json.subject + '\\nBody: ' + $json.body_text }}",
"type": "string"
}
]
},
"options": {}
}
},
{
"id": "http-classify-n004",
"name": "AI: Classify Email",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
960,
360
],
"parameters": {
"method": "POST",
"url": "={{ 'https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key=' + $env.GEMINI_API_KEY }}",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ JSON.stringify({ contents: [{ parts: [{ text: $json.prompt }] }] }) }}"
}
},
{
"id": "code-parse-cls-n005",
"name": "Parse Classification",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1200,
360
],
"parameters": {
"jsCode": "const raw = $input.first().json.candidates?.[0]?.content?.parts?.[0]?.text || '{}';\nlet cls = {};\ntry { cls = JSON.parse((raw.match(/\\{[\\s\\S]*\\}/) || [raw])[0]); } catch(e) { cls = { type: 'general', priority: 'medium', summary: '', requires_reply: false }; }\nconst prev = $('Build Classify Prompt').item.json;\nreturn [{ json: {\n email_id: prev.email_id,\n thread_id: prev.thread_id,\n from_email: prev.from_email,\n subject: prev.subject,\n body_text: prev.body_text,\n has_attachments:prev.has_attachments,\n email_type: cls.type || 'general',\n priority: cls.priority || 'medium',\n summary: cls.summary || '',\n requires_reply: cls.requires_reply || false\n}}];"
}
},
{
"id": "switch-type-n006",
"name": "Route by Email Type",
"type": "n8n-nodes-base.switch",
"typeVersion": 3,
"position": [
1440,
360
],
"parameters": {
"mode": "rules",
"rules": {
"values": [
{
"conditions": {
"options": {
"caseSensitive": false,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "sw1",
"leftValue": "={{ $json.email_type }}",
"rightValue": "meeting_request",
"operator": {
"type": "string",
"operation": "equals"
}
}
]
},
"renameOutput": true,
"outputKey": "Meeting Request"
},
{
"conditions": {
"options": {
"caseSensitive": false,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "sw2",
"leftValue": "={{ $json.email_type }}",
"rightValue": "invoice",
"operator": {
"type": "string",
"operation": "equals"
}
}
]
},
"renameOutput": true,
"outputKey": "Invoice"
},
{
"conditions": {
"options": {
"caseSensitive": false,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "sw3",
"leftValue": "={{ $json.email_type }}",
"rightValue": "newsletter",
"operator": {
"type": "string",
"operation": "equals"
}
}
]
},
"renameOutput": true,
"outputKey": "Newsletter"
}
]
},
"fallbackOutput": "extra"
}
},
{
"id": "set-mtg-prompt-n007",
"name": "Build Meeting Prompt",
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
1680,
100
],
"parameters": {
"mode": "manual",
"duplicateItem": false,
"assignments": {
"assignments": [
{
"id": "mp1",
"name": "email_id",
"value": "={{ $json.email_id }}",
"type": "string"
},
{
"id": "mp2",
"name": "from_email",
"value": "={{ $json.from_email }}",
"type": "string"
},
{
"id": "mp3",
"name": "subject",
"value": "={{ $json.subject }}",
"type": "string"
},
{
"id": "mp4",
"name": "body_text",
"value": "={{ $json.body_text }}",
"type": "string"
},
{
"id": "mp5",
"name": "prompt",
"value": "={{ 'Extract meeting details. Return ONLY raw JSON (no markdown):\\n{\"title\":\"string\",\"date\":\"YYYY-MM-DD\",\"start_time\":\"HH:MM\",\"end_time\":\"HH:MM\",\"timezone\":\"Europe/London\",\"location\":\"string or null\",\"description\":\"string\",\"confirmation_reply\":\"polite reply to sender\"}\\nIf unsure about a field use reasonable defaults. Today is ' + $now.toFormat('yyyy-MM-dd') + '.\\n\\nFrom: ' + $json.from_email + '\\nSubject: ' + $json.subject + '\\nBody: ' + $json.body_text }}",
"type": "string"
}
]
},
"options": {}
}
},
{
"id": "http-meeting-n008",
"name": "AI: Extract Meeting Details",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1920,
100
],
"parameters": {
"method": "POST",
"url": "={{ 'https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key=' + $env.GEMINI_API_KEY }}",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ JSON.stringify({ contents: [{ parts: [{ text: $json.prompt }] }] }) }}"
}
},
{
"id": "code-parse-mtg-n009",
"name": "Parse Meeting Details",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2160,
100
],
"parameters": {
"jsCode": "const raw = $input.first().json.candidates?.[0]?.content?.parts?.[0]?.text || '{}';\nlet m = {};\ntry { m = JSON.parse((raw.match(/\\{[\\s\\S]*\\}/) || [raw])[0]); } catch(e) { m = {}; }\nconst prev = $('Build Meeting Prompt').item.json;\nconst date = m.date || $now.toFormat('yyyy-MM-dd');\nconst start = m.start_time || '10:00';\nconst end = m.end_time || '11:00';\nconst tz = m.timezone || 'Europe/London';\nreturn [{ json: {\n email_id: prev.email_id,\n from_email: prev.from_email,\n subject: prev.subject,\n event_title: m.title || prev.subject || 'Meeting',\n event_description: m.description || '',\n event_location: m.location || '',\n event_start: date + 'T' + start + ':00',\n event_end: date + 'T' + end + ':00',\n confirmation_reply: m.confirmation_reply || 'Thank you \u2014 I have added this meeting to the calendar.'\n}}];"
}
},
{
"id": "cal-create-n010",
"name": "Create Calendar Event",
"type": "n8n-nodes-base.googleCalendar",
"typeVersion": 1.2,
"position": [
2400,
100
],
"parameters": {
"resource": "event",
"operation": "create",
"calendar": {
"__rl": true,
"value": "primary",
"mode": "list"
},
"start": "={{ $json.event_start }}",
"end": "={{ $json.event_end }}",
"additionalFields": {
"summary": "={{ $json.event_title }}",
"description": "={{ $json.event_description }}",
"location": "={{ $json.event_location }}"
}
},
"credentials": {
"googleCalendarOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"id": "gmail-reply-mtg-n011",
"name": "Reply: Meeting Confirmed",
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.1,
"position": [
2640,
100
],
"parameters": {
"resource": "message",
"operation": "reply",
"messageId": "={{ $('Parse Meeting Details').item.json.email_id }}",
"message": "={{ $('Parse Meeting Details').item.json.confirmation_reply }}",
"additionalFields": {}
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
}
},
{
"id": "set-inv-prompt-n012",
"name": "Build Invoice Prompt",
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
1680,
360
],
"parameters": {
"mode": "manual",
"duplicateItem": false,
"assignments": {
"assignments": [
{
"id": "ip1",
"name": "email_id",
"value": "={{ $json.email_id }}",
"type": "string"
},
{
"id": "ip2",
"name": "from_email",
"value": "={{ $json.from_email }}",
"type": "string"
},
{
"id": "ip3",
"name": "subject",
"value": "={{ $json.subject }}",
"type": "string"
},
{
"id": "ip4",
"name": "body_text",
"value": "={{ $json.body_text }}",
"type": "string"
},
{
"id": "ip5",
"name": "prompt",
"value": "={{ 'Extract invoice data. Return ONLY raw JSON (no markdown):\\n{\"vendor\":\"string\",\"invoice_number\":\"string or null\",\"invoice_date\":\"YYYY-MM-DD or null\",\"due_date\":\"YYYY-MM-DD or null\",\"amount\":0.00,\"currency\":\"GBP\",\"description\":\"string\",\"acknowledgment_reply\":\"professional acknowledgment reply\"}\\n\\nFrom: ' + $json.from_email + '\\nSubject: ' + $json.subject + '\\nBody: ' + $json.body_text }}",
"type": "string"
}
]
},
"options": {}
}
},
{
"id": "http-invoice-n013",
"name": "AI: Extract Invoice Data",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1920,
360
],
"parameters": {
"method": "POST",
"url": "={{ 'https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key=' + $env.GEMINI_API_KEY }}",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ JSON.stringify({ contents: [{ parts: [{ text: $json.prompt }] }] }) }}"
}
},
{
"id": "code-parse-inv-n014",
"name": "Parse Invoice Data",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2160,
360
],
"parameters": {
"jsCode": "const raw = $input.first().json.candidates?.[0]?.content?.parts?.[0]?.text || '{}';\nlet inv = {};\ntry { inv = JSON.parse((raw.match(/\\{[\\s\\S]*\\}/) || [raw])[0]); } catch(e) { inv = {}; }\nconst prev = $('Build Invoice Prompt').item.json;\nreturn [{ json: {\n email_id: prev.email_id,\n from_email: prev.from_email,\n subject: prev.subject,\n vendor: inv.vendor || prev.from_email,\n invoice_number: inv.invoice_number || '',\n invoice_date: inv.invoice_date || $now.toFormat('yyyy-MM-dd'),\n due_date: inv.due_date || '',\n amount: inv.amount || 0,\n currency: inv.currency || 'GBP',\n description: inv.description || prev.subject,\n acknowledgment_reply: inv.acknowledgment_reply || 'Thank you \u2014 your invoice has been received and logged.'\n}}];"
}
},
{
"id": "sheets-invoice-n015",
"name": "Log Invoice to Sheets",
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4.5,
"position": [
2400,
360
],
"parameters": {
"resource": "sheet",
"operation": "append",
"documentId": {
"__rl": true,
"value": "={{ $env.INVOICE_SHEET_ID || '' }}",
"mode": "id"
},
"sheetName": {
"__rl": true,
"value": "gid=0",
"mode": "id"
},
"columns": {
"mappingMode": "defineBelow",
"value": {
"Received Date": "={{ $now.toISO() }}",
"Vendor": "={{ $json.vendor }}",
"Invoice Number": "={{ $json.invoice_number }}",
"Invoice Date": "={{ $json.invoice_date }}",
"Due Date": "={{ $json.due_date }}",
"Amount": "={{ $json.amount }}",
"Currency": "={{ $json.currency }}",
"Description": "={{ $json.description }}"
}
},
"options": {}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"id": "gmail-reply-inv-n016",
"name": "Reply: Invoice Acknowledged",
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.1,
"position": [
2640,
360
],
"parameters": {
"resource": "message",
"operation": "reply",
"messageId": "={{ $('Parse Invoice Data').item.json.email_id }}",
"message": "={{ $('Parse Invoice Data').item.json.acknowledgment_reply }}",
"additionalFields": {}
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
}
},
{
"id": "gmail-archive-n017",
"name": "Archive Newsletter",
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.1,
"position": [
1680,
620
],
"parameters": {
"resource": "message",
"operation": "addLabels",
"messageId": "={{ $json.email_id }}",
"labelIds": [
"CATEGORY_PROMOTIONS"
]
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
}
},
{
"id": "set-draft-prompt-n018",
"name": "Build Draft Prompt",
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
1680,
880
],
"parameters": {
"mode": "manual",
"duplicateItem": false,
"assignments": {
"assignments": [
{
"id": "dp1",
"name": "email_id",
"value": "={{ $json.email_id }}",
"type": "string"
},
{
"id": "dp2",
"name": "from_email",
"value": "={{ $json.from_email }}",
"type": "string"
},
{
"id": "dp3",
"name": "subject",
"value": "={{ $json.subject }}",
"type": "string"
},
{
"id": "dp4",
"name": "body_text",
"value": "={{ $json.body_text }}",
"type": "string"
},
{
"id": "dp5",
"name": "prompt",
"value": "={{ 'You are a professional personal assistant. Draft a reply to the email below. Return ONLY raw JSON (no markdown):\\n{\"draft_subject\":\"Re: subject\",\"draft_body\":\"full reply text\"}\\n\\nFrom: ' + $json.from_email + '\\nSubject: ' + $json.subject + '\\nBody: ' + $json.body_text }}",
"type": "string"
}
]
},
"options": {}
}
},
{
"id": "http-draft-n019",
"name": "AI: Draft Smart Reply",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1920,
880
],
"parameters": {
"method": "POST",
"url": "={{ 'https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key=' + $env.GEMINI_API_KEY }}",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ JSON.stringify({ contents: [{ parts: [{ text: $json.prompt }] }] }) }}"
}
},
{
"id": "code-parse-draft-n020",
"name": "Parse Draft Reply",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2160,
880
],
"parameters": {
"jsCode": "const raw = $input.first().json.candidates?.[0]?.content?.parts?.[0]?.text || '{}';\nlet dr = {};\ntry { dr = JSON.parse((raw.match(/\\{[\\s\\S]*\\}/) || [raw])[0]); } catch(e) { dr = { draft_subject: '', draft_body: raw }; }\nconst prev = $('Build Draft Prompt').item.json;\nreturn [{ json: {\n email_id: prev.email_id,\n from_email: prev.from_email,\n subject: prev.subject,\n draft_subject: dr.draft_subject || ('Re: ' + prev.subject),\n draft_body: dr.draft_body || ''\n}}];"
}
},
{
"id": "gmail-draft-n021",
"name": "Create Email Draft",
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.1,
"position": [
2400,
880
],
"parameters": {
"resource": "draft",
"operation": "create",
"subject": "={{ $json.draft_subject }}",
"message": "={{ $json.draft_body }}",
"additionalFields": {}
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
}
},
{
"id": "gmail-mark-read-n022",
"name": "Mark Email Read",
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.1,
"position": [
2880,
360
],
"parameters": {
"resource": "message",
"operation": "markAsRead",
"messageId": "={{ $json.email_id || $json.id }}"
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
}
},
{
"id": "trig-schedule-n023",
"name": "Daily Digest Schedule",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.2,
"position": [
240,
1160
],
"parameters": {
"rule": {
"interval": [
{
"field": "days",
"triggerAtHour": 8,
"triggerAtMinute": 0
}
]
}
}
},
{
"id": "gmail-get-emails-n024",
"name": "Get Unread Emails",
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.1,
"position": [
480,
1160
],
"parameters": {
"resource": "message",
"operation": "getAll",
"returnAll": false,
"limit": 25,
"filters": {
"readStatus": "unread"
},
"options": {}
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
}
},
{
"id": "code-agg-emails-n025",
"name": "Aggregate Email Data",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
720,
1160
],
"parameters": {
"jsCode": "const emails = $input.all();\nconst summary = emails.slice(0, 20).map((item, i) => {\n const e = item.json;\n const from = e.From || e.from || 'Unknown';\n const subj = e.Subject || e.subject || '(no subject)';\n const snippet = (e.snippet || e.text || '').substring(0, 120);\n return `${i + 1}. From: ${from}\\n Subject: ${subj}\\n Preview: ${snippet}`;\n}).join('\\n\\n');\nreturn [{ json: { email_count: emails.length, email_summary: summary || 'No unread emails.' } }];"
}
},
{
"id": "cal-today-n026",
"name": "Get Today Calendar Events",
"type": "n8n-nodes-base.googleCalendar",
"typeVersion": 1.2,
"position": [
960,
1160
],
"parameters": {
"resource": "event",
"operation": "getAll",
"calendar": {
"__rl": true,
"value": "primary",
"mode": "list"
},
"returnAll": false,
"limit": 20,
"options": {
"timeMin": "={{ $now.startOf('day').toISO() }}",
"timeMax": "={{ $now.endOf('day').toISO() }}",
"singleEvents": true,
"orderBy": "startTime"
}
},
"credentials": {
"googleCalendarOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"id": "code-combine-digest-n027",
"name": "Combine Digest Data",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1200,
1160
],
"parameters": {
"jsCode": "const emailData = $('Aggregate Email Data').item.json;\nconst calItems = $input.all();\nconst eventList = calItems.length\n ? calItems.map(item => {\n const e = item.json;\n const title = e.summary || 'Untitled Event';\n const start = e.start?.dateTime || e.start?.date || 'TBD';\n const end = e.end?.dateTime || e.end?.date || '';\n const loc = e.location ? ` @ ${e.location}` : '';\n return `\u2022 ${title}${loc} \u2014 ${start}${end ? ' \u2192 ' + end : ''}`;\n }).join('\\n')\n : 'No events scheduled for today.';\nconst today = new Date().toLocaleDateString('en-GB', { weekday:'long', year:'numeric', month:'long', day:'numeric' });\nconst prompt = `You are a professional personal assistant. Create a concise morning briefing for today, ${today}.\\n\\nUNREAD EMAILS (${emailData.email_count}):\\n${emailData.email_summary}\\n\\nTODAY\\'S CALENDAR:\\n${eventList}\\n\\nFormat as:\\n1. Priority Actions (emails needing attention)\\n2. Today\\'s Schedule\\n3. Notes / Reminders\\n\\nBe friendly, professional, and concise \u2014 max 400 words.`;\nreturn [{ json: { email_count: emailData.email_count, email_summary: emailData.email_summary, event_list: eventList, prompt } }];"
}
},
{
"id": "http-digest-n028",
"name": "AI: Generate Daily Digest",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1440,
1160
],
"parameters": {
"method": "POST",
"url": "={{ 'https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key=' + $env.GEMINI_API_KEY }}",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ JSON.stringify({ contents: [{ parts: [{ text: $json.prompt }] }] }) }}"
}
},
{
"id": "code-parse-digest-n029",
"name": "Parse Digest Response",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1680,
1160
],
"parameters": {
"jsCode": "const aiText = ($input.first().json.candidates?.[0]?.content?.parts?.[0]?.text || 'No digest generated.').replace(/`[^]*`/g, '').trim();\nconst today = new Date().toLocaleDateString('en-GB', { weekday:'long', year:'numeric', month:'long', day:'numeric' });\nconst subject = `Your Morning Briefing \u2014 ${today}`;\nconst body = `<html><body style=\"font-family:sans-serif;max-width:600px;margin:0 auto;padding:20px\"><h2>\ud83d\uddd3\ufe0f Morning Briefing</h2><p><strong>${today}</strong></p><hr>${aiText.replace(/\\n/g, '<br>')}<hr><p style=\"font-size:11px;color:#888\">Sent by your Gmail Secretary</p></body></html>`;\nreturn [{ json: { digest_subject: subject, digest_body: body } }];"
}
},
{
"id": "gmail-send-digest-n030",
"name": "Send Daily Digest",
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.1,
"position": [
1920,
1160
],
"parameters": {
"resource": "message",
"operation": "send",
"sendTo": "gelsonmascarenhas@gmail.com",
"subject": "={{ $json.digest_subject }}",
"message": "={{ $json.digest_body }}",
"additionalFields": {
"emailType": "html"
}
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
}
},
{
"id": "trig-webhook-n031",
"name": "Secretary Command",
"type": "n8n-nodes-base.webhook",
"typeVersion": 2,
"position": [
240,
1700
],
"parameters": {
"httpMethod": "POST",
"path": "secretary",
"responseMode": "responseNode",
"options": {}
}
},
{
"id": "set-cmd-prompt-n032",
"name": "Build Command Prompt",
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
480,
1700
],
"parameters": {
"mode": "manual",
"duplicateItem": false,
"assignments": {
"assignments": [
{
"id": "cmp1",
"name": "raw_command",
"value": "={{ $json.body?.command || $json.command || $json.body?.text || '' }}",
"type": "string"
},
{
"id": "cmp2",
"name": "prompt",
"value": "={{ 'You are a secretary. Parse the user command and return ONLY raw JSON (no markdown):\\n{\"intent\":\"schedule_meeting\" or \"check_calendar\" or \"delete_event\" or \"search_email\" or \"send_email\" or \"general_query\",\"params\":{\"title\":\"string\",\"date\":\"YYYY-MM-DD\",\"time\":\"HH:MM\",\"duration_minutes\":60,\"description\":\"string\",\"event_id\":\"string\",\"query\":\"string\",\"to\":\"email\",\"subject\":\"string\",\"body\":\"string\",\"days_ahead\":1},\"human_response\":\"what you will do\"}\\nToday is ' + $now.toFormat('yyyy-MM-dd') + '. Command: ' + ($json.body && $json.body.command ? $json.body.command : ($json.command || '')) }}",
"type": "string"
}
]
},
"options": {}
}
},
{
"id": "http-parse-cmd-n033",
"name": "AI: Parse Command Intent",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
720,
1700
],
"parameters": {
"method": "POST",
"url": "={{ 'https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key=' + $env.GEMINI_API_KEY }}",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ JSON.stringify({ contents: [{ parts: [{ text: $json.prompt }] }] }) }}"
}
},
{
"id": "code-parse-cmd-n034",
"name": "Parse Command Result",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
960,
1700
],
"parameters": {
"jsCode": "const raw = $input.first().json.candidates?.[0]?.content?.parts?.[0]?.text || '{}';\nlet cmd = {};\ntry { cmd = JSON.parse((raw.match(/\\{[\\s\\S]*\\}/) || [raw])[0]); } catch(e) { cmd = { intent: 'general_query', params: {}, human_response: '' }; }\nreturn [{ json: {\n intent: cmd.intent || 'general_query',\n params: cmd.params || {},\n human_response: cmd.human_response || 'Processing your request...',\n event_title: cmd.params?.title || '',\n event_date: cmd.params?.date || new Date().toISOString().split('T')[0],\n event_time: cmd.params?.time || '10:00',\n event_duration: cmd.params?.duration_minutes || 60,\n event_desc: cmd.params?.description || '',\n event_id: cmd.params?.event_id || '',\n search_query: cmd.params?.query || '',\n send_to: cmd.params?.to || '',\n send_subject: cmd.params?.subject || '',\n send_body: cmd.params?.body || '',\n days_ahead: cmd.params?.days_ahead || 1\n}}];"
}
},
{
"id": "switch-cmd-n035",
"name": "Route Command",
"type": "n8n-nodes-base.switch",
"typeVersion": 3,
"position": [
1200,
1700
],
"parameters": {
"mode": "rules",
"rules": {
"values": [
{
"conditions": {
"options": {
"caseSensitive": false,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "rc1",
"leftValue": "={{ $json.intent }}",
"rightValue": "check_calendar",
"operator": {
"type": "string",
"operation": "equals"
}
}
]
},
"renameOutput": true,
"outputKey": "Check Calendar"
},
{
"conditions": {
"options": {
"caseSensitive": false,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "rc2",
"leftValue": "={{ $json.intent }}",
"rightValue": "schedule_meeting",
"operator": {
"type": "string",
"operation": "equals"
}
}
]
},
"renameOutput": true,
"outputKey": "Schedule Meeting"
},
{
"conditions": {
"options": {
"caseSensitive": false,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "rc3",
"leftValue": "={{ $json.intent }}",
"rightValue": "delete_event",
"operator": {
"type": "string",
"operation": "equals"
}
}
]
},
"renameOutput": true,
"outputKey": "Delete Event"
},
{
"conditions": {
"options": {
"caseSensitive": false,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "rc4",
"leftValue": "={{ $json.intent }}",
"rightValue": "search_email",
"operator": {
"type": "string",
"operation": "equals"
}
}
]
},
"renameOutput": true,
"outputKey": "Search Email"
},
{
"conditions": {
"options": {
"caseSensitive": false,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "rc5",
"leftValue": "={{ $json.intent }}",
"rightValue": "send_email",
"operator": {
"type": "string",
"operation": "equals"
}
}
]
},
"renameOutput": true,
"outputKey": "Send Email"
}
]
},
"fallbackOutput": "extra"
}
},
{
"id": "cal-list-cmd-n036",
"name": "Cmd: Get Calendar Events",
"type": "n8n-nodes-base.googleCalendar",
"typeVersion": 1.2,
"position": [
1440,
1460
],
"parameters": {
"resource": "event",
"operation": "getAll",
"calendar": {
"__rl": true,
"value": "primary",
"mode": "list"
},
"returnAll": false,
"limit": 10,
"options": {
"timeMin": "={{ $now.startOf('day').toISO() }}",
"timeMax": "={{ $now.plus({ days: $json.days_ahead || 1 }).endOf('day').toISO() }}",
"singleEvents": true,
"orderBy": "startTime"
}
},
"credentials": {
"googleCalendarOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"id": "cal-create-cmd-n037",
"name": "Cmd: Create Meeting",
"type": "n8n-nodes-base.googleCalendar",
"typeVersion": 1.2,
"position": [
1440,
1620
],
"parameters": {
"resource": "event",
"operation": "create",
"calendar": {
"__rl": true,
"value": "primary",
"mode": "list"
},
"start": "={{ $json.event_date + 'T' + $json.event_time + ':00' }}",
"end": "={{ $json.event_date + 'T' + ((() => { const [h,m] = ($json.event_time||'10:00').split(':').map(Number); const end = h + Math.floor(($json.event_duration||60)/60); const endM = m + ($json.event_duration||60)%60; return String(end).padStart(2,'0') + ':' + String(endM).padStart(2,'0'); })()) + ':00' }}",
"additionalFields": {
"summary": "={{ $json.event_title }}",
"description": "={{ $json.event_desc }}"
}
},
"credentials": {
"googleCalendarOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"id": "cal-delete-cmd-n038",
"name": "Cmd: Delete Event",
"type": "n8n-nodes-base.googleCalendar",
"typeVersion": 1.2,
"position": [
1440,
1780
],
"parameters": {
"resource": "event",
"operation": "delete",
"calendar": {
"__rl": true,
"value": "primary",
"mode": "list"
},
"eventId": "={{ $json.event_id }}"
},
"credentials": {
"googleCalendarOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"id": "gmail-search-cmd-n039",
"name": "Cmd: Search Gmail",
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.1,
"position": [
1440,
1940
],
"parameters": {
"resource": "message",
"operation": "getAll",
"returnAll": false,
"limit": 10,
"filters": {
"q": "={{ $json.search_query }}"
},
"options": {}
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
}
},
{
"id": "gmail-send-cmd-n040",
"name": "Cmd: Send Email",
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.1,
"position": [
1440,
2100
],
"parameters": {
"resource": "message",
"operation": "send",
"sendTo": "={{ $json.send_to }}",
"subject": "={{ $json.send_subject }}",
"message": "={{ $json.send_body }}",
"additionalFields": {}
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
}
},
{
"id": "set-resp-cal-n041",
"name": "Respond: Calendar Events",
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
1680,
1460
],
"parameters": {
"mode": "manual",
"duplicateItem": false,
"assignments": {
"assignments": [
{
"id": "rc1",
"name": "response_text",
"value": "={{ 'Found ' + $input.all().length + ' event(s): ' + $input.all().map(i => (i.json.summary || 'Untitled') + ' at ' + (i.json.start?.dateTime || i.json.start?.date || 'TBD')).join('; ') }}",
"type": "string"
}
]
},
"options": {}
}
},
{
"id": "set-resp-mtg-n042",
"name": "Respond: Meeting Created",
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
1680,
1620
],
"parameters": {
"mode": "manual",
"duplicateItem": false,
"assignments": {
"assignments": [
{
"id": "rm1",
"name": "response_text",
"value": "={{ 'Meeting \"' + ($json.summary || 'event') + '\" created on ' + ($json.start?.dateTime || $json.start?.date || 'calendar') + '.' }}",
"type": "string"
}
]
},
"options": {}
}
},
{
"id": "set-resp-del-n043",
"name": "Respond: Event Deleted",
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
1680,
1780
],
"parameters": {
"mode": "manual",
"duplicateItem": false,
"assignments": {
"assignments": [
{
"id": "rd1",
"name": "response_text",
"value": "Calendar event deleted successfully.",
"type": "string"
}
]
},
"options": {}
}
},
{
"id": "set-resp-search-n044",
"name": "Respond: Search Results",
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
1680,
1940
],
"parameters": {
"mode": "manual",
"duplicateItem": false,
"assignments": {
"assignments": [
{
"id": "rs1",
"name": "response_text",
"value": "={{ 'Found ' + $input.all().length + ' email(s): ' + $input.all().map(i => '\"' + (i.json.Subject || i.json.subject || '(no subject)') + '\" from ' + (i.json.From || i.json.from || 'unknown')).join('; ') }}",
"type": "string"
}
]
},
"options": {}
}
},
{
"id": "set-resp-sent-n045",
"name": "Respond: Email Sent",
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
1680,
2100
],
"parameters": {
"mode": "manual",
"duplicateItem": false,
"assignments": {
"assignments": [
{
"id": "rss1",
"name": "response_text",
"value": "Email sent successfully.",
"type": "string"
}
]
},
"options": {}
}
},
{
"id": "set-resp-general-n046",
"name": "Respond: General Query",
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
1440,
2260
],
"parameters": {
"mode": "manual",
"duplicateItem": false,
"assignments": {
"assignments": [
{
"id": "rg1",
"name": "response_text",
"value": "={{ $json.human_response || 'I processed your request.' }}",
"type": "string"
}
]
},
"options": {}
}
},
{
"id": "respond-webhook-n047",
"name": "Respond to Webhook",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1.1,
"position": [
1920,
1860
],
"parameters": {
"respondWith": "json",
"responseBody": "={{ JSON.stringify({ success: true, response: $json.response_text, timestamp: new Date().toISOString() }) }}",
"options": {
"responseCode": 200
}
}
}
],
"connections": {
"New Email Received": {
"main": [
[
{
"node": "Extract Email Fields",
"type": "main",
"index": 0
}
]
]
},
"Extract Email Fields": {
"main": [
[
{
"node": "Build Classify Prompt",
"type": "main",
"index": 0
}
]
]
},
"Build Classify Prompt": {
"main": [
[
{
"node": "AI: Classify Email",
"type": "main",
"index": 0
}
]
]
},
"AI: Classify Email": {
"main": [
[
{
"node": "Parse Classification",
"type": "main",
"index": 0
}
]
]
},
"Parse Classification": {
"main": [
[
{
"node": "Route by Email Type",
"type": "main",
"index": 0
}
]
]
},
"Route by Email Type": {
"main": [
[
{
"node": "Build Meeting Prompt",
"type": "main",
"index": 0
}
],
[
{
"node": "Build Invoice Prompt",
"type": "main",
"index": 0
}
],
[
{
"node": "Archive Newsletter",
"type": "main",
"index": 0
}
],
[
{
"node": "Build Draft Prompt",
"type": "main",
"index": 0
}
]
]
},
"Build Meeting Prompt": {
"main": [
[
{
"node": "AI: Extract Meeting Details",
"type": "main",
"index": 0
}
]
]
},
"AI: Extract Meeting Details": {
"main": [
[
{
"node": "Parse Meeting Details",
"type": "main",
"index": 0
}
]
]
},
"Parse Meeting Details": {
"main": [
[
{
"node": "Create Calendar Event",
"type": "main",
"index": 0
}
]
]
},
"Create Calendar Event": {
"main": [
[
{
"node": "Reply: Meeting Confirmed",
"type": "main",
"index": 0
}
]
]
},
"Reply: Meeting Confirmed": {
"main": [
[
{
"node": "Mark Email Read",
"type": "main",
"index": 0
}
]
]
},
"Build Invoice Prompt": {
"main": [
[
{
"node": "AI: Extract Invoice Data",
"type": "main",
"index": 0
}
]
]
},
"AI: Extract Invoice Data": {
"main": [
[
{
"node": "Parse Invoice Data",
"type": "main",
"index": 0
}
]
]
},
"Parse Invoice Data": {
"main": [
[
{
"node": "Log Invoice to Sheets",
"type": "main",
"index": 0
}
]
]
},
"Log Invoice to Sheets": {
"main": [
[
{
"node": "Reply: Invoice Acknowledged",
"type": "main",
"index": 0
}
]
]
},
"Reply: Invoice Acknowledged": {
"main": [
[
{
"node": "Mark Email Read",
"type": "main",
"index": 0
}
]
]
},
"Archive Newsletter": {
"main": [
[
{
"node": "Mark Email Read",
"type": "main",
"index": 0
}
]
]
},
"Build Draft Prompt": {
"main": [
[
{
"node": "AI: Draft Smart Reply",
"type": "main",
"index": 0
}
]
]
},
"AI: Draft Smart Reply": {
"main": [
[
{
"node": "Parse Draft Reply",
"type": "main",
"index": 0
}
]
]
},
"Parse Draft Reply": {
"main": [
[
{
"node": "Create Email Draft",
"type": "main",
"index": 0
}
]
]
},
"Create Email Draft": {
"main": [
[
{
"node": "Mark Email Read",
"type": "main",
"index": 0
}
]
]
},
"Daily Digest Schedule": {
"main": [
[
{
"node": "Get Unread Emails",
"type": "main",
"index": 0
}
]
]
},
"Get Unread Emails": {
"main": [
[
{
"node": "Aggregate Email Data",
"type": "main",
"index": 0
}
]
]
},
"Aggregate Email Data": {
"main": [
[
{
"node": "Get Today Calendar Events",
"type": "main",
"index": 0
}
]
]
},
"Get Today Calendar Events": {
"main": [
[
{
"node": "Combine Digest Data",
"type": "main",
"index": 0
}
]
]
},
"Combine Digest Data": {
"main": [
[
{
"node": "AI: Generate Daily Digest",
"type": "main",
"index": 0
}
]
]
},
"AI: Generate Daily Digest": {
"main": [
[
{
"node": "Parse Digest Response",
"type": "main",
"index": 0
}
]
]
},
"Parse Digest Response": {
"main": [
[
{
"node": "Send Daily Digest",
"type": "main",
"index": 0
}
]
]
},
"Secretary Command": {
"main": [
[
{
"node": "Build Command Prompt",
"type": "main",
"index": 0
}
]
]
},
"Build Command Prompt": {
"main": [
[
{
"node": "AI: Parse Command Intent",
"type": "main",
"index": 0
}
]
]
},
"AI: Parse Command Intent": {
"main": [
[
{
"node": "Parse Command Result",
"type": "main",
"index": 0
}
]
]
},
"Parse Command Result": {
"main": [
[
{
"node": "Route Command",
"type": "main",
"index": 0
}
]
]
},
"Route Command": {
"main": [
[
{
"node": "Cmd: Get Calendar Events",
"type": "main",
"index": 0
}
],
[
{
"node": "Cmd: Create Meeting",
"type": "main",
"index": 0
}
],
[
{
"node": "Cmd: Delete Event",
"type": "main",
"index": 0
}
],
[
{
"node": "Cmd: Search Gmail",
"type": "main",
"index": 0
}
],
[
{
"node": "Cmd: Send Email",
"type": "main",
"index": 0
}
],
[
{
"node": "Respond: General Query",
"type": "main",
"index": 0
}
]
]
},
"Cmd: Get Calendar Events": {
"main": [
[
{
"node": "Respond: Calendar Events",
"type": "main",
"index": 0
}
]
]
},
"Cmd: Create Meeting": {
"main": [
[
{
"node": "Respond: Meeting Created",
"type": "main",
"index": 0
}
]
]
},
"Cmd: Delete Event": {
"main": [
[
{
"node": "Respond: Event Deleted",
"type": "main",
"index": 0
}
]
]
},
"Cmd: Search Gmail": {
"main": [
[
{
"node": "Respond: Search Results",
"type": "main",
"index": 0
}
]
]
},
"Cmd: Send Email": {
"main": [
[
{
"node": "Respond: Email Sent",
"type": "main",
"index": 0
}
]
]
},
"Respond: Calendar Events": {
"main": [
[
{
"node": "Respond to Webhook",
"type": "main",
"index": 0
}
]
]
},
"Respond: Meeting Created": {
"main": [
[
{
"node": "Respond to Webhook",
"type": "main",
"index": 0
}
]
]
},
"Respond: Event Deleted": {
"main": [
[
{
"node": "Respond to Webhook",
"type": "main",
"index": 0
}
]
]
},
"Respond: Search Results": {
"main": [
[
{
"node": "Respond to Webhook",
"type": "main",
"index": 0
}
]
]
},
"Respond: Email Sent": {
"main": [
[
{
"node": "Respond to Webhook",
"type": "main",
"index": 0
}
]
]
},
"Respond: General Query": {
"main": [
[
{
"node": "Respond to Webhook",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1",
"saveManualExecutions": true,
"saveExecutionProgress": true,
"errorWorkflow": ""
},
"meta": {
"templateCredsSetupCompleted": false,
"description": "AI-powered Gmail secretary: auto-classifies emails, creates calendar events from meeting requests, extracts and logs invoices, drafts smart replies, sends a daily morning briefing, and responds to natural language commands via webhook."
},
"tags": [
{
"name": "secretary"
},
{
"name": "gmail"
},
{
"name": "calendar"
},
{
"name": "ai"
}
]
}
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.
gmailOAuth2googleCalendarOAuth2ApigoogleSheetsOAuth2Api
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Secretary — Gmail Manager (gelsonmascarenhas@gmail.com). Uses gmailTrigger, httpRequest, googleCalendar, gmail. Event-driven trigger; 47 nodes.
Source: https://github.com/gelson12/super-agent/blob/c6b7435c3ef54ed3f7432efdc42e0aed35990df8/n8n/gmail_secretary.json — 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.
Enterprise-grade resume screening automation built for production environments. This workflow combines intelligent AI analysis with comprehensive error handling to ensure reliable processing of candid
*Tags: AI Agent, Supply Chain, Logistics, Circular Economy, Route Planning, Transportation, GPS API*
This n8n workflow automates the process of parsing and extracting data from PDF invoices. With this workflow, accounts and finance people can realise huge time and cost savings in their busy schedules
*Tags: AI Agent, Supply Chain, Logistics, Route Planning, Transportation, GPS API*
Invoice_data_extraction_with_LlamaParse_and_OpenAI. Uses lmOpenAi, outputParserStructured, httpRequest, gmailTrigger. Event-driven trigger; 26 nodes.