AutomationFlowsData & Sheets › Automate Raindrop to Notion Knowledge Sync

Automate Raindrop to Notion Knowledge Sync

Original n8n title: Raindrop Knowledge Management

Raindrop Knowledge Management. Uses httpRequest, notion. Scheduled trigger; 11 nodes.

Cron / scheduled trigger★★★★☆ complexity11 nodesHTTP RequestNotion
Data & Sheets Trigger: Cron / scheduled Nodes: 11 Complexity: ★★★★☆ Added:

This workflow follows the HTTP Request → Notion 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 →

Download .json
{
  "name": "Raindrop Knowledge Management",
  "nodes": [
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "minutes",
              "minutesInterval": 30
            }
          ]
        }
      },
      "id": "6c84895f-7e29-4776-afc5-c6e290b13fc6",
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.1,
      "position": [
        -1680,
        400
      ]
    },
    {
      "parameters": {
        "url": "https://api.raindrop.io/rest/v1/raindrops/0",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "raindropOAuth2Api",
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "sort",
              "value": "-created"
            },
            {
              "name": "perpage",
              "value": "10"
            }
          ]
        },
        "options": {
          "response": {
            "response": {
              "responseFormat": "json"
            }
          }
        }
      },
      "id": "261cd63d-97ef-44dd-9899-7f0080689f77",
      "name": "\u53d6\u5f97 Raindrop \u6536\u85cf",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.1,
      "position": [
        -1460,
        400
      ],
      "credentials": {
        "raindropOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// 30\u5206\u9418\u89f8\u767c\u5c0d\u61c9\u7684\u7be9\u9078\u908f\u8f2f\nconst items = $input.all();\nconst response = items[0].json;\nconst newItems = [];\n\n// \u89f8\u767c\u9593\u9694 30 \u5206\u9418\uff0c\u6642\u9593\u7a97\u53e3\u8a2d\u70ba 35 \u5206\u9418\uff08\u591a 5 \u5206\u9418\u7de9\u885d\uff09\nconst scheduleInterval = 30; // \u5206\u9418\nconst timeWindow = (scheduleInterval + 5) * 60 * 1000; // 35 \u5206\u9418\nconst cutoffTime = Date.now() - timeWindow;\n\nconsole.log(`\u6aa2\u67e5 ${response.items?.length || 0} \u500b\u6536\u85cf\u9805\u76ee`);\nconsole.log(`\u6642\u9593\u7a97\u53e3\uff1a\u6700\u8fd1 ${scheduleInterval + 5} \u5206\u9418`);\nconsole.log(`\u622a\u6b62\u6642\u9593\uff1a${new Date(cutoffTime).toLocaleString('zh-TW')}`);\n\n// \u6309\u5efa\u7acb\u6642\u9593\u6392\u5e8f\uff0c\u6700\u65b0\u7684\u5728\u524d\u9762\nconst sortedItems = (response.items || []).sort((a, b) => {\n  return new Date(b.created).getTime() - new Date(a.created).getTime();\n});\n\nfor (const item of sortedItems) {\n  const createdTime = new Date(item.created).getTime();\n  const minutesAgo = Math.round((Date.now() - createdTime) / (60 * 1000));\n  \n  if (createdTime > cutoffTime) {\n    newItems.push({\n      id: item._id,\n      title: item.title || '\u7121\u6a19\u984c',\n      link: item.link,\n      excerpt: item.excerpt || '',\n      tags: item.tags || [],\n      created: item.created,\n      domain: item.domain || '',\n      type: item.type || 'link',\n      minutesAgo: minutesAgo\n    });\n    \n    console.log(`\u2705 \u65b0\u9805\u76ee\uff1a${item.title} (${minutesAgo} \u5206\u9418\u524d)`);\n  } else {\n    console.log(`\u23ed\ufe0f \u8df3\u904e\u820a\u9805\u76ee\uff1a${item.title} (${minutesAgo} \u5206\u9418\u524d\uff0c\u8d85\u904e 35 \u5206\u9418)`);\n  }\n}\n\n// \u9650\u5236\u6bcf\u6b21\u6700\u591a\u8655\u7406 5 \u500b\u9805\u76ee\uff08\u907f\u514d\u7a81\u7136\u5927\u91cf\u8655\u7406\uff09\nconst maxItems = 5;\nconst finalItems = newItems.slice(0, maxItems);\n\nif (finalItems.length < newItems.length) {\n  console.log(`\ud83d\udcdd \u9650\u5236\u8655\u7406\u6578\u91cf\uff1a${finalItems.length}/${newItems.length} \u500b\u9805\u76ee`);\n}\n\nif (finalItems.length === 0) {\n  console.log('\ud83d\udced \u6c92\u6709\u7b26\u5408\u6642\u9593\u7a97\u53e3\u7684\u65b0\u6536\u85cf\u9805\u76ee');\n  return [];\n}\n\nconsole.log(`\ud83c\udfaf \u767c\u73fe ${finalItems.length} \u500b\u65b0\u9805\u76ee\u6e96\u5099\u8655\u7406`);\nreturn finalItems.map(item => ({ json: item }));"
      },
      "id": "dff50a0b-e500-424f-a30c-6520a1fcb180",
      "name": "\u7be9\u9078\u65b0\u9805\u76ee",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -1240,
        400
      ]
    },
    {
      "parameters": {
        "jsCode": "// \u8655\u7406\u5167\u5bb9 - \u652f\u63f4\u591a\u7b46\u8cc7\u6599\u8655\u7406\nconst items = $input.all();\nconst results = [];\n\nconsole.log(`\ud83d\udcc4 \u6e96\u5099\u8655\u7406 ${items.length} \u500b\u9805\u76ee\u7684\u5167\u5bb9`);\n\n// \u5f37\u5316\u7684\u6587\u672c\u6e05\u7406\u51fd\u6578 - \u5c08\u9580\u8655\u7406 JSON \u76f8\u5bb9\u6027\nfunction sanitizeForJson(text) {\n  if (!text) return '';\n  \n  return text\n    // \u79fb\u9664\u6240\u6709\u63a7\u5236\u5b57\u7b26\n    .replace(/[\\u0000-\\u001F\\u007F-\\u009F]/g, '')\n    // \u8655\u7406 JSON \u7279\u6b8a\u5b57\u7b26\n    .replace(/\\\\/g, '\\\\\\\\')  // \u53cd\u659c\u7dda\n    .replace(/\"/g, '\\\\\"')    // \u96d9\u5f15\u865f\n    .replace(/'/g, \"\\\\'\")    // \u55ae\u5f15\u865f\n    // \u7d71\u4e00\u8655\u7406\u63db\u884c\u548c\u7a7a\u767d\n    .replace(/[\\r\\n\\t]/g, ' ')\n    .replace(/\\s+/g, ' ')\n    // \u79fb\u9664 Markdown \u7279\u6b8a\u7b26\u865f\uff08\u4fdd\u7559\u5167\u5bb9\uff09\n    .replace(/^#+\\s*/gm, '')  // \u79fb\u9664 # \u6a19\u984c\u7b26\u865f\n    .replace(/\\*\\*(.*?)\\*\\*/g, '$1')  // \u79fb\u9664\u7c97\u9ad4\u6a19\u8a18\n    .replace(/\\*(.*?)\\*/g, '$1')  // \u79fb\u9664\u659c\u9ad4\u6a19\u8a18\n    .replace(/`(.*?)`/g, '$1')  // \u79fb\u9664\u7a0b\u5f0f\u78bc\u6a19\u8a18\n    .replace(/---+/g, '')  // \u79fb\u9664\u5206\u9694\u7dda\n    // \u6e05\u7406\u591a\u9918\u7b26\u865f\n    .replace(/[{}[\\]]/g, '')  // \u79fb\u9664\u5927\u62ec\u865f\u548c\u4e2d\u62ec\u865f\n    .trim();\n}\n\n// HTML \u6e05\u7406\u51fd\u6578\nfunction cleanHtml(html) {\n  if (!html) return '';\n  \n  return html\n    .replace(/<script[^>]*>[\\s\\S]*?<\\/script>/gi, '')\n    .replace(/<style[^>]*>[\\s\\S]*?<\\/style>/gi, '')\n    .replace(/<nav[^>]*>[\\s\\S]*?<\\/nav>/gi, '')\n    .replace(/<footer[^>]*>[\\s\\S]*?<\\/footer>/gi, '')\n    .replace(/<aside[^>]*>[\\s\\S]*?<\\/aside>/gi, '')\n    .replace(/<header[^>]*>[\\s\\S]*?<\\/header>/gi, '')\n    .replace(/<div[^>]*class=\"[^\"]*ad[^\"]*\"[^>]*>[\\s\\S]*?<\\/div>/gi, '')\n    .replace(/<[^>]*>/g, ' ')\n    .replace(/&nbsp;/g, ' ')\n    .replace(/&amp;/g, '&')\n    .replace(/&lt;/g, '<')\n    .replace(/&gt;/g, '>')\n    .replace(/&quot;/g, '\"')\n    .replace(/&#39;/g, \"'\")\n    .replace(/\\s+/g, ' ')\n    .replace(/\\n+/g, '\\n')\n    .trim();\n}\n\nfunction extractTitle(html) {\n  const titleMatches = [\n    html.match(/<title[^>]*>([^<]+)<\\/title>/i),\n    html.match(/<h1[^>]*>([^<]+)<\\/h1>/i),\n    html.match(/<meta[^>]*property=\"og:title\"[^>]*content=\"([^\"]+)\"/i)\n  ];\n  \n  for (const match of titleMatches) {\n    if (match && match[1] && match[1].trim()) {\n      return match[1].trim().replace(/\\s+/g, ' ');\n    }\n  }\n  return '';\n}\n\nfunction extractDescription(html) {\n  const descMatches = [\n    html.match(/<meta[^>]*name=\"description\"[^>]*content=\"([^\"]+)\"/i),\n    html.match(/<meta[^>]*property=\"og:description\"[^>]*content=\"([^\"]+)\"/i)\n  ];\n  \n  for (const match of descMatches) {\n    if (match && match[1] && match[1].trim()) {\n      return match[1].trim().replace(/\\s+/g, ' ');\n    }\n  }\n  return '';\n}\n\nfunction detectContentType(url, content, domain) {\n  const lowerContent = (content || '').toLowerCase();\n  const lowerDomain = (domain || '').toLowerCase();\n  \n  if (lowerDomain.includes('reddit.com')) return '\u793e\u7fa4\u8a0e\u8ad6';\n  if (lowerDomain.includes('github.com')) return '\u958b\u6e90\u5c08\u6848';\n  if (lowerDomain.includes('medium.com') || lowerDomain.includes('dev.to')) return '\u6280\u8853\u6587\u7ae0';\n  if (lowerDomain.includes('stackoverflow.com')) return '\u6280\u8853\u554f\u7b54';\n  if (lowerDomain.includes('youtube.com') || lowerDomain.includes('youtu.be')) return '\u5f71\u7247\u6559\u5b78';\n  if (lowerDomain.includes('twitter.com') || lowerDomain.includes('x.com')) return '\u793e\u7fa4\u8a0e\u8ad6';\n  if (lowerDomain.includes('facebook.com')) return '\u793e\u7fa4\u8a0e\u8ad6';\n  \n  if (lowerContent.includes('tutorial') || lowerContent.includes('\u6559\u5b78')) return '\u6559\u5b78';\n  if (lowerContent.includes('tool') || lowerContent.includes('\u5de5\u5177')) return '\u5de5\u5177';\n  if (lowerContent.includes('news') || lowerContent.includes('\u65b0\u805e')) return '\u65b0\u805e';\n  \n  return '\u6280\u8853\u6587\u7ae0';\n}\n\n// \u8655\u7406\u6bcf\u500b\u9805\u76ee\nfor (let i = 0; i < items.length; i++) {\n  const item = items[i].json;\n  const html = item.data || '';\n  const originalData = items[i].json; // \u73fe\u5728\u5c31\u662f\u7576\u524d\u9805\u76ee\u7684\u8cc7\u6599\n\n  console.log(`\\n\ud83d\udcc4 \u8655\u7406\u9805\u76ee ${i + 1}/${items.length}\uff1a${originalData.title}`);\n  console.log(`\ud83d\udcca \u6293\u53d6\u72c0\u614b\uff1a${item.fetchSuccess ? '\u6210\u529f' : '\u5931\u6557'}`);\n\n  // \u5982\u679c\u6293\u53d6\u5931\u6557\uff0c\u4f7f\u7528 Raindrop \u63d0\u4f9b\u7684\u8cc7\u8a0a\n  if (!item.fetchSuccess && item.usedFallback) {\n    console.log(`\ud83d\udcdd \u4f7f\u7528 Raindrop \u6458\u8981\u4f5c\u70ba\u5167\u5bb9`);\n    \n    results.push({\n      json: {\n        // \u539f\u59cb\u8cc7\u6599\n        id: originalData.id,\n        title: sanitizeForJson(originalData.title || '\u7121\u6a19\u984c'),\n        link: originalData.link,\n        tags: originalData.tags || [],\n        domain: originalData.domain,\n        created: originalData.created,\n        raindropExcerpt: sanitizeForJson(originalData.excerpt || ''),\n        \n        // \u8655\u7406\u5f8c\u7684\u5167\u5bb9\n        cleanContent: sanitizeForJson(originalData.excerpt || '\u7121\u6cd5\u53d6\u5f97\u5167\u5bb9\uff0c\u8acb\u76f4\u63a5\u67e5\u770b\u539f\u59cb\u9023\u7d50'),\n        metaDescription: sanitizeForJson(originalData.excerpt || ''),\n        webTitle: sanitizeForJson(originalData.title || ''),\n        \n        // \u5167\u5bb9\u5206\u6790\n        contentLength: (originalData.excerpt || '').length,\n        estimatedReadTime: 2, // \u9810\u8a2d 2 \u5206\u9418\n        detectedType: detectContentType(originalData.link, originalData.excerpt, originalData.domain),\n        \n        // \u6c7a\u5b9a\u662f\u5426\u4f7f\u7528 AI\uff08\u4fdd\u6301\u539f\u672c\u908f\u8f2f\uff09\n        useAI: false, // \u5167\u5bb9\u4e0d\u8db3\uff0c\u4e0d\u4f7f\u7528 AI\n        \n        // \u932f\u8aa4\u8cc7\u8a0a\n        fetchError: item.fetchError,\n        processedAt: new Date().toISOString(),\n        minutesAfterCreation: originalData.minutesAgo\n      }\n    });\n    continue;\n  }\n\n  // \u7e7c\u7e8c\u8655\u7406\u6210\u529f\u6293\u53d6\u7684\u5167\u5bb9\n  const cleanContent = cleanHtml(html);\n  const webTitle = extractTitle(html);\n  const metaDescription = extractDescription(html);\n\n  // \u539f\u672c\u7684 AI \u5224\u65b7\u908f\u8f2f\n  const worthAnalyzing = cleanContent.length > 300 && \n                        cleanContent.length < 8000 && \n                        !originalData.domain.includes('twitter.com') &&\n                        !originalData.domain.includes('x.com');\n\n  console.log(`\ud83d\udcca \u5167\u5bb9\u9577\u5ea6\uff1a${cleanContent.length} \u5b57\u5143`);\n  console.log(`\ud83e\udd16 \u662f\u5426\u4f7f\u7528 AI\uff1a${worthAnalyzing ? '\u662f' : '\u5426'}`);\n\n  results.push({\n    json: {\n      id: originalData.id,\n      title: sanitizeForJson(originalData.title || webTitle || '\u7121\u6a19\u984c'),\n      link: originalData.link,\n      tags: originalData.tags || [],\n      domain: originalData.domain,\n      created: originalData.created,\n      raindropExcerpt: sanitizeForJson(originalData.excerpt || ''),\n      \n      cleanContent: sanitizeForJson(cleanContent.substring(0, 6000)),\n      metaDescription: sanitizeForJson(metaDescription),\n      webTitle: sanitizeForJson(webTitle),\n      \n      contentLength: cleanContent.length,\n      estimatedReadTime: Math.max(1, Math.ceil(cleanContent.split(' ').length / 200)),\n      detectedType: detectContentType(originalData.link, cleanContent, originalData.domain),\n      \n      useAI: worthAnalyzing, // \u4fdd\u6301\u539f\u672c\u7684\u908f\u8f2f\u5224\u65b7\n      \n      processedAt: new Date().toISOString(),\n      minutesAfterCreation: originalData.minutesAgo,\n      fetchedUrl: item.fetchedUrl\n    }\n  });\n}\n\nconsole.log(`\\n\ud83c\udfaf \u8655\u7406\u5b8c\u6210\uff0c\u5171 ${results.length} \u500b\u9805\u76ee`);\nreturn results;"
      },
      "id": "c62e2b5a-0075-4df0-b324-0f85157dd187",
      "name": "\u8655\u7406\u5167\u5bb9",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -840,
        400
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 1
          },
          "conditions": [
            {
              "id": "useai-condition",
              "leftValue": "={{$json.useAI}}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "equal"
              }
            },
            {
              "id": "6e7af8d3-19a1-4d96-9dfd-c1db04007e35",
              "leftValue": "={{ $json.useAI }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            },
            {
              "id": "d00e51a7-6a5d-4d55-928c-9ee6538a5145",
              "leftValue": "={{ $json.useAI }}",
              "rightValue": "f",
              "operator": {
                "type": "boolean",
                "operation": "false",
                "singleValue": true
              }
            }
          ],
          "combinator": "or"
        },
        "options": {}
      },
      "id": "bcfeaecb-58fa-4176-b72f-58460a9da6d5",
      "name": "\u662f\u5426\u4f7f\u7528 AI \u5206\u6790",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        -620,
        400
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://demo-ai-svc-res929348950322.cognitiveservices.azure.com/openai/deployments/o4-mini/chat/completions?api-version=2025-01-01-preview",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "azureOpenAiApi",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"messages\": [\n    {\n      \"role\": \"system\",\n      \"content\": \"\u4f60\u662f\u4e00\u500b\u5c08\u696d\u7684\u5167\u5bb9\u5206\u6790\u5e2b\u3002\u8acb\u5206\u6790\u7db2\u9801\u5167\u5bb9\u4e26\u63d0\u4f9b\u7d50\u69cb\u5316\u5206\u6790\u3002\\n\\n\u8acb\u4ee5 JSON \u683c\u5f0f\u56de\u61c9\uff1a\\n{\\n  \\\"summary\\\": \\\"2-3\u53e5\u8a71\u7684\u7cbe\u8981\u6458\u8981\\\",\\n  \\\"keyPoints\\\": [\\\"\u91cd\u9ede1\\\", \\\"\u91cd\u9ede2\\\", \\\"\u91cd\u9ede3\\\"],\\n  \\\"suggestedTags\\\": [\\\"\u6a19\u7c641\\\", \\\"\u6a19\u7c642\\\", \\\"\u6a19\u7c643\\\"],\\n  \\\"priority\\\": \\\"\u9ad8|\u4e2d|\u4f4e\\\",\\n  \\\"category\\\": \\\"\u6280\u8853\u6587\u7ae0|\u6559\u5b78|\u5de5\u5177|\u65b0\u805e|\u958b\u6e90\u5c08\u6848|\u6280\u8853\u554f\u7b54|\u5176\u4ed6\\\",\\n  \\\"difficulty\\\": \\\"\u521d\u7d1a|\u4e2d\u7d1a|\u9ad8\u7d1a\\\",\\n  \\\"practicalValue\\\": \\\"\u9ad8|\u4e2d|\u4f4e\\\",\\n  \\\"learningGoals\\\": [\\\"\u76ee\u6a191\\\", \\\"\u76ee\u6a192\\\"]\\n}\\n\\n\u7528\u7e41\u9ad4\u4e2d\u6587\u56de\u61c9\u3002\"\n    },\n    {\n      \"role\": \"user\",\n      \"content\": \"={{ '\u6a19\u984c\uff1a' + ($json.title || 'N/A') + '\\\\n\u7db2\u7ad9\uff1a' + ($json.domain || 'N/A') + '\\\\n\u63cf\u8ff0\uff1a' + ($json.metaDescription || 'N/A') + '\\\\n\u985e\u578b\uff1a' + ($json.detectedType || 'N/A') + '\\\\n\\\\n\u5167\u5bb9\uff1a\\\\n' + ($json.cleanContent || 'N/A').substring(0, 3500) }}\"\n    }\n  ],\n  \"max_completion_tokens\": 1000\n}",
        "options": {
          "response": {
            "response": {
              "responseFormat": "json"
            }
          }
        }
      },
      "id": "051e3887-da01-4337-ba78-8d79b24b02fd",
      "name": "Azure AI \u5167\u5bb9\u5206\u6790",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.1,
      "position": [
        -400,
        300
      ],
      "credentials": {
        "azureOpenAiApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// \u6574\u5408 AI \u5206\u6790\u7d50\u679c - \u652f\u63f4\u591a\u7b46\u8cc7\u6599\u8655\u7406\nconst azureItems = $input.all();\nconst processedItems = $('\u8655\u7406\u5167\u5bb9').all();\n\nconsole.log(`\ud83e\udd16 \u6e96\u5099\u6574\u5408 ${azureItems.length} \u500b AI \u5206\u6790\u7d50\u679c`);\nconsole.log(`\ud83d\udcc4 \u539f\u59cb\u8655\u7406\u9805\u76ee\u6578\u91cf\uff1a${processedItems.length}`);\n\nconst results = [];\n\n// \ud83c\udff7\ufe0f \u667a\u80fd\u6a19\u7c64\u6e05\u7406\u548c\u8655\u7406\u51fd\u6578\nfunction cleanAndProcessTags(originalTags, suggestedTags) {\n  console.log('\ud83c\udff7\ufe0f \u8655\u7406\u6a19\u7c64\uff1a');\n  console.log('\u539f\u59cb\u6a19\u7c64:', originalTags);\n  console.log('\u5efa\u8b70\u6a19\u7c64:', suggestedTags);\n  \n  // \u5408\u4f75\u6240\u6709\u6a19\u7c64\uff0c\u78ba\u4fdd\u90fd\u662f\u9663\u5217\n  const allTags = [\n    ...(Array.isArray(originalTags) ? originalTags : []),\n    ...(Array.isArray(suggestedTags) ? suggestedTags : [])\n  ];\n  \n  // \u6e05\u7406\u6a19\u7c64\u51fd\u6578\n  function cleanTag(tag) {\n    if (!tag || typeof tag !== 'string') return null;\n    \n    return tag\n      .trim()\n      // \u79fb\u9664 Reddit r/ \u524d\u7db4\n      .replace(/^r\\//, '')\n      // \u79fb\u9664\u7279\u6b8a\u5b57\u7b26\uff0c\u53ea\u4fdd\u7559\u4e2d\u82f1\u6587\u3001\u6578\u5b57\u3001\u7a7a\u683c\u3001\u9023\u5b57\u7b26\n      .replace(/[^\\w\\s\\u4e00-\\u9fff-]/g, '')\n      // \u79fb\u9664\u591a\u9918\u7a7a\u683c\n      .replace(/\\s+/g, ' ')\n      .trim()\n      // \u9650\u5236\u9577\u5ea6\n      .substring(0, 50);\n  }\n  \n  // \u8655\u7406\u4e26\u6e05\u7406\u6a19\u7c64\n  const cleanedTags = allTags\n    .map(cleanTag)\n    .filter(tag => tag && tag.length > 0) // \u79fb\u9664\u7a7a\u6a19\u7c64\n    .filter(tag => tag.length >= 2) // \u79fb\u9664\u592a\u77ed\u7684\u6a19\u7c64\n    .map(tag => {\n      // \u6a19\u6e96\u5316\u5e38\u898b\u6a19\u7c64\n      const tagLower = tag.toLowerCase();\n      if (tagLower.includes('chatgpt')) return 'ChatGPT';\n      if (tagLower.includes('javascript') || tagLower === 'js') return 'JavaScript';\n      if (tagLower.includes('python')) return 'Python';\n      if (tagLower.includes('react')) return 'React';\n      if (tagLower.includes('vue')) return 'Vue';\n      if (tagLower.includes('node')) return 'Node.js';\n      if (tagLower.includes('frontend') || tagLower.includes('\u524d\u7aef')) return '\u524d\u7aef\u958b\u767c';\n      if (tagLower.includes('backend') || tagLower.includes('\u5f8c\u7aef')) return '\u5f8c\u7aef\u958b\u767c';\n      if (tagLower.includes('ai') || tagLower.includes('\u4eba\u5de5\u667a\u6167')) return 'AI';\n      if (tagLower.includes('tutorial') || tagLower.includes('\u6559\u5b78')) return '\u6559\u5b78';\n      if (tagLower.includes('tool') || tagLower.includes('\u5de5\u5177')) return '\u5de5\u5177';\n      if (tagLower.includes('coding') || tagLower.includes('\u7a0b\u5f0f')) return '\u7a0b\u5f0f\u8a2d\u8a08';\n      \n      return tag;\n    });\n  \n  // \u53bb\u91cd\u4e26\u9650\u5236\u6578\u91cf\n  const uniqueTags = [...new Set(cleanedTags)].slice(0, 6);\n  \n  console.log('\u2705 \u6e05\u7406\u5f8c\u6a19\u7c64:', uniqueTags);\n  return uniqueTags;\n}\n\n// \u8655\u7406\u6bcf\u500b Azure AI \u56de\u61c9\nfor (let i = 0; i < azureItems.length; i++) {\n  const azureResponse = azureItems[i].json;\n  const originalData = processedItems[i]?.json || {};\n\n  console.log(`\\n\ud83e\udd16 \u8655\u7406 AI \u5206\u6790\u7d50\u679c ${i + 1}/${azureItems.length}`);\n  console.log(`\ud83d\udcc4 \u539f\u59cb\u9805\u76ee\uff1a${originalData?.title || '\u672a\u77e5\u6a19\u984c'}`);\n\n  let aiAnalysis;\n  try {\n    // Azure AI \u56de\u61c9\u5728 choices[0].message.content\n    const aiContent = azureResponse.choices[0].message.content;\n    console.log('\ud83d\udcdd AI \u539f\u59cb\u56de\u61c9 (\u524d100\u5b57):', aiContent.substring(0, 100));\n    \n    // \u53bb\u9664 ```json``` \u5305\u88dd\u4e26\u63d0\u53d6 JSON\n    let jsonString = aiContent;\n    \n    // \u5982\u679c\u5167\u5bb9\u88ab ```json``` \u5305\u88dd\uff0c\u63d0\u53d6 JSON \u90e8\u5206\n    const jsonMatch = aiContent.match(/```json\\s*([\\s\\S]*?)\\s*```/);\n    if (jsonMatch) {\n      jsonString = jsonMatch[1];\n      console.log('\u2702\ufe0f \u63d0\u53d6\u51fa JSON \u90e8\u5206');\n    } else {\n      // \u5982\u679c\u6c92\u6709\u5305\u88dd\uff0c\u5617\u8a66\u76f4\u63a5\u63d0\u53d6 JSON \u7269\u4ef6\n      const directJsonMatch = aiContent.match(/\\{[\\s\\S]*\\}/);\n      if (directJsonMatch) {\n        jsonString = directJsonMatch[0];\n      }\n    }\n    \n    // \u89e3\u6790 JSON\n    aiAnalysis = JSON.parse(jsonString);\n    console.log('\u2705 AI \u5206\u6790\u89e3\u6790\u6210\u529f');\n    \n  } catch (error) {\n    console.log('\u274c AI \u56de\u61c9\u89e3\u6790\u5931\u6557:', error.message);\n    console.log('\ud83d\udd0d \u539f\u59cb\u56de\u61c9 choices:', azureResponse.choices?.[0]);\n    \n    // \u89e3\u6790\u5931\u6557\u6642\u4f7f\u7528\u9810\u8a2d\u503c\n    aiAnalysis = {\n      summary: originalData?.raindropExcerpt || originalData?.metaDescription || 'AI \u5206\u6790\u5931\u6557\uff0c\u8acb\u67e5\u770b\u539f\u59cb\u9023\u7d50',\n      keyPoints: ['AI \u89e3\u6790\u932f\u8aa4', '\u4f7f\u7528\u57fa\u672c\u8cc7\u8a0a'],\n      suggestedTags: [],\n      priority: '\u4e2d',\n      category: originalData?.detectedType || '\u5176\u4ed6',\n      difficulty: '\u4e2d\u7d1a',\n      practicalValue: '\u4e2d',\n      learningGoals: ['\u67e5\u770b\u539f\u59cb\u5167\u5bb9']\n    };\n  }\n\n  // \u8655\u7406\u6a19\u7c64\n  const processedTags = cleanAndProcessTags(\n    originalData?.tags || [], \n    aiAnalysis?.suggestedTags || []\n  );\n\n  // \u683c\u5f0f\u5316\u91cd\u9ede\u5217\u8868\n  const formattedKeyPoints = (aiAnalysis?.keyPoints || ['\u7121\u91cd\u9ede\u8cc7\u8a0a'])\n    .filter(point => point && point.length > 0)\n    .map(point => `\u2022 ${point}`)\n    .join('\\n');\n\n  // \u683c\u5f0f\u5316\u5b78\u7fd2\u76ee\u6a19\n  const formattedLearningGoals = (aiAnalysis?.learningGoals || ['\u5b78\u7fd2\u65b0\u77e5\u8b58'])\n    .filter(goal => goal && goal.length > 0)\n    .map(goal => `\ud83c\udfaf ${goal}`)\n    .join('\\n');\n\n  // \u78ba\u4fdd\u6240\u6709\u5fc5\u8981\u6b04\u4f4d\u90fd\u6709\u503c\n  const finalData = {\n    // \u57fa\u672c\u8cc7\u6599\n    title: originalData?.title || '\u7121\u6a19\u984c',\n    url: originalData?.link || '',\n    summary: aiAnalysis?.summary || '\u7121\u6458\u8981',\n    keyPoints: formattedKeyPoints || '\u2022 \u7121\u91cd\u9ede\u8cc7\u8a0a',\n    tags: processedTags,\n    priority: aiAnalysis?.priority || '\u4e2d',\n    readingTime: originalData?.estimatedReadTime || 5,\n    category: aiAnalysis?.category || '\u5176\u4ed6',\n    difficulty: aiAnalysis?.difficulty || '\u4e2d\u7d1a',\n    domain: originalData?.domain || '',\n    collectedDate: originalData?.created || new Date().toISOString(),\n    status: '\u672a\u8b80',\n    analysisType: 'AI',\n    \n    // AI \u7279\u6709\u7684\u984d\u5916\u8cc7\u8a0a\n    practicalValue: aiAnalysis?.practicalValue || '\u4e2d',\n    learningGoals: formattedLearningGoals || '\ud83c\udfaf \u5b78\u7fd2\u65b0\u77e5\u8b58',\n    \n    // API \u4f7f\u7528\u8cc7\u8a0a\n    tokensUsed: azureResponse?.usage?.total_tokens || 0,\n    aiModel: azureResponse?.model || 'o4-mini',\n    analysisTime: new Date().toISOString()\n  };\n\n  console.log(`\ud83d\udcca \u9805\u76ee ${i + 1} \u6700\u7d42\u6574\u5408\u8cc7\u6599:`);\n  console.log('\u6a19\u984c:', finalData.title);\n  console.log('\u6a19\u7c64:', finalData.tags);\n  console.log('\u5206\u985e:', finalData.category);\n  console.log('\u512a\u5148\u7d1a:', finalData.priority);\n\n  results.push({ json: finalData });\n}\n\nconsole.log(`\\n\ud83c\udfaf AI \u5206\u6790\u6574\u5408\u5b8c\u6210\uff0c\u5171 ${results.length} \u500b\u9805\u76ee`);\nreturn results;"
      },
      "id": "b0488b17-d26d-4b1b-b16c-9033b81f1418",
      "name": "\u6574\u5408 AI \u5206\u6790\u7d50\u679c",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -180,
        300
      ]
    },
    {
      "parameters": {
        "jsCode": "// \u57fa\u672c\u5206\u6790 - \u4fee\u6b63\u7248\u672c\uff08\u8655\u7406\u55ae\u7b46\u8cc7\u6599\uff09\nconst data = $input.first().json;\n\nconsole.log(`\ud83d\udcca \u57fa\u672c\u5206\u6790\uff1a${data?.title || '\u672a\u77e5\u6a19\u984c'}`);\n\n// \u5206\u6790\u5167\u5bb9\u51fd\u6578\nfunction analyzeContent(title, content, domain) {\n  let priority = '\u4e2d';\n  let difficulty = '\u521d\u7d1a';\n  let tags = [];\n  \n  const text = ((title || '') + ' ' + (content || '')).toLowerCase();\n  const lowerDomain = (domain || '').toLowerCase();\n  \n  // \u6839\u64da\u57df\u540d\u5224\u65b7\n  if (lowerDomain.includes('reddit.com')) {\n    tags.push('reddit', '\u793e\u7fa4\u8a0e\u8ad6');\n    if (text.includes('chatgptcoding') || text.includes('programming')) {\n      tags.push('\u7a0b\u5f0f\u8a2d\u8a08');\n      difficulty = '\u4e2d\u7d1a';\n      priority = '\u9ad8';\n    }\n  }\n  \n  if (lowerDomain.includes('facebook.com')) {\n    tags.push('facebook', '\u793e\u7fa4\u8a0e\u8ad6');\n    if (text.includes('ai') || text.includes('copilot')) {\n      tags.push('AI\u5de5\u5177');\n      priority = '\u9ad8';\n    }\n  }\n  \n  if (text.includes('webdev') || text.includes('javascript')) {\n    tags.push('\u524d\u7aef\u958b\u767c');\n    difficulty = '\u4e2d\u7d1a';\n  }\n  \n  if (text.includes('machinelearning') || text.includes('ai')) {\n    tags.push('ai');\n    priority = '\u9ad8';\n    difficulty = '\u9ad8\u7d1a';\n  }\n  \n  // \u6839\u64da\u6a19\u984c\u95dc\u9375\u5b57\n  if (text.includes('tutorial') || text.includes('guide')) {\n    tags.push('\u6559\u5b78');\n    priority = '\u9ad8';\n  }\n  \n  if (text.includes('tool') || text.includes('library')) {\n    tags.push('\u5de5\u5177');\n    priority = '\u4e2d';\n  }\n  \n  return { priority, difficulty, tags };\n}\n\n// Reddit \u5167\u5bb9\u7279\u6b8a\u8655\u7406\u51fd\u6578\nfunction analyzeRedditContent(title, domain, excerpt) {\n  let priority = '\u4e2d';\n  let difficulty = '\u521d\u7d1a';\n  let tags = ['reddit', '\u793e\u7fa4\u8a0e\u8ad6'];\n  \n  const text = ((title || '') + ' ' + (excerpt || '')).toLowerCase();\n  \n  // \u6839\u64da subreddit \u5224\u65b7\n  if (text.includes('chatgptcoding') || text.includes('programming')) {\n    tags.push('\u7a0b\u5f0f\u8a2d\u8a08');\n    difficulty = '\u4e2d\u7d1a';\n    priority = '\u9ad8';\n  }\n  \n  if (text.includes('webdev') || text.includes('javascript')) {\n    tags.push('\u524d\u7aef\u958b\u767c');\n    difficulty = '\u4e2d\u7d1a';\n  }\n  \n  if (text.includes('machinelearning') || text.includes('ai')) {\n    tags.push('ai');\n    priority = '\u9ad8';\n    difficulty = '\u9ad8\u7d1a';\n  }\n  \n  // \u6839\u64da\u6a19\u984c\u95dc\u9375\u5b57\n  if (text.includes('tutorial') || text.includes('guide')) {\n    tags.push('\u6559\u5b78');\n    priority = '\u9ad8';\n  }\n  \n  if (text.includes('tool') || text.includes('library')) {\n    tags.push('\u5de5\u5177');\n    priority = '\u4e2d';\n  }\n  \n  return { priority, difficulty, tags };\n}\n\nconst analysis = (data?.domain || '').includes('reddit.com') \n  ? analyzeRedditContent(data?.title, data?.domain, data?.raindropExcerpt)\n  : analyzeContent(data?.title, data?.cleanContent, data?.domain);\n\nreturn {\n  title: data?.title || '\u7121\u6a19\u984c',\n  url: data?.link || '',\n  summary: data?.raindropExcerpt || data?.metaDescription || '\u793e\u7fa4\u8a0e\u8ad6\u4e32\uff0c\u5efa\u8b70\u76f4\u63a5\u67e5\u770b\u539f\u59cb\u9023\u7d50\u4e86\u89e3\u8a73\u7d30\u5167\u5bb9',\n  keyPoints: `\u2022 \u793e\u7fa4\u8a0e\u8ad6\u5167\u5bb9\\n\u2022 \u4e3b\u984c\uff1a${data?.title || '\u672a\u77e5'}\\n\u2022 \u5efa\u8b70\u76f4\u63a5\u700f\u89bd\u539f\u59cb\u9023\u7d50`,\n  tags: [...(data?.tags || []), ...analysis.tags],\n  priority: analysis.priority,\n  readingTime: data?.estimatedReadTime || 3,\n  category: data?.detectedType || '\u793e\u7fa4\u8a0e\u8ad6',\n  difficulty: analysis.difficulty,\n  domain: data?.domain || '',\n  collectedDate: data?.created || new Date().toISOString(),\n  status: '\u672a\u8b80',\n  analysisType: 'Basic'\n};"
      },
      "id": "62463155-faaa-4f50-84e2-59e5e7b10b67",
      "name": "\u57fa\u672c\u5206\u6790",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -400,
        500
      ]
    },
    {
      "parameters": {},
      "id": "fb851800-7ffc-4622-9e24-466adaaa725c",
      "name": "\u5408\u4f75\u5206\u6790\u7d50\u679c",
      "type": "n8n-nodes-base.merge",
      "typeVersion": 2.1,
      "position": [
        40,
        400
      ]
    },
    {
      "parameters": {
        "resource": "databasePage",
        "databaseId": {
          "__rl": true,
          "value": "1ff930aa1b1280278ff5d95c98ce3ffd",
          "mode": ""
        },
        "propertiesUi": {
          "propertyValues": [
            {
              "key": "\u6a19\u984c|title",
              "title": "={{$json.title}}"
            },
            {
              "key": "\u9023\u7d50|url",
              "urlValue": "={{$json.url}}"
            },
            {
              "key": "\u6458\u8981|rich_text",
              "textContent": "={{$json.summary}}"
            },
            {
              "key": "\u91cd\u9ede|rich_text",
              "textContent": "={{$json.keyPoints}}"
            },
            {
              "key": "\u6a19\u7c64|multi_select",
              "multiSelectValue": "={{$json.tags}}"
            },
            {
              "key": "\u512a\u5148\u7d1a|select",
              "selectValue": "={{$json.priority}}"
            },
            {
              "key": "\u9810\u4f30\u95b1\u8b80\u6642\u9593|number",
              "numberValue": "={{$json.readingTime}}"
            },
            {
              "key": "\u5206\u985e|select",
              "selectValue": "={{$json.category}}"
            },
            {
              "key": "\u96e3\u5ea6|select",
              "selectValue": "={{$json.difficulty}}"
            },
            {
              "key": "\u4f86\u6e90\u7db2\u7ad9|rich_text",
              "textContent": "={{$json.domain}}"
            },
            {
              "key": "\u6536\u85cf\u65e5\u671f|date",
              "date": "={{$json.collectedDate}}"
            },
            {
              "key": "\u72c0\u614b|select",
              "selectValue": "={{$json.status}}"
            }
          ]
        },
        "blockUi": {
          "blockValues": [
            {
              "type": "heading_1",
              "richText": true,
              "text": {
                "text": [
                  {
                    "text": "={{$json.title}}",
                    "annotationUi": {
                      "bold": true,
                      "color": "blue"
                    }
                  }
                ]
              }
            },
            {
              "richText": true,
              "text": {
                "text": [
                  {
                    "text": "=\ud83c\udf10 \u4f86\u6e90\uff1a{{$json.domain}} | \ud83d\udcc5 {{new Date($json.collectedDate).toLocaleDateString('zh-TW')}} | \u23f1\ufe0f {{$json.readingTime}}\u5206\u9418",
                    "annotationUi": {
                      "italic": true,
                      "color": "gray"
                    }
                  }
                ]
              }
            },
            {
              "richText": true,
              "text": {
                "text": [
                  {
                    "text": "\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550",
                    "annotationUi": {
                      "color": "gray"
                    }
                  }
                ]
              }
            },
            {
              "type": "heading_2",
              "richText": true,
              "text": {
                "text": [
                  {
                    "text": "\ud83d\udca1 \u5167\u5bb9\u6458\u8981",
                    "annotationUi": {
                      "bold": true
                    }
                  }
                ]
              }
            },
            {
              "richText": true,
              "text": {
                "text": [
                  {
                    "text": "={{$json.summary}}",
                    "annotationUi": {
                      "color": "blue"
                    }
                  }
                ]
              }
            },
            {
              "type": "heading_2",
              "richText": true,
              "text": {
                "text": [
                  {
                    "text": "\ud83d\udccb \u91cd\u9ede\u6458\u8981",
                    "annotationUi": {
                      "bold": true
                    }
                  }
                ]
              }
            },
            {
              "richText": true,
              "text": {
                "text": [
                  {
                    "text": "={{$json.keyPoints}}",
                    "annotationUi": {}
                  }
                ]
              }
            },
            {
              "type": "heading_2",
              "richText": true,
              "text": {
                "text": [
                  {
                    "text": "\ud83c\udfaf \u5b78\u7fd2\u76ee\u6a19",
                    "annotationUi": {
                      "bold": true
                    }
                  }
                ]
              }
            },
            {
              "richText": true,
              "text": {
                "text": [
                  {
                    "text": "={{$json.learningGoals || '\ud83c\udfaf \u63a2\u7d22\u65b0\u77e5\u8b58\u8207\u6280\u80fd\\n\ud83c\udfaf \u63d0\u5347\u5c08\u696d\u80fd\u529b\\n\ud83c\udfaf \u5be6\u969b\u61c9\u7528\u6240\u5b78\u5167\u5bb9'}}",
                    "annotationUi": {
                      "color": "green"
                    }
                  }
                ]
              }
            },
            {
              "type": "heading_2",
              "richText": true,
              "text": {
                "text": [
                  {
                    "text": "\ud83d\udcca \u5167\u5bb9\u8a73\u7d30\u8cc7\u8a0a",
                    "annotationUi": {
                      "bold": true
                    }
                  }
                ]
              }
            },
            {
              "type": "bulleted_list_item",
              "richText": true,
              "text": {
                "text": [
                  {
                    "text": "=\ud83d\udcda \u5206\u985e\uff1a{{$json.category}}",
                    "annotationUi": {
                      "bold": true
                    }
                  }
                ]
              }
            },
            {
              "type": "bulleted_list_item",
              "richText": true,
              "text": {
                "text": [
                  {
                    "text": "=\u26a1 \u512a\u5148\u7d1a\uff1a{{$json.priority}}",
                    "annotationUi": {
                      "bold": true
                    }
                  }
                ]
              }
            },
            {
              "type": "bulleted_list_item",
              "richText": true,
              "text": {
                "text": [
                  {
                    "text": "=\ud83d\udcc8 \u96e3\u5ea6\u7b49\u7d1a\uff1a{{$json.difficulty}}",
                    "annotationUi": {
                      "bold": true
                    }
                  }
                ]
              }
            },
            {
              "type": "bulleted_list_item",
              "richText": true,
              "text": {
                "text": [
                  {
                    "text": "=\u23f1\ufe0f \u9810\u4f30\u95b1\u8b80\u6642\u9593\uff1a{{$json.readingTime}} \u5206\u9418",
                    "annotationUi": {
                      "bold": true
                    }
                  }
                ]
              }
            },
            {
              "type": "bulleted_list_item",
              "richText": true,
              "text": {
                "text": [
                  {
                    "text": "=\ud83e\udd16 \u5206\u6790\u65b9\u5f0f\uff1a{{$json.analysisType}}",
                    "annotationUi": {
                      "bold": true
                    }
                  }
                ]
              }
            },
            {
              "type": "heading_2",
              "richText": true,
              "text": {
                "text": [
                  {
                    "text": "\ud83c\udff7\ufe0f \u76f8\u95dc\u6a19\u7c64",
                    "annotationUi": {
                      "bold": true
                    }
                  }
                ]
              }
            },
            {
              "richText": true,
              "text": {
                "text": [
                  {
                    "text": "=={{$json.tags.join(' \u2022 ')}}",
                    "annotationUi": {
                      "code": true,
                      "color": "purple"
                    }
                  }
                ]
              }
            },
            {
              "richText": true,
              "text": {
                "text": [
                  {
                    "text": "\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550",
                    "annotationUi": {
                      "color": "gray"
                    }
                  }
                ]
              }
            },
            {
              "type": "heading_2",
              "richText": true,
              "text": {
                "text": [
                  {
                    "text": "\u2705 \u5b78\u7fd2\u9032\u5ea6\u8ffd\u8e64",
                    "annotationUi": {
                      "bold": true,
                      "color": "green"
                    }
                  }
                ]
              }
            },
            {
              "type": "to_do",
              "richText": true,
              "text": {
                "text": [
                  {
                    "text": "\ud83d\udcd6 \u521d\u6b65\u700f\u89bd\u5167\u5bb9",
                    "annotationUi": {
                      "bold": true
                    }
                  }
                ]
              }
            },
            {
              "type": "to_do",
              "richText": true,
              "text": {
                "text": [
                  {
                    "text": "\ud83d\udd0d \u6df1\u5165\u95b1\u8b80\u7406\u89e3",
                    "annotationUi": {
                      "bold": true
                    }
                  }
                ]
              }
            },
            {
              "type": "to_do",
              "richText": true,
              "text": {
                "text": [
                  {
                    "text": "\ud83d\udca1 \u638c\u63e1\u6838\u5fc3\u6982\u5ff5",
                    "annotationUi": {
                      "bold": true
                    }
                  }
                ]
              }
            },
            {
              "type": "to_do",
              "richText": true,
              "text": {
                "text": [
                  {
                    "text": "\ud83d\udee0\ufe0f \u52d5\u624b\u5be6\u4f5c\u7df4\u7fd2",
                    "annotationUi": {
                      "bold": true
                    }
                  }
                ]
              }
            },
            {
              "type": "to_do",
              "richText": true,
              "text": {
                "text": [
                  {
                    "text": "\ud83d\udcdd \u6574\u7406\u5b78\u7fd2\u7b46\u8a18",
                    "annotationUi": {
                      "bold": true
                    }
                  }
                ]
              }
            },
            {
              "type": "to_do",
              "richText": true,
              "text": {
                "text": [
                  {
                    "text": "\ud83d\udd04 \u8907\u7fd2\u4e26\u61c9\u7528",
                    "annotationUi": {
                      "bold": true
                    }
                  }
                ]
              }
            },
            {
              "type": "heading_2",
              "richText": true,
              "text": {
                "text": [
                  {
                    "text": "\ud83d\udcdd \u6211\u7684\u5b78\u7fd2\u7b46\u8a18",
                    "annotationUi": {
                      "bold": true,
                      "color": "yellow"
                    }
                  }
                ]
              }
            },
            {
              "richText": true,
              "text": {
                "text": [
                  {
                    "text": "\ud83d\udcad \u5728\u9019\u88e1\u8a18\u9304\u4f60\u7684\u5b78\u7fd2\u5fc3\u5f97\u3001\u91cd\u8981\u767c\u73fe\u548c\u500b\u4eba\u601d\u8003...",
                    "annotationUi": {
                      "italic": true,
                      "color": "gray"
                    }
                  }
                ]
              }
            },
            {},
            {},
            {
              "type": "heading_3",
              "richText": true,
              "text": {
                "text": [
                  {
                    "text": "\ud83e\udd14 \u5b78\u7fd2\u904e\u7a0b\u4e2d\u7684\u554f\u984c\u8207\u601d\u8003",
                    "annotationUi": {
                      "bold": true
                    }
                  }
                ]
              }
            },
            {
              "type": "bulleted_list_item"
            },
            {
              "type": "bulleted_list_item"
            },
            {
              "type": "heading_3",
              "richText": true,
              "text": {
                "text": [
                  {
                    "text": "\ud83d\udca1 \u5be6\u4f5c\u60f3\u6cd5\u8207\u61c9\u7528\u8a08\u756b",
                    "annotationUi": {
                      "bold": true
                    }
                  }
                ]
              }
            },
            {
              "type": "bulleted_list_item"
            },
            {
              "type": "bulleted_list_item"
            },
            {
              "type": "heading_3",
              "richText": true,
              "text": {
                "text": [
                  {
                    "text": "\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550",
                    "annotationUi": {
                      "color": "gray"
                    }
                  }
                ]
              }
            },
            {
              "type": "heading_2",
              "richText": true,
              "text": {
                "text": [
                  {
                    "text": "\ud83d\udd17 \u539f\u59cb\u5167\u5bb9\u9023\u7d50",
                    "annotationUi": {
                      "bold": true,
                      "color": "blue"
                    }
                  }
                ]
              }
            },
            {
              "richText": true,
              "text": {
                "text": [
                  {
                    "text": "=\ud83d\udd17 \u9ede\u64ca\u67e5\u770b\u539f\u59cb\u6587\u7ae0\uff1a{{$json.title}}",
                    "isLink": true,
                    "textLink": "={{$json.url}}",
                    "annotationUi": {
                      "bold": true,
                      "underline": true,
                      "color": "blue"
                    }
                  }
                ]
              }
            },
            {
              "richText": true,
              "text": {
                "text": [
                  {
                    "text": "=\ud83c\udf10 \u7db2\u5740\uff1a{{$json.url}}",
                    "annotationUi": {
                      "code": true,
                      "color": "gray"
                    }
                  }
                ]
              }
            },
            {
              "type": "heading_3",
              "richText": true,
              "text": {
                "text": [
                  {
                    "text": "\u2139\ufe0f \u7cfb\u7d71\u8cc7\u8a0a",
                    "annotationUi": {
                      "color": "gray"
                    }
                  }
                ]
              }
            },
            {
              "type": "bulleted_list_item",
              "richText": true,
              "text": {
                "text": [
                  {
                    "text": "=\ud83d\udcc5 \u6536\u85cf\u6642\u9593\uff1a{{new Date($json.collectedDate).toLocaleString('zh-TW')}}",
                    "annotationUi": {
                      "code": true
                    }
                  },
                  {
                    "text": "=\ud83e\udd16 AI \u6a21\u578b\uff1a{{$json.aiModel || 'N/A'}}",
                    "annotationUi": {
                      "code": true
                    }
                  },
                  {
                    "text": "=\ud83d\udd22 Token \u4f7f\u7528\u91cf\uff1a{{$json.tokensUsed || 0}}",
                    "annotationUi": {
                      "code": true
                    }
                  }
                ]
              }
            },
            {
              "richText": true,
              "text": {
                "text": [
                  {
                    "text": "\ud83e\udd16 \u6b64\u9801\u9762\u7531 AI \u81ea\u52d5\u751f\u6210\u5206\u6790\uff0c\u5305\u542b\u667a\u80fd\u6a19\u7c64\u3001\u91cd\u9ede\u6458\u8981\u548c\u500b\u4eba\u5316\u5b78\u7fd2\u5efa\u8b70\u3002\u6b61\u8fce\u5728\u7b46\u8a18\u5340\u57df\u8a18\u9304\u4f60\u7684\u60f3\u6cd5\uff01",
                    "annotationUi": {
                      "italic": true,
                      "color": "gray"
                    }
                  }
                ]
              }
            }
          ]
        },
        "options": {}
      },
      "id": "3be53dbd-e356-4957-b2fc-b0be0b1590ce",
      "name": "\u5b58\u5165 Notion \u8cc7\u6599\u5eab",
      "type": "n8n-nodes-base.notion",
      "typeVersion": 2,
      "position": [
        260,
        400
      ],
      "credentials": {
        "notionApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// \u5f37\u5316\u7248\u7db2\u9801\u6293\u53d6 - \u8655\u7406\u591a\u7b46\u8cc7\u6599\nconst items = $input.all();\nconst results = [];\n\nconsole.log(`\ud83c\udf10 \u6e96\u5099\u8655\u7406 ${items.length} \u500b\u9805\u76ee`);\n\n// \u70ba\u4e0d\u540c\u7db2\u7ad9\u8a2d\u5b9a\u4e0d\u540c\u7684\u6293\u53d6\u7b56\u7565\nfunction getRequestConfig(url, domain) {\n  const baseConfig = {\n    url: url,\n    method: 'GET',\n    timeout: 30000,\n    sendHeaders: true,\n    headerParameters: {\n      parameters: [\n        {\n          name: 'User-Agent',\n          value: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'\n        },\n        {\n          name: 'Accept',\n          value: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8'\n        },\n        {\n          name: 'Accept-Language',\n          value: 'en-US,en;q=0.9,zh-TW;q=0.8,zh;q=0.7'\n        },\n        {\n          name: 'Accept-Encoding',\n          value: 'gzip, deflate, br'\n        },\n        {\n          name: 'Connection',\n          value: 'keep-alive'\n        },\n        {\n          name: 'Upgrade-Insecure-Requests',\n          value: '1'\n        }\n      ]\n    },\n    options: {\n      response: {\n        response: {\n          responseFormat: 'text'\n        }\n      }\n    }\n  };\n\n  // \u91dd\u5c0d\u7279\u5b9a\u7db2\u7ad9\u7684\u7279\u6b8a\u8655\u7406\n  if (domain.includes('reddit.com')) {\n    // Reddit \u7279\u6b8a\u8655\u7406\n    baseConfig.headerParameters.parameters.push(\n      {\n        name: 'Referer',\n        value: 'https://www.reddit.com/'\n      },\n      {\n        name: 'DNT',\n        value: '1'\n      },\n      {\n        name: 'Sec-Fetch-Dest',\n        value: 'document'\n      },\n      {\n        name: 'Sec-Fetch-Mode',\n        value: 'navigate'\n      },\n      {\n        name: 'Sec-Fetch-Site',\n        value: 'same-origin'\n      }\n    );\n    \n    // \u5617\u8a66\u4f7f\u7528 old.reddit.com\n    if (!url.includes('old.reddit.com')) {\n      baseConfig.url = url.replace('www.reddit.com', 'old.reddit.com');\n      console.log(`\ud83d\udd04 \u6539\u7528 old.reddit.com\uff1a${baseConfig.url}`);\n    }\n  }\n  \n  if (domain.includes('twitter.com') || domain.includes('x.com')) {\n    // Twitter/X \u7279\u6b8a\u8655\u7406\n    baseConfig.headerParameters.parameters.push({\n      name: 'Referer',\n      value: 'https://twitter.com/'\n    });\n  }\n  \n  if (domain.includes('linkedin.com')) {\n    // LinkedIn \u7279\u6b8a\u8655\u7406\n    baseConfig.headerParameters.parameters.push({\n      name: 'Referer',\n      value: 'https://www.linkedin.com/'\n    });\n  }\n\n  return baseConfig;\n}\n\n// \u8655\u7406\u6bcf\u500b\u9805\u76ee\nfor (let i = 0; i < items.length; i++) {\n  const originalData = items[i].json;\n  const url = originalData.link;\n  const domain = originalData.domain || '';\n\n  console.log(`\\n\ud83d\udcc4 \u8655\u7406\u9805\u76ee ${i + 1}/${items.length}\uff1a${originalData.title}`);\n  console.log(`\ud83d\udccd \u7db2\u5740\uff1a${url}`);\n  console.log(`\ud83c\udfe0 \u57df\u540d\uff1a${domain}`);\n\n  // \u53d6\u5f97\u8acb\u6c42\u8a2d\u5b9a\n  const requestConfig = getRequestConfig(url, domain);\n\n  try {\n    // \u9032\u884c HTTP \u8acb\u6c42\n    const response = await $http.request(requestConfig);\n    \n    if (response.data) {\n      console.log(`\u2705 \u6210\u529f\u6293\u53d6\u5167\u5bb9\uff0c\u9577\u5ea6\uff1a${response.data.length} \u5b57\u5143`);\n      results.push({\n        json: {\n          ...originalData,\n          data: response.data,\n          fetchSuccess: true,\n          fetchedUrl: requestConfig.url,\n          fetchTime: new Date().toISOString()\n        }\n      });\n    } else {\n      console.log(`\u26a0\ufe0f \u56de\u61c9\u70ba\u7a7a`);\n      throw new Error('Empty response');\n    }\n    \n  } catch (error) {\n    console.log(`\u274c \u6293\u53d6\u5931\u6557\uff1a${error.message}`);\n    \n    // \u5982\u679c\u662f Reddit \u4e14\u7b2c\u4e00\u6b21\u5617\u8a66\u5931\u6557\uff0c\u5617\u8a66\u4e0d\u540c\u7684\u65b9\u6cd5\n    if (domain.includes('reddit.com') && !requestConfig.url.includes('old.reddit.com')) {\n      console.log(`\ud83d\udd04 \u5617\u8a66\u4f7f\u7528 old.reddit.com`);\n      \n      try {\n        const fallbackConfig = {\n          ...requestConfig,\n          url: url.replace('www.reddit.com', 'old.reddit.com').replace('reddit.com', 'old.reddit.com')\n        };\n        \n        const fallbackResponse = await $http.request(fallbackConfig);\n        \n        if (fallbackResponse.data) {\n          console.log(`\u2705 old.reddit.com \u6210\u529f\uff0c\u9577\u5ea6\uff1a${fallbackResponse.data.length} \u5b57\u5143`);\n          results.push({\n            json: {\n              ...originalData,\n              data: fallbackResponse.data,\n              fetchSuccess: true,\n              fetchedUrl: fallbackConfig.url,\n              fetchTime: new Date().toISOString(),\n              fallbackUsed: 'old.reddit.com'\n            }\n          });\n          continue; // \u6210\u529f\u5f8c\u8df3\u5230\u4e0b\u4e00\u500b\u9805\u76ee\n        }\n      } catch (fallbackError) {\n        console.log(`\u274c old.reddit.com \u4e5f\u5931\u6557\uff1a${fallbackError.message}`);\n      }\n    }\n    \n    // \u5982\u679c\u6293\u53d6\u5931\u6557\uff0c\u8fd4\u56de\u57fa\u672c\u8cc7\u8a0a\uff0c\u8b93\u5de5\u4f5c\u6d41\u7a0b\u7e7c\u7e8c\n    console.log(`\ud83d\udcdd \u6293\u53d6\u5931\u6557\uff0c\u4f7f\u7528 Raindrop \u6458\u8981\u4f5c\u70ba\u5f8c\u5099`);\n    results.push({\n      json: {\n        ...originalData,\n        data: `<html><head><title>${originalData.title}</title><meta name=\"description\" content=\"${originalData.excerpt}\"></head><body><p>${originalData.excerpt}</p></body></html>`,\n        fetchSuccess: false,\n        fetchError: error.message,\n        fetchTime: new Date().toISOString(),\n        usedFallback: true\n      }\n    });\n  }\n}\n\nconsole.log(`\\n\ud83c\udfaf \u8655\u7406\u5b8c\u6210\uff0c\u5171 ${results.length} \u500b\u9805\u76ee`);\nreturn results;"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -1040,
        400
      ],
      "id": "a2adc7a9-b643-42a3-a904-bf77dccde236",
      "name": "\u6293\u53d6\u7db2\u9801\u5167\u5bb9"
    }
  ],
  "connections": {
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "\u53d6\u5f97 Raindrop \u6536\u85cf",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u53d6\u5f97 Raindrop \u6536\u85cf": {
      "main": [
        [
          {
            "node": "\u7be9\u9078\u65b0\u9805\u76ee",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u7be9\u9078\u65b0\u9805\u76ee": {
      "main": [
        [
          {
            "node": "\u6293\u53d6\u7db2\u9801\u5167\u5bb9",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u8655\u7406\u5167\u5bb9": {
      "main": [
        [
          {
            "node": "\u662f\u5426\u4f7f\u7528 AI \u5206\u6790",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u662f\u5426\u4f7f\u7528 AI \u5206\u6790": {
      "main": [
        [
          {
            "node": "Azure AI \u5167\u5bb9\u5206\u6790",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "\u57fa\u672c\u5206\u6790",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Azure AI \u5167\u5bb9\u5206\u6790": {
      "main": [
        [
          {
            "node": "\u6574\u5408 AI \u5206\u6790\u7d50\u679c",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u6574\u5408 AI \u5206\u6790\u7d50\u679c": {
      "main": [
        [
          {
            "node": "\u5408\u4f75\u5206\u6790\u7d50\u679c",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u57fa\u672c\u5206\u6790": {
      "main": [
        [
          {
            "node": "\u5408\u4f75\u5206\u6790\u7d50\u679c",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "\u5408\u4f75\u5206\u6790\u7d50\u679c": {
      "main": [
        [
          {
            "node": "\u5b58\u5165 Notion \u8cc7\u6599\u5eab",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u6293\u53d6\u7db2\u9801\u5167\u5bb9": {
      "main": [
        [
          {
            "node": "\u8655\u7406\u5167\u5bb9",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": true,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "7f2db0e4-5103-4b3b-9897-deb9ac3d8165",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "id": "E1OK2GVGla40YBIp",
  "tags": [
    {
      "name": "raindrop",
      "id": "67ge26Co3u11nufo",
      "createdAt": "2025-05-27T17:26:59.646Z",
      "updatedAt": "2025-05-27T17:26:59.646Z"
    },
    {
      "name": "notion",
      "id": "jJONDkvSm8dw29BK",
      "createdAt": "2025-05-27T17:27:01.909Z",
      "updatedAt": "2025-05-27T17:27:01.909Z"
    },
    {
      "name": "knowledge",
      "id": "qU6ml7ppBu4zvXak",
      "createdAt": "2025-05-27T17:27:08.636Z",
      "updatedAt": "2025-05-27T17:27:08.636Z"
    }
  ]
}

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.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

Raindrop Knowledge Management. Uses httpRequest, notion. Scheduled trigger; 11 nodes.

Source: https://github.com/lettucebo/N8N-Flows/blob/52ab732270953f61117544747dae01a81fdde982/flows/RaindropKnowledgeManagement/Raindrop_Knowledge_Management.json — original creator credit. Request a take-down →

More Data & Sheets workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

Data & Sheets

This template is designed for social media managers, content creators, data analysts, and anyone who wants to automatically save and analyze their Meta Threads posts in Notion.

HTTP Request, Notion
Data & Sheets

&gt; Transform your content strategy with automated competitor intelligence

HTTP Request, Airtable, Notion +2
Data & Sheets

⚠️ COMMUNITY TEMPLATE DISCLAIMER: This is a community-contributed template that uses ScrapeGraphAI (a community node). Please ensure you have the ScrapeGraphAI community node installed in your n8n ins

N8N Nodes Scrapegraphai, HTTP Request, Notion +1
Data & Sheets

n8n workflows can go out of hand when you're automating as much as we do at n8n. We needed a place to document them and keep track of who owns and maintains them. To facilitate this we use this n8n wo

n8n, HTTP Request, Notion
Data & Sheets

Opportunity Radar Weekly. Uses httpRequest, notion. Scheduled trigger; 8 nodes.

HTTP Request, Notion