8
n8n 中文网amn8n.com

带 AI 过滤的个性化学习内容聚合器

高级

这是一个Market Research, AI Summarization领域的自动化工作流,包含 18 个节点。主要使用 Set, Code, Merge, HttpRequest, RssFeedRead 等节点。 使用 GPT-4.1-mini 和 Google Sheets 从 Reddit 和 RSS 筛选学习内容

前置要求
  • 可能需要目标 API 的认证凭证
  • Google Sheets API 凭证
  • OpenAI API Key
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
  "id": "SPMdOPACsv0whzC1",
  "meta": {
    "instanceId": "15d6057a37b8367f33882dd60593ee5f6cc0c59310ff1dc66b626d726083b48d",
    "templateCredsSetupCompleted": true
  },
  "name": "带 AI 过滤的个性化学习内容聚合器",
  "tags": [],
  "nodes": [
    {
      "id": "530285ce-4719-441a-9027-a5a1f55454f8",
      "name": "计划触发器 - 每日两次",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        144,
        272
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "triggerAtHour": 8
            },
            {
              "triggerAtHour": 18
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "01138c7e-b68b-4772-bb47-ff096170fad2",
      "name": "工作流配置",
      "type": "n8n-nodes-base.set",
      "position": [
        368,
        272
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "id-2",
              "name": "rssFeeds",
              "type": "string",
              "value": "<__PLACEHOLDER_VALUE__Comma-separated RSS feed URLs to monitor__>"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "f752f79f-3242-49bd-9ad9-536aadf3ecda",
      "name": "从 Google Sheets 获取关键词",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        592,
        272
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1e7dTOI3g-SEmv2unfMTrmzuLllb5TBY6IXajPjZ1RmE/edit#gid=0",
          "cachedResultName": "シート1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1e7dTOI3g-SEmv2unfMTrmzuLllb5TBY6IXajPjZ1RmE",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1e7dTOI3g-SEmv2unfMTrmzuLllb5TBY6IXajPjZ1RmE/edit?usp=drivesdk",
          "cachedResultName": "無題のスプレッドシート"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "bf214976-ba37-435f-8191-1d6af7ed0159",
      "name": "循环遍历关键词",
      "type": "n8n-nodes-base.code",
      "position": [
        816,
        272
      ],
      "parameters": {
        "jsCode": "const keywords = $input.all().map(item => item.json);\nconst outputs = [];\n\nfor (const row of keywords) {\n  let keyword = row.keyword || row.Keyword || Object.values(row)[0];\n\n  // 文字列でない場合のフォールバック\n  if (typeof keyword === 'object' && keyword !== null) {\n    keyword = Object.values(keyword)[0];\n  }\n\n  if (typeof keyword === 'string' && keyword.trim()) {\n    outputs.push({ json: { keyword: keyword.trim() } });\n  }\n}\n\nreturn outputs;\n"
      },
      "typeVersion": 2
    },
    {
      "id": "91891a18-73a3-4582-af3f-a932483dd8e2",
      "name": "搜索 RSS 源",
      "type": "n8n-nodes-base.rssFeedRead",
      "position": [
        1040,
        80
      ],
      "parameters": {
        "url": "={{ $('Workflow Configuration').first().json.rssFeeds.split(',')[0] }}",
        "options": {}
      },
      "typeVersion": 1.2
    },
    {
      "id": "fa1e5bad-c831-42d8-a246-a694b5ff11f4",
      "name": "合并所有搜索结果",
      "type": "n8n-nodes-base.merge",
      "position": [
        1264,
        176
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineAll"
      },
      "typeVersion": 3.2
    },
    {
      "id": "7b189ca5-cd33-42fb-a415-6573cba65dd8",
      "name": "为 AI 准备文章",
      "type": "n8n-nodes-base.code",
      "position": [
        1488,
        176
      ],
      "parameters": {
        "jsCode": "const items = $input.all();\nconst articles = [];\n\nfor (const item of items) {\n  const data = item.json;\n  \n  // Handle Reddit API response format (data.children array)\n  if (data.data && data.data.children && Array.isArray(data.data.children)) {\n    for (const child of data.data.children) {\n      const post = child.data;\n      let article = {\n        title: post.title || 'No title',\n        url: post.url || `https://reddit.com${post.permalink}` || '',\n        description: post.selftext || post.title || '',\n        source: 'Reddit',\n        publishedAt: post.created_utc ? new Date(post.created_utc * 1000).toISOString() : new Date().toISOString()\n      };\n      articles.push(article);\n    }\n  }\n  // Handle individual Reddit post format\n  else if (data.subreddit || data.permalink) {\n    let article = {\n      title: data.title || data.name || 'No title',\n      url: data.url || data.permalink || '',\n      description: data.selftext || data.text || data.title || '',\n      source: 'Reddit',\n      publishedAt: data.created_utc ? new Date(data.created_utc * 1000).toISOString() : new Date().toISOString()\n    };\n    articles.push(article);\n  }\n  // Handle Twitter format\n  else if (data.author_id || data.tweet_id) {\n    let article = {\n      title: data.text ? data.text.substring(0, 100) : 'No title',\n      url: data.url || '',\n      description: data.text || data.content || '',\n      source: 'Twitter',\n      publishedAt: data.created_at || new Date().toISOString()\n    };\n    articles.push(article);\n  }\n  // Handle RSS format\n  else {\n    let article = {\n      title: data.title || data.name || 'No title',\n      url: data.url || data.link || '',\n      description: data.description || data.content || '',\n      source: 'RSS',\n      publishedAt: data.pubDate || data.published || new Date().toISOString()\n    };\n    articles.push(article);\n  }\n}\n\nconst articlesText = articles.map((a, i) => \n  `Article ${i + 1}:\\nTitle: ${a.title}\\nURL: ${a.url}\\nDescription: ${a.description.substring(0, 300)}...\\nSource: ${a.source}\\n`\n).join('\\n---\\n');\n\nreturn [{ json: { articles, articlesText, keyword: $('Loop Over Keywords').first().json.keyword } }];"
      },
      "typeVersion": 2
    },
    {
      "id": "04657aeb-6396-46a1-8457-174cbd5380d6",
      "name": "AI 内容过滤器",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        1712,
        176
      ],
      "parameters": {
        "text": "=You are a content curator for personalized learning. Your task is to analyze articles and select only those that are:\n1. Highly relevant to the keyword: {{ $json.keyword }}\n2. Contain NEW and valuable information (tutorials, new features, announcements, guides)\n3. NOT promotional content, spam, or low-quality posts\n\nHere are the articles to analyze:\n\n{{ $json.articlesText }}\n\nRespond with a JSON array containing only the article numbers (1, 2, 3, etc.) that meet the criteria. Example: [1, 3, 5]\nIf no articles meet the criteria, respond with an empty array: []\n\nOnly return the JSON array, nothing else",
        "options": {},
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 2.2
    },
    {
      "id": "047ef445-5190-4a41-83cc-535cc0419149",
      "name": "解析 AI 响应",
      "type": "n8n-nodes-base.code",
      "position": [
        2064,
        176
      ],
      "parameters": {
        "jsCode": "const aiResponse = $json.output;\nconst articles = $('Prepare Articles for AI').first().json.articles;\n\nlet selectedIndices = [];\ntry {\n  // Try to parse the AI response as JSON\n  const match = aiResponse.match(/\\[(.*?)\\]/s);\n  if (match) {\n    selectedIndices = JSON.parse('[' + match[1] + ']');\n  }\n} catch (error) {\n  console.log('Failed to parse AI response:', error);\n  return [];\n}\n\nconst selectedArticles = selectedIndices\n  .map(index => articles[index - 1])\n  .filter(article => article !== undefined);\n\nreturn selectedArticles.map(article => ({ json: article }));"
      },
      "typeVersion": 2
    },
    {
      "id": "ccc0797d-0636-4027-98e0-6aae1e8ecb58",
      "name": "OpenAI 聊天模型",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        1792,
        400
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini"
        },
        "options": {}
      },
      "typeVersion": 1.2
    },
    {
      "id": "8c4b9ba8-1478-4a8a-96fc-93971fd97d7b",
      "name": "通过 API 搜索 Reddit",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1040,
        272
      ],
      "parameters": {
        "url": "https://www.reddit.com/search.json",
        "options": {
          "response": {
            "response": {
              "responseFormat": "json"
            }
          }
        },
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "q",
              "value": "={{ $json.keyword }}"
            },
            {
              "name": "limit",
              "value": "10"
            },
            {
              "name": "sort",
              "value": "relevance"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "578fc36c-a9d8-4893-821d-7cbb04a6174d",
      "name": "保存到 Google Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2288,
        176
      ],
      "parameters": {
        "columns": {
          "value": {
            "URL": "={{ $json.url }}",
            "Title": "={{ $json.title }}",
            "Source": "={{ $json.source }}",
            "Added Date": "={{ $now.toISO() }}",
            "Description": "={{ $json.description }}"
          },
          "schema": [
            {
              "id": "Title",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Title",
              "defaultMatch": true,
              "canBeUsedToMatch": true
            },
            {
              "id": "URL",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "URL",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Description",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Description",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Source",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Source",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Added Date",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Added Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "Title"
          ]
        },
        "options": {},
        "operation": "appendOrUpdate",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1891354699,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1e7dTOI3g-SEmv2unfMTrmzuLllb5TBY6IXajPjZ1RmE/edit#gid=1891354699",
          "cachedResultName": "シート3"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1e7dTOI3g-SEmv2unfMTrmzuLllb5TBY6IXajPjZ1RmE",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1e7dTOI3g-SEmv2unfMTrmzuLllb5TBY6IXajPjZ1RmE/edit?usp=drivesdk",
          "cachedResultName": "無題のスプレッドシート"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "846c183a-c784-4ca2-bc85-78503934df11",
      "name": "模板概览",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -352,
        64
      ],
      "parameters": {
        "width": 560,
        "height": 896,
        "content": "## 带 AI 过滤的个性化学习内容聚合器"
      },
      "typeVersion": 1
    },
    {
      "id": "57735186-ac1c-45cb-a685-1fa0aba45fc5",
      "name": "配置说明",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        368,
        176
      ],
      "parameters": {
        "content": "保存来自 Google Sheets 的 RSS 源 URL 和用户定义关键词"
      },
      "typeVersion": 1
    },
    {
      "id": "50c96cef-b37c-44fa-930a-bafbb2f1b0f9",
      "name": "获取 Reddit 说明",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        960,
        464
      ],
      "parameters": {
        "height": 128,
        "content": "基于关键词通过公共 API 从 Reddit 获取学习相关帖子"
      },
      "typeVersion": 1
    },
    {
      "id": "461e1737-57fa-4116-a0c9-83d5c02136ff",
      "name": "合并说明",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1248,
        48
      ],
      "parameters": {
        "content": "合并所有内容源(RSS + Reddit)的结果以进行统一 AI 过滤"
      },
      "typeVersion": 1
    },
    {
      "id": "85ed87bf-4ecf-4ceb-9cdd-6d66712b1ccf",
      "name": "AI 过滤说明",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1712,
        16
      ],
      "parameters": {
        "content": "AI 分析文章并仅保留高质量、相关的教育内容"
      },
      "typeVersion": 1
    },
    {
      "id": "3cc34535-4907-4957-92fa-11ae789bdcec",
      "name": "保存结果说明",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2208,
        32
      ],
      "parameters": {
        "content": "自动将最终精选文章保存到您连接的 Google Sheets"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "efbba744-6c3b-4fd9-b47b-f5e3b08a8256",
  "connections": {
    "Search RSS Feeds": {
      "main": [
        [
          {
            "node": "Merge All Search Results",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Content Filter": {
      "main": [
        [
          {
            "node": "Parse AI Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Content Filter",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Parse AI Response": {
      "main": [
        [
          {
            "node": "Save to Google Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Keywords": {
      "main": [
        [
          {
            "node": "Search RSS Feeds",
            "type": "main",
            "index": 0
          },
          {
            "node": "Search Reddit via API",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Search Reddit via API": {
      "main": [
        [
          {
            "node": "Merge All Search Results",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Workflow Configuration": {
      "main": [
        [
          {
            "node": "Get Keywords from Google Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Articles for AI": {
      "main": [
        [
          {
            "node": "AI Content Filter",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge All Search Results": {
      "main": [
        [
          {
            "node": "Prepare Articles for AI",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger - Twice Daily": {
      "main": [
        [
          {
            "node": "Workflow Configuration",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Keywords from Google Sheets": {
      "main": [
        [
          {
            "node": "Loop Over Keywords",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
常见问题

如何使用这个工作流?

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

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

高级 - 市场调研, AI 摘要总结

需要付费吗?

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

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

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

外部链接
在 n8n.io 查看

分享此工作流