This workflow corresponds to n8n.io template #7162 — we link there as the canonical source.
This workflow follows the Chainllm → Chainsummarization 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": "twvLZRSedaF7hjy2",
"name": "Reddit Daily Hot Posts \u2192 Gmail Digest (Multi-Subreddit, AI Summaries)",
"tags": [],
"nodes": [
{
"id": "143de7a4-65e3-431c-96b2-1ac4aefff128",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
880,
-464
],
"parameters": {
"width": 1328,
"height": 544,
"content": "## Retrieve daily hot subreddit posts"
},
"typeVersion": 1
},
{
"id": "447db4d5-fb68-4035-b6c8-87b40f829c24",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
432,
-464
],
"parameters": {
"color": 5,
"width": 256,
"height": 544,
"content": "## Set subreddits you wish to track"
},
"typeVersion": 1
},
{
"id": "a20dd531-ea12-4dbb-86e0-4ae6d0fc0a22",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
2448,
-656
],
"parameters": {
"width": 1760,
"height": 496,
"content": "## Process each post"
},
"typeVersion": 1
},
{
"id": "0b9096aa-22c9-4487-889a-af55ab509f20",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
2448,
16
],
"parameters": {
"width": 1904,
"height": 736,
"content": "## Summarizes each post and sends to your inbox"
},
"typeVersion": 1
},
{
"id": "fce66882-b289-4bd5-829b-104188cc9974",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
160,
-464
],
"parameters": {
"color": 5,
"width": 256,
"height": 544,
"content": "## Set interval in which you which to receive newsletter in your inbox"
},
"typeVersion": 1
},
{
"id": "806fef98-e4a9-4b7d-8eb7-ae5aa4e75829",
"name": "Schedule: Daily run",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
240,
-192
],
"parameters": {
"rule": {
"interval": [
{
"triggerAtHour": 6
}
]
}
},
"typeVersion": 1.2
},
{
"id": "bd33313a-7409-4bb2-ba68-47528d416624",
"name": "Split Subreddit List",
"type": "n8n-nodes-base.splitOut",
"position": [
736,
-192
],
"parameters": {
"options": {
"destinationFieldName": "subreddit"
},
"fieldToSplitOut": "subreddits"
},
"typeVersion": 1
},
{
"id": "6eb61b05-f1bf-47b0-99f5-5734838fa92e",
"name": "List Hot Posts",
"type": "n8n-nodes-base.reddit",
"position": [
928,
-192
],
"parameters": {
"filters": {
"category": "hot"
},
"operation": "getAll",
"returnAll": true,
"subreddit": "={{ $json.subreddit }}"
},
"credentials": {
"redditOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "b9eb5d1f-4a0b-4db9-9063-1fc7c8358ed4",
"name": "Attach ISO Date to Posts1",
"type": "n8n-nodes-base.merge",
"position": [
1376,
-192
],
"parameters": {
"mode": "combine",
"options": {},
"combineBy": "combineByPosition"
},
"typeVersion": 3.2
},
{
"id": "573e28e0-521a-4f8f-8c00-1a5fc0d2d1f0",
"name": "Normalize Post Date (created_utc \u2192 ISO)",
"type": "n8n-nodes-base.set",
"position": [
1152,
-272
],
"parameters": {
"options": {
"ignoreConversionErrors": true
},
"assignments": {
"assignments": [
{
"id": "4430b889-070a-4fc0-870f-99abfc8358f4",
"name": "created_iso",
"type": "string",
"value": "={{ \n (() => {\n const ts = Number($json.created_utc); // Reddit = seconds\n const ms = ts > 1e12 ? ts : ts * 1000;\n return new Date(ms).toISOString(); // e.g. \"2025-07-14T15:25:27.000Z\"\n })() \n}}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "737f2bc8-c044-4956-b561-57fb9e0cc59e",
"name": "Select Fields (id, score, url, date, subreddit)",
"type": "n8n-nodes-base.set",
"position": [
1600,
-192
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "76648d06-3f14-4b5f-9f8f-96db17245efd",
"name": "subreddit",
"type": "string",
"value": "={{ $json.subreddit }}"
},
{
"id": "c91431ae-68b9-4a47-966f-d20a4115e912",
"name": "id",
"type": "string",
"value": "={{ $json.id }}"
},
{
"id": "610a5fb8-3620-4a40-9217-8aedb8882e3e",
"name": "date",
"type": "string",
"value": "={{ $json.created_iso }}"
},
{
"id": "11155f65-05cf-4a2c-852d-b318be54271a",
"name": "score",
"type": "number",
"value": "={{ $json.score }}"
},
{
"id": "fd9a0200-08ed-40f1-b9b7-733ee22aa0a6",
"name": "url",
"type": "string",
"value": "={{ $json.url }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "8ee37fa1-dac3-40ee-84cf-9ec997cc8dab",
"name": "Filter: Last 24h & Score > 30",
"type": "n8n-nodes-base.filter",
"position": [
1824,
-192
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "1f69ceb7-48ec-47e9-af5c-60ddb9e84f93",
"operator": {
"type": "dateTime",
"operation": "afterOrEquals"
},
"leftValue": "={{ $json.date }}",
"rightValue": "={{ new Date(new Date($now).getTime() - 24 * 60 * 60 * 1000).toISOString() }}"
},
{
"id": "3081a1f6-5405-4389-b6a3-a70210821b1f",
"operator": {
"type": "number",
"operation": "gt"
},
"leftValue": "={{ $json.score }}",
"rightValue": 30
}
]
}
},
"typeVersion": 2.2
},
{
"id": "3859d2ae-dea4-49b9-b087-c5e6a5405b1f",
"name": "Sort by Score (desc)",
"type": "n8n-nodes-base.sort",
"position": [
2048,
-192
],
"parameters": {
"options": {},
"sortFieldsUi": {
"sortField": [
{
"order": "descending",
"fieldName": "score"
}
]
}
},
"typeVersion": 1
},
{
"id": "bb18c422-097b-4e64-bbfe-64049f487920",
"name": "Iterate Posts (single batch)",
"type": "n8n-nodes-base.splitInBatches",
"position": [
2256,
-192
],
"parameters": {
"options": {},
"batchSize": "={{ $input.all().length }}"
},
"typeVersion": 3
},
{
"id": "482ae953-738b-4aec-a66c-cacc162a9a44",
"name": "Get Post by ID",
"type": "n8n-nodes-base.reddit",
"position": [
2496,
-480
],
"parameters": {
"postId": "={{ $json.id }}",
"operation": "get",
"subreddit": "={{ $json.subreddit }}"
},
"credentials": {
"redditOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "5cfd61e4-6928-445c-a148-2c8ac8accb27",
"name": "Deduplicate by ID",
"type": "n8n-nodes-base.removeDuplicates",
"position": [
2720,
-480
],
"parameters": {
"compare": "selectedFields",
"options": {},
"fieldsToCompare": "id"
},
"typeVersion": 2
},
{
"id": "26d7e22f-14bd-4320-bb56-1e9d69ad367d",
"name": "Build Post Body (root)",
"type": "n8n-nodes-base.code",
"position": [
2944,
-480
],
"parameters": {
"jsCode": "/**\n * Build one n8n item per Reddit post that arrives on the input.\n * Run mode: \u201cRun Once for All Items\u201d\n */\nreturn $input.all().map(({ json: p }) => {\n // \u2500\u2500\u2500 convert epoch-seconds \u2192 YYYY-MM-DD (UTC) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const createdUtcDate =\n (typeof p.created_utc === 'number')\n ? new Date(p.created_utc * 1000).toISOString().slice(0, 10) // \"YYYY-MM-DD\"\n : null; // fallback if field missing\n\n return {\n json: {\n /* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 identifiers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n post_id : p.id || (p.name ? p.name.replace('t3_', '') : null),\n comment_id: null, // post has no comment_id\n parent_id : null,\n\n /* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 text & author \u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n body : `${p.title || ''}${p.selftext ? '\\n\\n' + p.selftext : ''}`,\n author : p.author,\n score : p.score,\n\n /* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 context \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n depth : -1, // reserve \u20131 for the root post\n subreddit : p.subreddit,\n permalink : `https://reddit.com${p.permalink}`,\n\n /* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 timestamps \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n created_utc: createdUtcDate, // e.g. \"2024-07-01\"\n\n /* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 metadata \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n chunk_type: 'post' // post | comment | reply\n }\n };\n});"
},
"typeVersion": 2
},
{
"id": "5ef14e2a-04a9-4419-8831-da9128cc1740",
"name": "List Top-level Comments",
"type": "n8n-nodes-base.reddit",
"position": [
3168,
-416
],
"parameters": {
"postId": "={{ $json.post_id }}",
"resource": "postComment",
"operation": "getAll",
"subreddit": "={{ $json.subreddit }}"
},
"credentials": {
"redditOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "861258dc-6bac-489f-a99a-31753c197b20",
"name": "Flatten Comment Threads",
"type": "n8n-nodes-base.code",
"position": [
3392,
-416
],
"parameters": {
"jsCode": "/* ---------- helper ---------- */\nfunction walkChildren(node, store, depth = 0, sub) {\n if (!node || node.kind !== 't1') return;\n const d = node.data;\n\n /* convert epoch-seconds \u2192 YYYY-MM-DD (UTC) */\n const createdUtcDate =\n (typeof d.created_utc === 'number')\n ? new Date(d.created_utc * 1000).toISOString().slice(0, 10)\n : null;\n \n store.push({\n post_id : d.link_id?.replace('t3_',''),\n comment_id: d.name,\n parent_id : d.parent_id,\n body : d.body || '',\n author : d.author,\n score : d.score,\n depth,\n subreddit : sub, \n permalink : `https://reddit.com${d.permalink}`,\n created_utc: createdUtcDate \n });\n\n (d.replies?.data?.children || [])\n .forEach(c => walkChildren(c, store, depth+1, sub));\n}\n\n/* ---------- main ---------- */\nconst flat = [];\nitems.forEach(item => {\n const root = item.json;\n const sub = root.subreddit; // NEW\n walkChildren({ kind:'t1', data: root }, flat, 0, sub);\n});\nreturn flat.map(o => ({ json:o }));\n"
},
"typeVersion": 2
},
{
"id": "a82e836e-f97b-4fb2-8fd6-332cb226e92a",
"name": "Filter: Valid Comments",
"type": "n8n-nodes-base.filter",
"position": [
3616,
-416
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "0f7812db-c828-4389-8dd4-37ab54c626ad",
"operator": {
"type": "string",
"operation": "notEmpty",
"singleValue": true
},
"leftValue": "={{ $json.post_id }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2
},
{
"id": "22338a1a-f650-432a-a1af-e3119946f3a3",
"name": "Append Posts + Comments",
"type": "n8n-nodes-base.merge",
"position": [
3840,
-480
],
"parameters": {},
"typeVersion": 3.2
},
{
"id": "3541c2bc-a535-45b6-a0a8-138bdbff2b31",
"name": "Build Thread Text",
"type": "n8n-nodes-base.code",
"position": [
4064,
-480
],
"parameters": {
"jsCode": "/**\n * n8n Code node \u25b8 build a stringified Reddit-style comment thread\n *\n * Works with both \"old\" (object_id, parent_id t1_/t3_) and \"new\" (post_id, comment_id, chunk_type) schemas.\n *\n * Input : items[] each item.json has some mix of:\n * { uid?, object_id?, post_id?, comment_id?, parent_uid?, parent_id?, chunk_type?, body, created_utc }\n * Output : items[] one per root post:\n * {\n * post_id: \"1dsmdb7\",\n * thread_text: \"POST: ...\\n- top-level\\n - reply\\n\"\n * }\n */\n\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst stripPrefix = id => {\n if (!id) return null;\n // accept fullnames t1_, t3_, t4_ etc\n return String(id).replace(/^t[0-9]_/, '');\n};\n\nconst clean = txt => (txt || '').replace(/\\s*\\n\\s*/g, ' ').trim();\n\n// Decide canonical UID for this row\nconst getUID = j => {\n if (j.uid) return String(j.uid);\n if (j.comment_id) return stripPrefix(j.comment_id);\n if (j.object_id) return stripPrefix(j.object_id);\n // Fallback: posts sometimes only have post_id\n if (j.post_id) return stripPrefix(j.post_id);\n return null;\n};\n\n// Decide canonical parent UID\nconst getParentUID = j => {\n if (j.parent_uid) return String(j.parent_uid);\n if (j.parent_id) return stripPrefix(j.parent_id);\n\n // New export case:\n // chunk_type === \"comment\" (or depth >=0) but parent_id missing -> assume post_id is parent\n const isPost = (j.chunk_type === 'post') || (j.depth != null && Number(j.depth) < 0);\n if (!isPost && j.post_id) return stripPrefix(j.post_id);\n\n // Root posts -> null\n return null;\n};\n\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 1. build node map \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst map = new Map(); // uid -> node\nconst roots = [];\n\nfor (const it of items) {\n const j = it.json;\n if (!j.body || !j.body.trim()) continue; // skip empty\n\n const uid = getUID(j);\n if (!uid) continue; // cannot index, skip row\n\n const parent_uid = getParentUID(j);\n\n const node = {\n uid,\n parent_uid,\n body: clean(j.body),\n created: j.created_utc,\n children: [],\n // keep raw fields if needed downstream\n _raw: j,\n };\n\n map.set(uid, node);\n}\n\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 2. link parents & children \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nfor (const node of map.values()) {\n if (node.parent_uid && map.has(node.parent_uid)) {\n map.get(node.parent_uid).children.push(node);\n } else {\n // no known parent in this batch -> treat as root post\n roots.push(node);\n }\n}\n\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 2b. ensure posts sorted before comments when multiple roots\n// optional: group by original post_id if available\n// (skip if you are happy letting multiple orphan comments become separate roots)\n\n// sort children chronologically\nconst byDate = (a, b) => {\n const da = a.created ? new Date(a.created).getTime() : 0;\n const db = b.created ? new Date(b.created).getTime() : 0;\n return da - db;\n};\nconst sortTree = n => { n.children.sort(byDate); n.children.forEach(sortTree); };\nroots.forEach(sortTree);\n\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 3. stringify the thread \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst buildString = (n, indent = '') => {\n const prefix = indent ? '- ' : 'POST: ';\n let out = indent + prefix + n.body + '\\n';\n for (const c of n.children) out += buildString(c, indent + ' ');\n return out;\n};\n\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 4. emit one item per root \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nreturn roots.map(r => ({\n json: {\n post_id: r._raw?.post_id || r.uid,\n thread_text: buildString(r).trim(),\n },\n}));"
},
"typeVersion": 2
},
{
"id": "54d0d414-a002-44b7-b1b7-7980782165dc",
"name": "Merge: Thread + Post Details",
"type": "n8n-nodes-base.merge",
"position": [
4288,
-416
],
"parameters": {
"mode": "combine",
"options": {},
"combineBy": "combineByPosition"
},
"typeVersion": 3.2
},
{
"id": "3c37fad6-9320-408b-9686-92337dca5d3a",
"name": "Set (id, thread_text, link)",
"type": "n8n-nodes-base.set",
"position": [
4512,
-256
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "0c77ff7e-681e-43e1-a70e-09ddac37d6a5",
"name": "id",
"type": "string",
"value": "={{ $json.id }}"
},
{
"id": "e1f70c7c-98c6-4da8-86a4-6e6fc19c018e",
"name": "thread_text",
"type": "string",
"value": "={{ $json.thread_text }}"
},
{
"id": "5b65a8d5-88c5-4d0e-81d5-e873a751d38c",
"name": "link",
"type": "string",
"value": "={{ $json.url }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "85340b98-fcdb-4251-8dc8-551e81d0a2f3",
"name": "Call Sub-workflow: Summarize & Email",
"type": "n8n-nodes-base.executeWorkflow",
"position": [
2512,
96
],
"parameters": {
"options": {},
"workflowId": {
"__rl": true,
"mode": "id",
"value": "twvLZRSedaF7hjy2"
},
"workflowInputs": {
"value": {
"id": "={{ $json.id }}",
"link": "={{ $json.link }}",
"email": "={{ $('Set Topic, Subreddits and Email Address').first().json.email }}",
"topic": "={{ $('Set Topic, Subreddits and Email Address').first().json['topic'] }}",
"thread_text": "={{ $json.thread_text }}"
},
"schema": [
{
"id": "topic",
"type": "string",
"display": true,
"required": false,
"displayName": "topic",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "id",
"type": "string",
"display": true,
"required": false,
"displayName": "id",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "thread_text",
"type": "string",
"display": true,
"required": false,
"displayName": "thread_text",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "link",
"type": "string",
"display": true,
"required": false,
"displayName": "link",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "email",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "email",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": true
}
},
"typeVersion": 1.2
},
{
"id": "0911fcd5-3fa1-44f9-88ae-852939c26bf5",
"name": "Sub-workflow Trigger",
"type": "n8n-nodes-base.executeWorkflowTrigger",
"position": [
2512,
368
],
"parameters": {
"workflowInputs": {
"values": [
{
"name": "topic"
},
{
"name": "id"
},
{
"name": "thread_text"
},
{
"name": "link"
},
{
"name": "email"
}
]
}
},
"typeVersion": 1.1
},
{
"id": "5ca4c51f-bd8c-4861-bf2f-26d4bcf343e1",
"name": "Extract Link",
"type": "n8n-nodes-base.set",
"position": [
3040,
272
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "a8042f2e-2fdc-4209-bbeb-4c4a689c651f",
"name": "link",
"type": "string",
"value": "={{ $json.link }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "d315e9d1-993d-444b-abae-8d23a77a8000",
"name": "Extract Thread Text",
"type": "n8n-nodes-base.set",
"position": [
2736,
464
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "c66e0f4a-9293-4283-828c-85859225b231",
"name": "thread_text",
"type": "string",
"value": "={{ $json.thread_text }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "148cdd3b-679a-4ec7-ac5e-61b1775d6465",
"name": "GPT-4o mini",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
"position": [
3904,
592
],
"parameters": {
"model": "openai/gpt-4o-mini",
"options": {}
},
"credentials": {
"openRouterApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "8bb8fddb-de27-4a35-a6e5-9045daf856dd",
"name": "Summarize Threads",
"type": "@n8n/n8n-nodes-langchain.chainSummarization",
"position": [
2960,
464
],
"parameters": {
"options": {}
},
"typeVersion": 2.1
},
{
"id": "c0f55602-75a0-4783-b6a4-dd21a03486d4",
"name": "Combine Summaries + Links",
"type": "n8n-nodes-base.merge",
"position": [
3360,
368
],
"parameters": {
"mode": "combine",
"options": {},
"combineBy": "combineByPosition"
},
"typeVersion": 3.2
},
{
"id": "9f8ecb80-43e2-477c-a727-18a9c5463bd5",
"name": "Aggregate Summaries & Links",
"type": "n8n-nodes-base.aggregate",
"position": [
3584,
368
],
"parameters": {
"options": {},
"fieldsToAggregate": {
"fieldToAggregate": [
{
"fieldToAggregate": "output.text"
},
{
"fieldToAggregate": "link"
}
]
}
},
"typeVersion": 1
},
{
"id": "de10067c-e42e-4f75-ad61-92a190422d54",
"name": "Format HTML for Gmail",
"type": "@n8n/n8n-nodes-langchain.chainLlm",
"position": [
3808,
368
],
"parameters": {
"text": "=## INPUT:\nYou will receive:\n- `text`: a JSON array of Reddit thread summaries\n- `link`: a JSON array of Reddit post URLs\n\nThese arrays are of equal length, and `text[n]` corresponds to `link[n]`.\n\n## TASK:\nFormat the matched items into **HTML** for a Gmail-compatible email. Use the structure below:\n\n```\n\n<h1>Summary</h1>\n\n<h2>Summarized One-liner Title from TEXT_1</h2>\n<p>TEXT_1</p>\n<p><a href=\"LINK_1\">View Reddit Thread</a></p>\n\n<br /><br />\n\n<h2>Summarized One-liner Title from TEXT_2</h2>\n<p>TEXT_2</p>\n<p><a href=\"LINK_2\">View Reddit Thread</a></p>\n\n... and so on\n\n```\n\n## RULES:\n- Do NOT wrap the entire thing in `<html>` or `<body>`.\n- Ensure proper spacing and line breaks between sections using `<p>` or `<br />`.\n- Hyperlink formatting must be clean and click-friendly.\n- All content must be Gmail-safe (no external CSS, JS, or fancy HTML).\n- DO NOT include any extraneous commentary or explanation \u2014 just return the HTML block.\n\n## INPUT:\nList of summarized reddit threads: {{ $json.text }}\n\nList of reddit links: {{ $json.link }}\n\nReturn the result as clean HTML only.\n",
"batching": {},
"messages": {
"messageValues": [
{
"message": "=You are a world-class AI tasked with formatting content for HTML email rendering in Gmail."
}
]
},
"promptType": "define"
},
"typeVersion": 1.7
},
{
"id": "c4dbcf94-b82f-47f3-9185-1b1e3ae1911a",
"name": "Send Digest",
"type": "n8n-nodes-base.gmail",
"position": [
4208,
368
],
"parameters": {
"sendTo": "={{ $('Sub-workflow Trigger').first().json.email }}",
"message": "={{ $json.text }}",
"options": {
"appendAttribution": false
},
"subject": "={{ $('Sub-workflow Trigger').first().json.topic }} {{ 'Daily Digest' }}"
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "d7d8c4bc-a9bc-4c1f-8046-890611abfaee",
"name": "Set Topic, Subreddits and Email Address",
"type": "n8n-nodes-base.set",
"position": [
512,
-192
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "b62e1476-3762-49dc-ac77-fd676bf7aa61",
"name": "topic",
"type": "string",
"value": "Investing"
},
{
"id": "fc74917a-193d-44fd-879e-c3c6e2156c67",
"name": "subreddits",
"type": "array",
"value": "=[\"investing\", \"stocks\"]"
},
{
"id": "673498be-f268-44aa-8f3a-da75cc8bd50d",
"name": "email",
"type": "string",
"value": "user@example.com"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "99d1e0af-32e9-4e33-a40d-642db28d3d6f",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
-656,
-544
],
"parameters": {
"color": 5,
"width": 624,
"height": 256,
"content": "\n**Start here (required settings)**\n\n* **1) Schedule**: Open **Schedule Trigger** and choose your run time. If times look off, set **Workflow Settings \u2192 Timezone**.\n* **2) Topic and subreddits**: Open **Set Topic & Subreddits** and set:\n\n * `topic`: a short label for your digest (example: Investing)\n * `subreddits`: array of subreddit names (example: `[\"investing\",\"stocks\"]`)\n * `email`: your gmail (example: john@gmail.com)"
},
"typeVersion": 1
},
{
"id": "88a4e517-fc50-4128-8160-e0acd34ea87b",
"name": "Sticky Note6",
"type": "n8n-nodes-base.stickyNote",
"position": [
-656,
-256
],
"parameters": {
"width": 624,
"height": 176,
"content": "\n**What this workflow does**\n\n* Fetch **hot** posts per subreddit, normalize dates, filter to **last 24h** and **score > 30**, then sort by score.\n* Build a **thread text** from the post and main comments.\n* **Summarize** each thread with an LLM and **send one Gmail digest**.\n"
},
"typeVersion": 1
},
{
"id": "f4c542ec-a961-4e0e-b913-accbb5544c80",
"name": "Sticky Note7",
"type": "n8n-nodes-base.stickyNote",
"position": [
-656,
-48
],
"parameters": {
"width": 624,
"height": 208,
"content": "**Customize**\n\n* Change score threshold in **Filter: Last 24h & Score > 30**.\n* Add or remove subreddits anytime in **Set Topic, Subreddits, and Email Address**.\n* To reduce email length, place a **Limit** node before summarization.\n* Respect Reddit API and Gmail limits if you scale up."
},
"typeVersion": 1
},
{
"id": "7f1dffb8-95eb-4949-aa18-9c1efd7ae820",
"name": "Sticky Note8",
"type": "n8n-nodes-base.stickyNote",
"position": [
-656,
192
],
"parameters": {
"width": 624,
"height": 560,
"content": "## Start here: Step-by Step Youtube Tutorial :star:\nWatch this to ensure you configure the workflow correctly\n\n[](https://youtu.be/H6tMJ0-a9RY)\n"
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"timezone": "Asia/Singapore",
"callerPolicy": "workflowsFromSameOwner",
"executionOrder": "v1"
},
"versionId": "de790c1b-fe57-4962-8b0e-6fb74880e57b",
"connections": {
"GPT-4o mini": {
"ai_languageModel": [
[
{
"node": "Summarize Threads",
"type": "ai_languageModel",
"index": 0
},
{
"node": "Format HTML for Gmail",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Extract Link": {
"main": [
[
{
"node": "Combine Summaries + Links",
"type": "main",
"index": 1
}
]
]
},
"Get Post by ID": {
"main": [
[
{
"node": "Deduplicate by ID",
"type": "main",
"index": 0
}
]
]
},
"List Hot Posts": {
"main": [
[
{
"node": "Normalize Post Date (created_utc \u2192 ISO)",
"type": "main",
"index": 0
},
{
"node": "Attach ISO Date to Posts1",
"type": "main",
"index": 1
}
]
]
},
"Build Thread Text": {
"main": [
[
{
"node": "Merge: Thread + Post Details",
"type": "main",
"index": 0
}
]
]
},
"Deduplicate by ID": {
"main": [
[
{
"node": "Build Post Body (root)",
"type": "main",
"index": 0
}
]
]
},
"Summarize Threads": {
"main": [
[
{
"node": "Combine Summaries + Links",
"type": "main",
"index": 0
}
]
]
},
"Extract Thread Text": {
"main": [
[
{
"node": "Summarize Threads",
"type": "main",
"index": 0
}
]
]
},
"Schedule: Daily run": {
"main": [
[
{
"node": "Set Topic, Subreddits and Email Address",
"type": "main",
"index": 0
}
]
]
},
"Sort by Score (desc)": {
"main": [
[
{
"node": "Iterate Posts (single batch)",
"type": "main",
"index": 0
}
]
]
},
"Split Subreddit List": {
"main": [
[
{
"node": "List Hot Posts",
"type": "main",
"index": 0
}
]
]
},
"Sub-workflow Trigger": {
"main": [
[
{
"node": "Extract Link",
"type": "main",
"index": 0
},
{
"node": "Extract Thread Text",
"type": "main",
"index": 0
}
]
]
},
"Format HTML for Gmail": {
"main": [
[
{
"node": "Send Digest",
"type": "main",
"index": 0
}
]
]
},
"Build Post Body (root)": {
"main": [
[
{
"node": "Append Posts + Comments",
"type": "main",
"index": 0
},
{
"node": "List Top-level Comments",
"type": "main",
"index": 0
}
]
]
},
"Filter: Valid Comments": {
"main": [
[
{
"node": "Append Posts + Comments",
"type": "main",
"index": 1
}
]
]
},
"Append Posts + Comments": {
"main": [
[
{
"node": "Build Thread Text",
"type": "main",
"index": 0
}
]
]
},
"Flatten Comment Threads": {
"main": [
[
{
"node": "Filter: Valid Comments",
"type": "main",
"index": 0
}
]
]
},
"List Top-level Comments": {
"main": [
[
{
"node": "Flatten Comment Threads",
"type": "main",
"index": 0
}
]
]
},
"Attach ISO Date to Posts1": {
"main": [
[
{
"node": "Select Fields (id, score, url, date, subreddit)",
"type": "main",
"index": 0
}
]
]
},
"Combine Summaries + Links": {
"main": [
[
{
"node": "Aggregate Summaries & Links",
"type": "main",
"index": 0
}
]
]
},
"Aggregate Summaries & Links": {
"main": [
[
{
"node": "Format HTML for Gmail",
"type": "main",
"index": 0
}
]
]
},
"Set (id, thread_text, link)": {
"main": [
[
{
"node": "Iterate Posts (single batch)",
"type": "main",
"index": 0
}
]
]
},
"Iterate Posts (single batch)": {
"main": [
[
{
"node": "Call Sub-workflow: Summarize & Email",
"type": "main",
"index": 0
}
],
[
{
"node": "Merge: Thread + Post Details",
"type": "main",
"index": 1
},
{
"node": "Get Post by ID",
"type": "main",
"index": 0
}
]
]
},
"Merge: Thread + Post Details": {
"main": [
[
{
"node": "Set (id, thread_text, link)",
"type": "main",
"index": 0
}
]
]
},
"Filter: Last 24h & Score > 30": {
"main": [
[
{
"node": "Sort by Score (desc)",
"type": "main",
"index": 0
}
]
]
},
"Set Topic, Subreddits and Email Address": {
"main": [
[
{
"node": "Split Subreddit List",
"type": "main",
"index": 0
}
]
]
},
"Normalize Post Date (created_utc \u2192 ISO)": {
"main": [
[
{
"node": "Attach ISO Date to Posts1",
"type": "main",
"index": 0
}
]
]
},
"Select Fields (id, score, url, date, subreddit)": {
"main": [
[
{
"node": "Filter: Last 24h & Score > 30",
"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.
gmailOAuth2openRouterApiredditOAuth2Api
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
What it does
Source: https://n8n.io/workflows/7162/ — 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 workflow template creates a comprehensive AI-powered mock interview system that conducts voice-based interviews, provides real-time transcription, and generates detailed performance assessmen
Professionals and individuals who receive high volumes of emails, those who want to automatically organize their Gmail inbox using AI classification.
This workflow automates the backup of all your n8n workflows to a specified Google Drive folder. It operates in two main phases: Orchestration (Scheduled Task): The workflow is initiated by a Schedule
Alrouf AI Integration (Production). Uses googleSheets, chainLlm, lmChatGoogleGemini, outputParserStructured. Manual trigger; 21 nodes.
This workflow contains community nodes that are only compatible with the self-hosted version of n8n.