This workflow corresponds to n8n.io template #8358 — we link there as the canonical source.
This workflow follows the Chainsummarization → HTTP Request 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 →
{
"meta": {
"templateCredsSetupCompleted": true
},
"nodes": [
{
"id": "3b5b2708-da04-420a-aa33-498cd726ab8d",
"name": "Schedule Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
0,
-224
],
"parameters": {
"rule": {
"interval": [
{
"triggerAtHour": 20
}
]
}
},
"typeVersion": 1.2
},
{
"id": "602ac44e-3936-4cfe-81fc-0c89aa180904",
"name": "Discord",
"type": "n8n-nodes-base.discord",
"position": [
2272,
-224
],
"parameters": {
"files": {
"values": [
{}
]
},
"content": "= {{ $('separate text and markdown').item.json.plainText }}",
"options": {},
"authentication": "webhook"
},
"credentials": {
"discordWebhookApi": {
"name": "<your credential>"
}
},
"typeVersion": 2
},
{
"id": "cab9950b-4b4f-418b-ae4c-bd29a4966bb5",
"name": "OpenAI Chat Model1",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
880,
-64
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "gpt-4.1-mini"
},
"options": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "85dde31c-3895-4ece-bb8c-ee5f21f55c89",
"name": "HTTP Request",
"type": "n8n-nodes-base.httpRequest",
"position": [
1920,
-224
],
"parameters": {
"url": "={{ $json.url }}",
"options": {}
},
"typeVersion": 4.2
},
{
"id": "a49d8c5b-f638-4309-add4-7524c347e9cb",
"name": "Summarization Chain",
"type": "@n8n/n8n-nodes-langchain.chainSummarization",
"position": [
896,
-224
],
"parameters": {
"options": {
"summarizationMethodAndPrompts": {
"values": {
"prompt": "You will receive a collection of emails.\n\nSummarize them in **two formats**:\n\n1. **Plain Text Digest** \n - Use clear sentences. \n - Separate different senders with line breaks. \n - Keep it compact but readable. \n - Mention only the most important details (credentials, OTPs, deadlines, required actions). \n - Mark urgent items with [Action Required]. \n\n2. **Markdown Digest** \n - Use headings for senders. \n - Bullets for details. \n - Highlight actions with **[Action Required]**. \n\nHere are the emails:\n\n\"{text}\"\n\nNow output:\n\nPLAIN TEXT:\n...\n\nMARKDOWN:\n...\n",
"summarizationMethod": "stuff"
}
}
}
},
"typeVersion": 2.1
},
{
"id": "7f9ab61d-ffd9-477e-8886-2472e5d4a1ab",
"name": "PDFco Api",
"type": "n8n-nodes-pdfco.PDFco Api",
"position": [
1696,
-224
],
"parameters": {
"html": "={{ $json.data }}",
"operation": "URL/HTML to PDF",
"convertType": "htmlToPDF",
"advancedOptions": {}
},
"credentials": {
"pdfcoApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "156e95b9-c5c7-477d-b1a4-0c3545a56669",
"name": "Markdown",
"type": "n8n-nodes-base.markdown",
"position": [
1472,
-224
],
"parameters": {
"mode": "markdownToHtml",
"options": {},
"markdown": "=\n{{ $json.markdown }}"
},
"typeVersion": 1
},
{
"id": "190586e3-685c-4c95-87f1-882dba9e54ca",
"name": "Aggregate",
"type": "n8n-nodes-base.aggregate",
"position": [
672,
-224
],
"parameters": {
"include": "specifiedFields",
"options": {},
"aggregate": "aggregateAllItemData",
"fieldsToInclude": "subject, from, plainText"
},
"typeVersion": 1
},
{
"id": "9c7247ee-9811-4ad4-bb4a-bbc53a23ab38",
"name": "extract required sections from mails",
"type": "n8n-nodes-base.code",
"position": [
448,
-224
],
"parameters": {
"jsCode": "// n8n Code node (JavaScript)\n\n// Helper: decode Gmail's base64url\nfunction decodeBase64Url(str) {\n if (!str) return \"\";\n str = str.replace(/-/g, '+').replace(/_/g, '/');\n return Buffer.from(str, 'base64').toString('utf8');\n}\n\n// Helper: clean text\nfunction cleanText(txt) {\n if (!txt) return \"\";\n\n return txt\n // remove long URLs\n .replace(/https?:\\/\\/\\S+/g, \"\")\n // remove multiple stars/dashes\n .replace(/[*]{3,}|[-]{3,}/g, \"\")\n // remove extra blank lines\n .replace(/\\n\\s*\\n\\s*\\n+/g, \"\\n\\n\")\n // trim\n .trim();\n}\n\nconst items = $input.all();\nconst returnData = [];\n\nfor (let i = 0; i < items.length; i++) {\n const email = items[i].json;\n let plainText = \"\";\n\n // Case 1: direct body\n if (email?.payload?.body?.data) {\n plainText = decodeBase64Url(email.payload.body.data);\n }\n\n // Case 2: multipart body\n if (!plainText && Array.isArray(email?.payload?.parts)) {\n for (const part of email.payload.parts) {\n if (part.mimeType === \"text/plain\" && part.body?.data) {\n plainText = decodeBase64Url(part.body.data);\n break;\n }\n }\n }\n\n // Fallback if you already had email.text\n if (!plainText && email.text) {\n plainText = email.text;\n }\n\n const extractedData = {\n id: email.id || \"\",\n subject: email.subject || email.payload?.headers?.find(h => h.name === \"Subject\")?.value || \"\",\n from: email.from?.text || email.from || email.payload?.headers?.find(h => h.name === \"From\")?.value || \"\",\n to: email.to?.text || email.to || email.payload?.headers?.find(h => h.name === \"To\")?.value || \"\",\n plainText: cleanText(plainText),\n };\n\n returnData.push({ json: extractedData });\n}\n\nreturn returnData;\n"
},
"typeVersion": 2
},
{
"id": "157ef58a-86fa-41fc-96d4-b058684d513f",
"name": "get mails from past 24 h",
"type": "n8n-nodes-base.gmail",
"position": [
224,
-224
],
"parameters": {
"simple": false,
"filters": {
"labelIds": [
"INBOX",
"IMPORTANT"
],
"receivedAfter": "={{$now.minus({days: 1}).toISO()}}"
},
"options": {},
"operation": "getAll",
"returnAll": true
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "0df5a671-79aa-4c7d-bbd7-296a214b4c9c",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
416,
-368
],
"parameters": {
"width": 400,
"height": 320,
"content": "## extract fields and aggregate\n- sender\n- subject\n- body"
},
"typeVersion": 1
},
{
"id": "5a0a95ad-14a7-484a-94c2-ef6a582151fa",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
176,
-304
],
"parameters": {
"width": 208,
"height": 208,
"content": "## get mails\n- Important and inbox"
},
"typeVersion": 1
},
{
"id": "2335cdb8-b1e1-4d7c-98f7-e84dfec2e4c0",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-64,
-320
],
"parameters": {
"width": 192,
"height": 256,
"content": "## daily trigger"
},
"typeVersion": 1
},
{
"id": "b82da96e-aa95-45fd-b13e-51f998143f6c",
"name": "separate text and markdown",
"type": "n8n-nodes-base.code",
"position": [
1248,
-224
],
"parameters": {
"jsCode": "const output = $json[\"output\"][\"text\"];\n\n// Match plain text - works for both \"PLAIN TEXT\" and \"PLAIN TEXT DIGEST\"\nconst plainText = output.match(/PLAIN TEXT(?: DIGEST)?:\\s*([\\s\\S]*?)(?:\\n\\n---\\n\\nMARKDOWN DIGEST:|\\n\\nMARKDOWN:)/)?.[1]?.trim();\n\n// Match markdown - works for both \"MARKDOWN\" and \"MARKDOWN DIGEST\"\nconst markdown = output.match(/MARKDOWN(?: DIGEST)?:\\s*([\\s\\S]*)/)?.[1]?.trim();\n\nreturn [{\n plainText,\n markdown\n}];\n"
},
"typeVersion": 2
},
{
"id": "44150497-0310-40d3-bb8d-8bd7624ab4c1",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
832,
-384
],
"parameters": {
"width": 320,
"height": 480,
"content": "## summarize all mails\n- ### model used gpt 4o-mini"
},
"typeVersion": 1
},
{
"id": "e77850b7-6d9c-44da-8c36-33ab2cac645f",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
1392,
-304
],
"parameters": {
"width": 432,
"height": 240,
"content": "## convert markdown to html and convert html to pdf using PDFco Api"
},
"typeVersion": 1
},
{
"id": "24c297f1-9195-43e2-b27d-208aaad5b518",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
1856,
-400
],
"parameters": {
"height": 336,
"content": "## Download PDF\n- ### using link generated from pdfco"
},
"typeVersion": 1
},
{
"id": "31e1f02c-4b0a-49c6-ad17-3d8bef1fc35c",
"name": "Sticky Note6",
"type": "n8n-nodes-base.stickyNote",
"position": [
2192,
-352
],
"parameters": {
"width": 336,
"height": 304,
"content": "## Send discord\n- using webhook\n- result will contain summary and a pdf of summary"
},
"typeVersion": 1
}
],
"connections": {
"Markdown": {
"main": [
[
{
"node": "PDFco Api",
"type": "main",
"index": 0
}
]
]
},
"Aggregate": {
"main": [
[
{
"node": "Summarization Chain",
"type": "main",
"index": 0
}
]
]
},
"PDFco Api": {
"main": [
[
{
"node": "HTTP Request",
"type": "main",
"index": 0
}
]
]
},
"HTTP Request": {
"main": [
[
{
"node": "Discord",
"type": "main",
"index": 0
}
]
]
},
"Schedule Trigger": {
"main": [
[
{
"node": "get mails from past 24 h",
"type": "main",
"index": 0
}
]
]
},
"OpenAI Chat Model1": {
"ai_languageModel": [
[
{
"node": "Summarization Chain",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Summarization Chain": {
"main": [
[
{
"node": "separate text and markdown",
"type": "main",
"index": 0
}
]
]
},
"get mails from past 24 h": {
"main": [
[
{
"node": "extract required sections from mails",
"type": "main",
"index": 0
}
]
]
},
"separate text and markdown": {
"main": [
[
{
"node": "Markdown",
"type": "main",
"index": 0
}
]
]
},
"extract required sections from mails": {
"main": [
[
{
"node": "Aggregate",
"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.
discordWebhookApigmailOAuth2openAiApipdfcoApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow contains community nodes that are only compatible with the self-hosted version of n8n.
Source: https://n8n.io/workflows/8358/ — 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 workflow is ideal for HR professionals, recruiters, and small businesses looking to streamline resume screening with AI-powered analysis and CRM integration.
Deduplicate Scraping Ai Grants For Eligibility Using Ai. Uses splitOut, httpRequest, lmChatOpenAi, informationExtractor. Scheduled trigger; 24 nodes.
This n8n template scrapes a list of AI grants from grants.gov and qualifies them using AI; determining interest and eligibility for the business. It then sends an email alert of interesting items to t
Sign up for Decodo — get better pricing here
gmail label and notify. Uses lmChatOpenAi, textClassifier, gmail, openAi. Scheduled trigger; 16 nodes.