Agrégateur de contenu d'apprentissage personnalisé avec filtres IA

Avancé

Ceci est unMarket Research, AI Summarizationworkflow d'automatisation du domainecontenant 18 nœuds.Utilise principalement des nœuds comme Set, Code, Merge, HttpRequest, RssFeedRead. Filtrer le contenu d'apprentissage à partir de Reddit et RSS avec GPT-4.1-mini et Google Sheets

Prérequis
  • Peut nécessiter les informations d'identification d'authentification de l'API cible
  • Informations d'identification Google Sheets API
  • Clé API OpenAI
Aperçu du workflow
Visualisation des connexions entre les nœuds, avec support du zoom et du déplacement
Exporter le workflow
Copiez la configuration JSON suivante dans n8n pour importer et utiliser ce workflow
{
  "id": "SPMdOPACsv0whzC1",
  "meta": {
    "instanceId": "15d6057a37b8367f33882dd60593ee5f6cc0c59310ff1dc66b626d726083b48d",
    "templateCredsSetupCompleted": true
  },
  "name": "Personalized Learning Content Aggregator with AI Filtering",
  "tags": [],
  "nodes": [
    {
      "id": "530285ce-4719-441a-9027-a5a1f55454f8",
      "name": "Déclencheur programmé - Deux fois par jour",
      "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": "Configuration du workflow",
      "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": "Obtenir les mots-clés depuis 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": "Boucle sur les mots-clés",
      "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": "Rechercher les flux 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": "Fusionner tous les résultats",
      "type": "n8n-nodes-base.merge",
      "position": [
        1264,
        176
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineAll"
      },
      "typeVersion": 3.2
    },
    {
      "id": "7b189ca5-cd33-42fb-a415-6573cba65dd8",
      "name": "Préparer les articles pour l'IA",
      "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": "Filtre de contenu IA",
      "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": "Analyser la réponse IA",
      "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": "Modèle de chat 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": "Rechercher Reddit via API",
      "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": "Sauvegarder dans 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": "Aperçu du modèle",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -352,
        64
      ],
      "parameters": {
        "width": 560,
        "height": 896,
        "content": "## Personalized Learning Content Aggregator with AI Filtering\n\n### Who’s it for\nThis workflow is for learners, educators, and professionals who want to automatically collect and filter the most relevant educational articles, tutorials, and resources based on specific keywords.\n\n### How it works\n- Fetches content from RSS feeds and Reddit based on user-defined keywords.\n- AI analyzes and filters the articles to keep only **relevant, educational, and non-promotional** posts.\n- Saves curated results into a Google Sheet for easy review.\n\n### How to set up\n1. Connect your **Google Sheets** and **AI** (OpenAI or LangChain) credentials.\n2. Add your RSS feed URLs and keywords to Google Sheets.\n3. Adjust schedule timing in the trigger node (default: 8 AM & 6 PM daily).\n4. Run the workflow and check the results in your Google Sheet.\n\n### Requirements\n- Google Sheets account for storage.\n- RSS feed URLs and keyword list.\n- AI node (OpenAI / Gemini / Claude) for filtering logic.\n\n### How to customize\n- Change or add new content sources (e.g., YouTube, Medium, Dev.to).\n- Adjust AI prompt criteria to match your learning goals.\n- Save results to other platforms (e.g., Notion, Slack, or Airtable).\n\n**Note:** This workflow uses no personal identifiers or API keys directly in nodes. All credentials are safely stored in n8n’s credential manager."
      },
      "typeVersion": 1
    },
    {
      "id": "57735186-ac1c-45cb-a685-1fa0aba45fc5",
      "name": "Note de configuration",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        368,
        176
      ],
      "parameters": {
        "content": "Holds the RSS feed URLs and user-defined keywords from Google Sheets."
      },
      "typeVersion": 1
    },
    {
      "id": "50c96cef-b37c-44fa-930a-bafbb2f1b0f9",
      "name": "Note de récupération Reddit",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        960,
        464
      ],
      "parameters": {
        "height": 128,
        "content": "Fetches learning-related posts from Reddit via public API based on keywords."
      },
      "typeVersion": 1
    },
    {
      "id": "461e1737-57fa-4116-a0c9-83d5c02136ff",
      "name": "Note de fusion",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1248,
        48
      ],
      "parameters": {
        "content": "Combines results from all content sources (RSS + Reddit) for unified AI filtering."
      },
      "typeVersion": 1
    },
    {
      "id": "85ed87bf-4ecf-4ceb-9cdd-6d66712b1ccf",
      "name": "Note de filtre IA",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1712,
        16
      ],
      "parameters": {
        "content": "AI analyzes articles and keeps only high-quality, relevant educational content."
      },
      "typeVersion": 1
    },
    {
      "id": "3cc34535-4907-4957-92fa-11ae789bdcec",
      "name": "Note de sauvegarde des résultats",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2208,
        32
      ],
      "parameters": {
        "content": "Saves the final curated articles to your connected Google Sheet automatically."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "efbba744-6c3b-4fd9-b47b-f5e3b08a8256",
  "connections": {
    "91891a18-73a3-4582-af3f-a932483dd8e2": {
      "main": [
        [
          {
            "node": "fa1e5bad-c831-42d8-a246-a694b5ff11f4",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "04657aeb-6396-46a1-8457-174cbd5380d6": {
      "main": [
        [
          {
            "node": "047ef445-5190-4a41-83cc-535cc0419149",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "ccc0797d-0636-4027-98e0-6aae1e8ecb58": {
      "ai_languageModel": [
        [
          {
            "node": "04657aeb-6396-46a1-8457-174cbd5380d6",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "047ef445-5190-4a41-83cc-535cc0419149": {
      "main": [
        [
          {
            "node": "578fc36c-a9d8-4893-821d-7cbb04a6174d",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "bf214976-ba37-435f-8191-1d6af7ed0159": {
      "main": [
        [
          {
            "node": "91891a18-73a3-4582-af3f-a932483dd8e2",
            "type": "main",
            "index": 0
          },
          {
            "node": "8c4b9ba8-1478-4a8a-96fc-93971fd97d7b",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "8c4b9ba8-1478-4a8a-96fc-93971fd97d7b": {
      "main": [
        [
          {
            "node": "fa1e5bad-c831-42d8-a246-a694b5ff11f4",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "01138c7e-b68b-4772-bb47-ff096170fad2": {
      "main": [
        [
          {
            "node": "f752f79f-3242-49bd-9ad9-536aadf3ecda",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "7b189ca5-cd33-42fb-a415-6573cba65dd8": {
      "main": [
        [
          {
            "node": "04657aeb-6396-46a1-8457-174cbd5380d6",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "fa1e5bad-c831-42d8-a246-a694b5ff11f4": {
      "main": [
        [
          {
            "node": "7b189ca5-cd33-42fb-a415-6573cba65dd8",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "530285ce-4719-441a-9027-a5a1f55454f8": {
      "main": [
        [
          {
            "node": "01138c7e-b68b-4772-bb47-ff096170fad2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "f752f79f-3242-49bd-9ad9-536aadf3ecda": {
      "main": [
        [
          {
            "node": "bf214976-ba37-435f-8191-1d6af7ed0159",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Foire aux questions

Comment utiliser ce workflow ?

Copiez le code de configuration JSON ci-dessus, créez un nouveau workflow dans votre instance n8n et sélectionnez "Importer depuis le JSON", collez la configuration et modifiez les paramètres d'authentification selon vos besoins.

Dans quelles scénarios ce workflow est-il adapté ?

Avancé - Étude de marché, Résumé IA

Est-ce payant ?

Ce workflow est entièrement gratuit et peut être utilisé directement. Veuillez noter que les services tiers utilisés dans le workflow (comme l'API OpenAI) peuvent nécessiter un paiement de votre part.

Informations sur le workflow
Niveau de difficulté
Avancé
Nombre de nœuds18
Catégorie2
Types de nœuds10
Description de la difficulté

Adapté aux utilisateurs avancés, avec des workflows complexes contenant 16+ nœuds

Liens externes
Voir sur n8n.io

Partager ce workflow

Catégories

Catégories: 34