workflow recipe
n8n OpenAI Email Summary Workflow for Gmail Triage
Use Gmail to collect a narrow set of messages, Set or Code to clean the fields, OpenAI to summarize, and Slack or Gmail to deliver a concise digest.
- Use when
- n8n workflows, Gmail, OpenAI, email summaries
- First check
- Define the Gmail label or query that marks messages safe for summarization.
- Time to check
- 5-10 minutes
- Next step
- Run the recommended steps, then verify a production execution.
Independent third-party notes. n8n is a trademark of its owner and is referenced only for compatibility and troubleshooting context.
Quick Answer
Use Gmail to collect a narrow set of messages, Set or Code to clean the fields, OpenAI to summarize, and Slack or Gmail to deliver a concise digest.
Problem Pattern
AI email summary workflows can leak too much content, summarize the wrong messages, or fail when prompts receive messy HTML and long threads.
Version awareness
Last reviewed 2026-05-21
Key Facts
- Input control
- Summarize only messages that match a specific label, query, or schedule window.
- Prompt control
- Use short, structured fields rather than raw email HTML when possible.
- Output control
- Send a digest to Slack, email, or a sheet depending on the team's workflow.
- Privacy control
- Avoid processing sensitive messages unless the data policy allows it.
Recommended Steps
- Define the Gmail label or query that marks messages safe for summarization.
- Extract only the fields needed for context: sender, subject, snippet, date, and selected body text.
- Use OpenAI with a compact instruction that asks for action items, urgency, and a one-sentence summary.
- Format the summary with Set before sending it to Slack, Gmail, or a sheet.
- Test with short, long, and noisy email threads before enabling the schedule.
Verification
- Only labeled or query-matched emails enter the workflow.
- The prompt receives clean text and useful metadata.
- The output summary includes sender, topic, urgency, and action items.
- Sensitive fields are excluded from the final digest.
Warnings
- Do not summarize private or regulated emails without a clear data policy.
- Raw HTML and long threads can produce poor summaries unless cleaned first.
- Model output should be treated as a draft, not a guaranteed factual record.
Best For
- Daily inbox triage
- Lead or support email summaries
- Small teams that need a digest before deeper review
Not For
- Legal, medical, or regulated email processing without review
- Workflows that require guaranteed extraction accuracy without human checks
Common Mistakes
- Running the workflow over the entire inbox.
- Sending raw email HTML into the prompt.
- Forgetting to label safe messages before summarization.
- Treating model output as a final decision rather than a triage aid.
Examples
Schedule Trigger: every weekday morning
Gmail: find messages labeled summarize
Set: sender, subject, date, snippet, cleaned_text
OpenAI: summarize action items and urgency
Slack: post digest to team channel Importable Workflow Starter
openai-email-summary-starter.jsonStarter workflow for summarizing selected email text with OpenAI and posting the summary to a review destination. Node type names can vary by n8n version; verify after import.
Node order
- Manual/Webhook test input
- Set email fields
- OpenAI summary
- Set summary output
Credential checklist
- OpenAI credential configured in n8n.
- Optional Gmail/IMAP credential if replacing the manual input with a real mailbox trigger.
| Source field | Destination field | Notes |
|---|---|---|
| email.subject | summary title | Keep title short. |
| email.body | OpenAI prompt body | Strip signatures or quoted replies before production use. |
| email.messageId | dedupe key | Store before sending summaries. |
{
"name": "OpenAI email summary starter",
"nodes": [
{
"parameters": {},
"id": "Manual",
"name": "Manual Trigger",
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [
0,
0
]
},
{
"parameters": {
"keepOnlySet": true,
"values": {
"string": [
{
"name": "messageId",
"value": "msg_example_456"
},
{
"name": "subject",
"value": "Weekly vendor update"
},
{
"name": "body",
"value": "Replace this with sanitized email body text before calling OpenAI."
}
]
}
},
"id": "SetEmail",
"name": "Set email fields",
"type": "n8n-nodes-base.set",
"typeVersion": 2,
"position": [
240,
0
]
},
{
"parameters": {
"resource": "chat",
"operation": "complete",
"model": "REPLACE_WITH_MODEL",
"messages": {
"values": [
{
"role": "system",
"content": "Summarize operational email context without exposing secrets."
},
{
"role": "user",
"content": "={{\"Subject: \" + $json.subject + \"\\n\\nBody: \" + $json.body}}"
}
]
}
},
"id": "OpenAI",
"name": "Summarize with OpenAI",
"type": "@n8n/n8n-nodes-langchain.openAi",
"typeVersion": 1,
"position": [
480,
0
],
"credentials": {
"openAiApi": {
"id": "REPLACE_WITH_CREDENTIAL_ID",
"name": "REPLACE_WITH_OPENAI_CREDENTIAL"
}
}
},
{
"parameters": {
"keepOnlySet": true,
"values": {
"string": [
{
"name": "messageId",
"value": "={{$(\"Set email fields\").item.json.messageId}}"
},
{
"name": "summary",
"value": "={{$json.text || $json.message?.content || $json.choices?.[0]?.message?.content || \"Review OpenAI output shape\"}}"
}
]
}
},
"id": "SetSummary",
"name": "Set summary output",
"type": "n8n-nodes-base.set",
"typeVersion": 2,
"position": [
720,
0
]
}
],
"connections": {
"Manual Trigger": {
"main": [
[
{
"node": "Set email fields",
"type": "main",
"index": 0
}
]
]
},
"Set email fields": {
"main": [
[
{
"node": "Summarize with OpenAI",
"type": "main",
"index": 0
}
]
]
},
"Summarize with OpenAI": {
"main": [
[
{
"node": "Set summary output",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1"
},
"active": false,
"pinData": {},
"versionId": "replace-after-import"
} {
"messageId": "msg_example_456",
"subject": "Weekly vendor update",
"body": "Long email body goes here."
} {
"messageId": "msg_example_456",
"summary": "Short operational summary.",
"nextAction": "Review vendor dates."
} Failure paths
- Prompt includes private data that should be redacted.
- Output shape changes and downstream node expects a fixed key.
- OpenAI credential or model setting differs between environments.
Activation checklist
- Import into a non-production workflow first.
- Replace placeholder credential names and destination IDs.
- Run the minimal test payload with non-sensitive data.
- Confirm error paths do not leak secrets.
- Activate only after one successful end-to-end production-shaped test.
Duplicate prevention: Use a stable event ID, message ID, or payload hash in a datastore/sheet column before writing side effects.
{
"subject": "Smoke test",
"body": "Summarize this short email in one sentence."
} What to change before import
- Credential names and credential IDs.
- Slack channel, sheet ID, email labels, or other destination identifiers.
- Webhook path and response body.
- Any sample fields that differ from your payload.
FAQ
Can this summarize all unread email?
It can, but that is usually too broad. A label or query keeps privacy, noise, and cost easier to control.
Why are summaries vague?
The input may be mostly HTML, quoted thread text, or missing key context. Clean the text and pass structured metadata.