8
n8n 中文网amn8n.com

Reddit每日热门帖子→Gmail摘要(多子版块,AI摘要)

高级

这是一个Market Research, Multimodal AI领域的自动化工作流,包含 39 个节点。主要使用 Set, Code, Sort, Gmail, Merge 等节点。 从Reddit到Gmail的流程,含关键功能和GPT-4o Mini使用

前置要求
  • Google 账号和 Gmail API 凭证
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
  "id": "twvLZRSedaF7hjy2",
  "meta": {
    "instanceId": "36fee986cc83112881fb12ec7cc2d0221d7bddd71c11715c196899b114e8b0d2"
  },
  "name": "Reddit 每日热门帖子 → Gmail 摘要(多子版块,AI 摘要)",
  "tags": [],
  "nodes": [
    {
      "id": "143de7a4-65e3-431c-96b2-1ac4aefff128",
      "name": "便签",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        880,
        -464
      ],
      "parameters": {
        "width": 1328,
        "height": 544,
        "content": "## 检索每日热门子版块帖子"
      },
      "typeVersion": 1
    },
    {
      "id": "447db4d5-fb68-4035-b6c8-87b40f829c24",
      "name": "便签1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        432,
        -464
      ],
      "parameters": {
        "color": 5,
        "width": 256,
        "height": 544,
        "content": "## 设置您希望跟踪的子版块"
      },
      "typeVersion": 1
    },
    {
      "id": "a20dd531-ea12-4dbb-86e0-4ae6d0fc0a22",
      "name": "便签2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2448,
        -656
      ],
      "parameters": {
        "width": 1760,
        "height": 496,
        "content": "## 处理每个帖子"
      },
      "typeVersion": 1
    },
    {
      "id": "0b9096aa-22c9-4487-889a-af55ab509f20",
      "name": "便签3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2448,
        16
      ],
      "parameters": {
        "width": 1904,
        "height": 736,
        "content": "## 摘要每个帖子并发送到您的收件箱"
      },
      "typeVersion": 1
    },
    {
      "id": "fce66882-b289-4bd5-829b-104188cc9974",
      "name": "便签4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        160,
        -464
      ],
      "parameters": {
        "color": 5,
        "width": 256,
        "height": 544,
        "content": "## 设置您希望在收件箱中接收新闻简报的间隔"
      },
      "typeVersion": 1
    },
    {
      "id": "806fef98-e4a9-4b7d-8eb7-ae5aa4e75829",
      "name": "计划:每日运行",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        240,
        -192
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "triggerAtHour": 6
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "bd33313a-7409-4bb2-ba68-47528d416624",
      "name": "分割子版块列表",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        736,
        -192
      ],
      "parameters": {
        "options": {
          "destinationFieldName": "subreddit"
        },
        "fieldToSplitOut": "subreddits"
      },
      "typeVersion": 1
    },
    {
      "id": "6eb61b05-f1bf-47b0-99f5-5734838fa92e",
      "name": "列出热门帖子",
      "type": "n8n-nodes-base.reddit",
      "position": [
        928,
        -192
      ],
      "parameters": {
        "filters": {
          "category": "hot"
        },
        "operation": "getAll",
        "returnAll": true,
        "subreddit": "={{ $json.subreddit }}"
      },
      "credentials": {
        "redditOAuth2Api": {
          "id": "SedJCshrgbKDsJGh",
          "name": "Reddit account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "b9eb5d1f-4a0b-4db9-9063-1fc7c8358ed4",
      "name": "为帖子附加 ISO 日期",
      "type": "n8n-nodes-base.merge",
      "position": [
        1376,
        -192
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineByPosition"
      },
      "typeVersion": 3.2
    },
    {
      "id": "573e28e0-521a-4f8f-8c00-1a5fc0d2d1f0",
      "name": "标准化帖子日期(created_utc → 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": "选择字段(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": "筛选:过去 24 小时且分数 > 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": "按分数排序(降序)",
      "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": "迭代帖子(单批次)",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        2256,
        -192
      ],
      "parameters": {
        "options": {},
        "batchSize": "={{ $input.all().length }}"
      },
      "typeVersion": 3
    },
    {
      "id": "482ae953-738b-4aec-a66c-cacc162a9a44",
      "name": "按 ID 获取帖子",
      "type": "n8n-nodes-base.reddit",
      "position": [
        2496,
        -480
      ],
      "parameters": {
        "postId": "={{ $json.id }}",
        "operation": "get",
        "subreddit": "={{ $json.subreddit }}"
      },
      "credentials": {
        "redditOAuth2Api": {
          "id": "SedJCshrgbKDsJGh",
          "name": "Reddit account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "5cfd61e4-6928-445c-a148-2c8ac8accb27",
      "name": "按 ID 去重",
      "type": "n8n-nodes-base.removeDuplicates",
      "position": [
        2720,
        -480
      ],
      "parameters": {
        "compare": "selectedFields",
        "options": {},
        "fieldsToCompare": "id"
      },
      "typeVersion": 2
    },
    {
      "id": "26d7e22f-14bd-4320-bb56-1e9d69ad367d",
      "name": "构建帖子正文(根)",
      "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: “Run Once for All Items”\n */\nreturn $input.all().map(({ json: p }) => {\n  // ─── convert epoch-seconds → YYYY-MM-DD (UTC) ───────────────────────────\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      /* ───────── identifiers ───────── */\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      /* ───────── text & author ─────── */\n      body      : `${p.title || ''}${p.selftext ? '\\n\\n' + p.selftext : ''}`,\n      author    : p.author,\n      score     : p.score,\n\n      /* ───────── context ───────────── */\n      depth     : -1,                                   // reserve –1 for the root post\n      subreddit : p.subreddit,\n      permalink : `https://reddit.com${p.permalink}`,\n\n      /* ───────── timestamps ────────── */\n      created_utc: createdUtcDate,                      // e.g. \"2024-07-01\"\n\n      /* ───────── metadata ──────────── */\n      chunk_type: 'post'                                // post | comment | reply\n    }\n  };\n});"
      },
      "typeVersion": 2
    },
    {
      "id": "5ef14e2a-04a9-4419-8831-da9128cc1740",
      "name": "列出顶级评论",
      "type": "n8n-nodes-base.reddit",
      "position": [
        3168,
        -416
      ],
      "parameters": {
        "postId": "={{ $json.post_id }}",
        "resource": "postComment",
        "operation": "getAll",
        "subreddit": "={{ $json.subreddit }}"
      },
      "credentials": {
        "redditOAuth2Api": {
          "id": "SedJCshrgbKDsJGh",
          "name": "Reddit account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "861258dc-6bac-489f-a99a-31753c197b20",
      "name": "展平评论线程",
      "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 → 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": "筛选:有效评论",
      "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": "附加帖子 + 评论",
      "type": "n8n-nodes-base.merge",
      "position": [
        3840,
        -480
      ],
      "parameters": {},
      "typeVersion": 3.2
    },
    {
      "id": "3541c2bc-a535-45b6-a0a8-138bdbff2b31",
      "name": "构建线程文本",
      "type": "n8n-nodes-base.code",
      "position": [
        4064,
        -480
      ],
      "parameters": {
        "jsCode": "/**\n * n8n Code node ▸ 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// ────────────────── helpers ──────────────────\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// ────────────────── 1. build node map ──────────────────\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// ────────────────── 2. link parents & children ──────────────────\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// ────────────────── 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// ────────────────── 3. stringify the thread ──────────────────\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// ────────────────── 4. emit one item per root ──────────────────\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": "合并:线程 + 帖子详情",
      "type": "n8n-nodes-base.merge",
      "position": [
        4288,
        -416
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineByPosition"
      },
      "typeVersion": 3.2
    },
    {
      "id": "3c37fad6-9320-408b-9686-92337dca5d3a",
      "name": "设置(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": "调用子工作流:摘要并发送邮件",
      "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": "子工作流触发器",
      "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": "提取链接",
      "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": "提取线程文本",
      "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": {
          "id": "9H6tnWvfT2T0cL3J",
          "name": "OpenRouter account (Augra)"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "8bb8fddb-de27-4a35-a6e5-9045daf856dd",
      "name": "摘要线程",
      "type": "@n8n/n8n-nodes-langchain.chainSummarization",
      "position": [
        2960,
        464
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 2.1
    },
    {
      "id": "c0f55602-75a0-4783-b6a4-dd21a03486d4",
      "name": "组合摘要 + 链接",
      "type": "n8n-nodes-base.merge",
      "position": [
        3360,
        368
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineByPosition"
      },
      "typeVersion": 3.2
    },
    {
      "id": "9f8ecb80-43e2-477c-a727-18a9c5463bd5",
      "name": "聚合摘要和链接",
      "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": "为 Gmail 格式化 HTML",
      "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 — 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": "发送摘要",
      "type": "n8n-nodes-base.gmail",
      "position": [
        4208,
        368
      ],
      "webhookId": "19deaeea-18d2-440a-9250-74b087adff4a",
      "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": {
          "id": "VbTLd2y2kR8BFtur",
          "name": "Gmail account"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "d7d8c4bc-a9bc-4c1f-8046-890611abfaee",
      "name": "设置主题、子版块和电子邮件地址",
      "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": "johndoe@gmail.com"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "99d1e0af-32e9-4e33-a40d-642db28d3d6f",
      "name": "便签5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -656,
        -544
      ],
      "parameters": {
        "color": 5,
        "width": 624,
        "height": 256,
        "content": ""
      },
      "typeVersion": 1
    },
    {
      "id": "88a4e517-fc50-4128-8160-e0acd34ea87b",
      "name": "### 需要帮助?",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -656,
        -256
      ],
      "parameters": {
        "width": 624,
        "height": 176,
        "content": ""
      },
      "typeVersion": 1
    },
    {
      "id": "f4c542ec-a961-4e0e-b913-accbb5544c80",
      "name": "## 试试看!",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -656,
        -48
      ],
      "parameters": {
        "width": 624,
        "height": 208,
        "content": "**自定义**"
      },
      "typeVersion": 1
    },
    {
      "id": "7f1dffb8-95eb-4949-aa18-9c1efd7ae820",
      "name": "GET 模型",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -656,
        192
      ],
      "parameters": {
        "width": 624,
        "height": 560,
        "content": "## 从此开始:分步 YouTube 教程 :star:"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "pinData": {},
  "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 → 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 → 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
          }
        ]
      ]
    }
  }
}
常见问题

如何使用这个工作流?

复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。

这个工作流适合什么场景?

高级 - 市场调研, 多模态 AI

需要付费吗?

本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。

工作流信息
难度等级
高级
节点数量39
分类2
节点类型18
难度说明

适合高级用户,包含 16+ 个节点的复杂工作流

作者
Hunyao

Hunyao

@hun-yao

Hun Yao is a founder-engineer obsessed with building scalable automation that actually moves the needle - with a focus in the E-commerce space. A self-taught product builder with roots in marketing and AI, he uses n8n as his playground to ship MVPs fast - turning modular workflows into elegant, revenue-generating systems.

外部链接
在 n8n.io 查看

分享此工作流