This workflow follows the Agent → HTTP Request 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 →
{
"name": "RSS Collector - Scraping and Validation",
"nodes": [
{
"parameters": {
"rule": {
"interval": [
{
"field": "hours",
"hoursInterval": 6
}
]
}
},
"id": "schedule-trigger",
"name": "Schedule Trigger - 6h",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.2,
"position": [
250,
300
]
},
{
"parameters": {
"authentication": "serviceAccount",
"resource": "row",
"operation": "get",
"tableId": "rss_sources",
"returnAll": true,
"filterType": "string",
"filterString": "ativo=eq.true"
},
"id": "get-rss-sources",
"name": "Buscar Fontes RSS Ativas",
"type": "n8n-nodes-base.supabase",
"typeVersion": 1,
"position": [
450,
300
],
"credentials": {
"supabaseApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"batchSize": 1,
"options": {}
},
"id": "split-sources",
"name": "Loop Over RSS Sources",
"type": "n8n-nodes-base.splitInBatches",
"typeVersion": 3,
"position": [
650,
300
]
},
{
"parameters": {
"url": "={{ $json.url_feed }}",
"options": {
"quantity": 20
}
},
"id": "rss-feed-read",
"name": "Ler Feed RSS",
"type": "n8n-nodes-base.rssFeedRead",
"typeVersion": 1,
"position": [
850,
300
]
},
{
"parameters": {
"jsCode": "// Extrair e preparar dados dos itens do feed\nconst items = $input.all();\nconst feedItems = [];\nconst sourceData = $('Loop Over RSS Sources').item.json;\n\nfor (const item of items) {\n feedItems.push({\n url_original: item.json.link,\n titulo_original: item.json.title,\n descricao: item.json.description || item.json.contentSnippet || '',\n data_publicacao: item.json.pubDate || item.json.isoDate || new Date().toISOString(),\n rss_source_id: sourceData.id,\n rss_source_nome: sourceData.nome,\n config_scraping: sourceData.config_scraping || {}\n });\n}\n\nreturn feedItems.map(item => ({ json: item }));"
},
"id": "extract-feed-data",
"name": "Extrair URLs dos Itens",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1050,
300
]
},
{
"parameters": {
"batchSize": 1,
"options": {}
},
"id": "split-feed-items",
"name": "Loop Over Feed Items",
"type": "n8n-nodes-base.splitInBatches",
"typeVersion": 3,
"position": [
1250,
300
]
},
{
"parameters": {
"jsCode": "// Preparar dados para verifica\u00e7\u00e3o de duplicatas\nconst currentItem = $json;\n\n// Garantir que temos os dados necess\u00e1rios\nif (!currentItem.url_original) {\n throw new Error('url_original n\u00e3o encontrado no item atual');\n}\n\nreturn [{\n json: {\n url_original: currentItem.url_original,\n titulo_original: currentItem.titulo_original || '',\n descricao: currentItem.descricao || '',\n data_publicacao: currentItem.data_publicacao || new Date().toISOString(),\n rss_source_id: currentItem.rss_source_id,\n rss_source_nome: currentItem.rss_source_nome || '',\n config_scraping: currentItem.config_scraping || {}\n }\n}];"
},
"id": "prepare-duplicate-check",
"name": "Preparar Dados para Verifica\u00e7\u00e3o",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1450,
300
]
},
{
"parameters": {
"authentication": "serviceAccount",
"resource": "row",
"operation": "get",
"tableId": "materias_originais",
"returnAll": false,
"limit": 1,
"filterType": "string",
"filterString": "=url_original=eq.{{ $json.url_original }}"
},
"id": "check-duplicates",
"name": "Verificar Duplicatas",
"type": "n8n-nodes-base.supabase",
"typeVersion": 1,
"position": [
1650,
300
],
"credentials": {
"supabaseApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict"
},
"conditions": [
{
"id": "not-exists",
"leftValue": "={{ $json.id }}",
"rightValue": "",
"operator": {
"type": "string",
"operation": "isEmpty"
}
}
],
"combinator": "and"
},
"options": {}
},
"id": "if-not-duplicate",
"name": "IF: URL n\u00e3o existe?",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
1850,
300
]
},
{
"parameters": {
"method": "GET",
"url": "={{ $('Extrair URLs dos Itens').item.json.url_original }}",
"options": {
"headers": {
"entries": [
{
"name": "User-Agent",
"value": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
}
]
},
"timeout": 30000,
"response": {
"response": {
"responseFormat": "text"
}
}
}
},
"id": "scrape-content",
"name": "Scraping do Conte\u00fado",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
2050,
200
],
"continueOnFail": true
},
{
"parameters": {
"jsCode": "// Preparar seletores CSS baseado na config ou usar defaults\nconst feedData = $('Preparar Dados para Verifica\u00e7\u00e3o').item.json;\nconst configScraping = feedData.config_scraping || {};\n\nconst htmlContent = $json.data || '';\n\nreturn [{\n json: {\n html: htmlContent,\n url_original: feedData.url_original,\n titulo_original: feedData.titulo_original,\n data_publicacao: feedData.data_publicacao,\n rss_source_id: feedData.rss_source_id,\n rss_source_nome: feedData.rss_source_nome,\n seletor_titulo: configScraping.seletor_titulo || 'h1, .post-title, .entry-title, article h1, .article-title',\n seletor_conteudo: configScraping.seletor_conteudo || 'article, .post-content, .entry-content, .content, main, .article-body',\n seletor_imagem: configScraping.seletor_imagem || 'meta[property=\"og:image\"], .featured-image img, article img:first-of-type'\n }\n}];"
},
"id": "prepare-selectors",
"name": "Preparar Seletores CSS",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2250,
200
]
},
{
"parameters": {
"jsCode": "// Extrair conte\u00fado usando seletores CSS\nconst { JSDOM } = require('jsdom');\nconst html = $json.html;\nconst dom = new JSDOM(html);\nconst document = dom.window.document;\n\n// Fun\u00e7\u00e3o auxiliar para extrair texto\nfunction extractText(selector) {\n const elements = document.querySelectorAll(selector);\n for (const el of elements) {\n if (el && el.textContent.trim()) {\n return el.textContent.trim();\n }\n }\n return '';\n}\n\n// Fun\u00e7\u00e3o auxiliar para extrair HTML\nfunction extractHTML(selector) {\n const elements = document.querySelectorAll(selector);\n for (const el of elements) {\n if (el && el.innerHTML.trim()) {\n return el.innerHTML.trim();\n }\n }\n return '';\n}\n\n// Fun\u00e7\u00e3o auxiliar para extrair atributo de imagem\nfunction extractImage(selector) {\n const elements = document.querySelectorAll(selector);\n for (const el of elements) {\n if (el) {\n return el.getAttribute('content') || el.getAttribute('src') || '';\n }\n }\n return '';\n}\n\nconst tituloExtraido = extractText($json.seletor_titulo);\nconst conteudoHTML = extractHTML($json.seletor_conteudo);\nconst imagemDestaque = extractImage($json.seletor_imagem);\n\nreturn [{\n json: {\n url_original: $json.url_original,\n titulo_original: tituloExtraido || $json.titulo_original,\n conteudo_html: conteudoHTML,\n imagem_destaque: imagemDestaque,\n data_publicacao: $json.data_publicacao,\n rss_source_id: $json.rss_source_id,\n rss_source_nome: $json.rss_source_nome\n }\n}];"
},
"id": "extract-with-css",
"name": "Extrair com Seletores",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2450,
200
]
},
{
"parameters": {
"jsCode": "// Limpar HTML e extrair apenas texto\nfunction cleanHTML(html) {\n if (!html) return '';\n \n // Remover scripts, styles e comments\n let text = html.replace(/<script\\b[^<]*(?:(?!<\\/script>)<[^<]*)*<\\/script>/gi, '');\n text = text.replace(/<style\\b[^<]*(?:(?!<\\/style>)<[^<]*)*<\\/style>/gi, '');\n text = text.replace(/<!--[\\s\\S]*?-->/g, '');\n \n // Adicionar quebras de linha antes de elementos block\n text = text.replace(/<\\/(p|div|h[1-6]|li|td|tr|section|article)>/gi, '\\n');\n text = text.replace(/<br\\s*\\/?>/gi, '\\n');\n \n // Remover todas as tags HTML\n text = text.replace(/<[^>]+>/g, ' ');\n \n // Decodificar entidades HTML comuns\n text = text.replace(/ /g, ' ');\n text = text.replace(/&/g, '&');\n text = text.replace(/</g, '<');\n text = text.replace(/>/g, '>');\n text = text.replace(/"/g, '\"');\n text = text.replace(/'/g, \"'\");\n text = text.replace(/'/g, \"'\");\n \n // Remover m\u00faltiplos espa\u00e7os e quebras de linha\n text = text.replace(/[ \\t]+/g, ' ');\n text = text.replace(/\\n\\s*\\n/g, '\\n\\n');\n text = text.trim();\n \n // Limitar a 15000 caracteres para an\u00e1lise da IA\n return text.substring(0, 15000);\n}\n\nconst conteudoLimpo = cleanHTML($json.conteudo_html);\nconst tituloFinal = $json.titulo_original;\n\n// Validar se tem conte\u00fado m\u00ednimo\nif (conteudoLimpo.length < 300) {\n throw new Error('Conte\u00fado muito curto (menos de 300 caracteres)');\n}\n\nreturn [{\n json: {\n url_original: $json.url_original,\n titulo_original: tituloFinal,\n conteudo_original: conteudoLimpo,\n imagem_destaque: $json.imagem_destaque,\n data_publicacao: $json.data_publicacao,\n rss_source_id: $json.rss_source_id,\n rss_source_nome: $json.rss_source_nome\n }\n}];"
},
"id": "clean-html",
"name": "Limpar HTML",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2650,
200
],
"continueOnFail": true
},
{
"parameters": {
"promptType": "define",
"text": "=**T\u00edtulo:** {{ $json.titulo_original }}\n\n**Conte\u00fado (primeiros 5000 caracteres):**\n{{ $json.conteudo_original.substring(0, 5000) }}\n\n**Fonte:** {{ $json.rss_source_nome }}\n\n**Responda APENAS com JSON no formato:**\n{\n \"relevante\": true ou false,\n \"motivo\": \"explica\u00e7\u00e3o breve em 1 linha\",\n \"categoria_sugerida\": \"tecnologia\" ou \"marketing\" ou \"ia\" ou \"automacao\" ou \"outro\",\n \"confianca\": 0.0 a 1.0\n}",
"options": {
"systemMessage": "Voc\u00ea \u00e9 um agente especializado em avaliar a relev\u00e2ncia de conte\u00fados para um blog de tecnologia, marketing digital, automa\u00e7\u00e3o e IA.\n\nAnalise o artigo fornecido e determine se ele \u00e9 RELEVANTE ou N\u00c3O RELEVANTE.\n\n**Crit\u00e9rios de Relev\u00e2ncia:**\n\u2705 RELEVANTE se for sobre:\n- Tecnologia, programa\u00e7\u00e3o, desenvolvimento web/mobile\n- Intelig\u00eancia Artificial, Machine Learning, automa\u00e7\u00e3o\n- Marketing digital, SEO, redes sociais\n- Neg\u00f3cios digitais, empreendedorismo tech\n- Inova\u00e7\u00e3o, tend\u00eancias tecnol\u00f3gicas\n- Produtividade, ferramentas, software\n\n\u274c N\u00c3O RELEVANTE se for sobre:\n- Pol\u00edtica, esportes, entretenimento\n- Fofocas, celebridades\n- Conte\u00fado muito curto ou superficial\n- Spam, conte\u00fado promocional excessivo\n- Temas completamente fora do escopo tech/marketing\n\n**IMPORTANTE:** Responda APENAS com um JSON v\u00e1lido, sem markdown, sem explica\u00e7\u00f5es adicionais."
}
},
"id": "ai-relevance",
"name": "IA: Avaliar Relev\u00e2ncia",
"type": "@n8n/n8n-nodes-langchain.agent",
"typeVersion": 1.3,
"position": [
2850,
200
]
},
{
"parameters": {
"options": {
"temperature": 0.3,
"maxOutputTokens": 500
}
},
"id": "gemini-model",
"name": "Google Gemini Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"typeVersion": 1,
"position": [
2850,
400
],
"credentials": {
"googlePalmApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "// Parsear e validar resposta da IA\nlet avaliacaoIA;\nconst feedData = $('Limpar HTML').item.json;\n\ntry {\n // AI Agent retorna a resposta no campo 'output'\n const agentOutput = $json.output || $json.message || $json.text || $json.content || '';\n \n // Tentar parsear como JSON\n if (typeof agentOutput === 'object') {\n avaliacaoIA = agentOutput;\n } else if (typeof agentOutput === 'string') {\n // Extrair JSON do texto (pode vir com markdown ou texto adicional)\n const jsonMatch = agentOutput.match(/\\{[\\s\\S]*\\}/);\n if (jsonMatch) {\n avaliacaoIA = JSON.parse(jsonMatch[0]);\n } else {\n throw new Error('Resposta da IA n\u00e3o cont\u00e9m JSON v\u00e1lido');\n }\n } else {\n throw new Error('Formato de resposta inesperado');\n }\n \n // Validar campos obrigat\u00f3rios\n if (typeof avaliacaoIA.relevante !== 'boolean') {\n avaliacaoIA.relevante = false;\n avaliacaoIA.motivo = 'Resposta inv\u00e1lida da IA';\n }\n \n} catch (error) {\n console.error('Erro ao processar resposta da IA:', error.message);\n console.error('Resposta recebida:', JSON.stringify($json, null, 2));\n avaliacaoIA = {\n relevante: false,\n motivo: 'Erro ao processar resposta: ' + error.message,\n categoria_sugerida: 'outro',\n confianca: 0\n };\n}\n\nreturn [{\n json: {\n ...feedData,\n relevante: avaliacaoIA.relevante === true,\n motivo_ia: avaliacaoIA.motivo || 'Sem motivo especificado',\n categoria_sugerida: avaliacaoIA.categoria_sugerida || 'outro',\n confianca_ia: avaliacaoIA.confianca || 0.5\n }\n}];"
},
"id": "parse-ai-response",
"name": "Parsear Resposta IA",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
3050,
200
]
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict"
},
"conditions": [
{
"id": "is-relevant",
"leftValue": "={{ $json.relevante }}",
"rightValue": "true",
"operator": {
"type": "boolean",
"operation": "equals"
}
}
],
"combinator": "and"
},
"options": {}
},
"id": "if-relevant",
"name": "IF: Conte\u00fado Relevante?",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
3250,
200
]
},
{
"parameters": {
"authentication": "serviceAccount",
"resource": "row",
"operation": "create",
"tableId": "materias_originais",
"dataMode": "defineBelow",
"fieldsUi": {
"fieldValues": [
{
"fieldName": "rss_source_id",
"fieldValue": "={{ $json.rss_source_id }}"
},
{
"fieldName": "url_original",
"fieldValue": "={{ $json.url_original }}"
},
{
"fieldName": "titulo_original",
"fieldValue": "={{ $json.titulo_original }}"
},
{
"fieldName": "conteudo_original",
"fieldValue": "={{ $json.conteudo_original }}"
},
{
"fieldName": "data_publicacao",
"fieldValue": "={{ $json.data_publicacao }}"
},
{
"fieldName": "processado",
"fieldValue": "false"
},
{
"fieldName": "relevante",
"fieldValue": "true"
}
]
}
},
"id": "save-materia",
"name": "Salvar Mat\u00e9ria no Banco",
"type": "n8n-nodes-base.supabase",
"typeVersion": 1,
"position": [
3450,
100
],
"credentials": {
"supabaseApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"method": "POST",
"url": "={{ $env.N8N_WEBHOOK_BASE_URL }}/gerar-conteudo",
"options": {
"headers": {
"entries": [
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"bodyParameters": {
"parameters": [
{
"name": "materia_id",
"value": "={{ $json.id }}"
},
{
"name": "titulo_original",
"value": "={{ $('Parsear Resposta IA').item.json.titulo_original }}"
},
{
"name": "conteudo_original",
"value": "={{ $('Parsear Resposta IA').item.json.conteudo_original }}"
},
{
"name": "rss_source_nome",
"value": "={{ $('Parsear Resposta IA').item.json.rss_source_nome }}"
},
{
"name": "categoria",
"value": "={{ $('Parsear Resposta IA').item.json.categoria_sugerida }}"
}
]
}
},
"sendBody": true,
"bodyContentType": "json"
},
"id": "trigger-content-generation",
"name": "Disparar Gera\u00e7\u00e3o de Conte\u00fado",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
3650,
100
],
"continueOnFail": true
},
{
"parameters": {
"jsCode": "// Log de sucesso\nconst materia = $('Parsear Resposta IA').item.json;\nconst saved = $json;\n\nconsole.log(`\u2705 Mat\u00e9ria salva com sucesso!`);\nconsole.log(`\ud83d\udcdd T\u00edtulo: ${materia.titulo_original}`);\nconsole.log(`\ud83c\udd94 ID: ${saved.id}`);\nconsole.log(`\ud83d\udd17 URL: ${materia.url_original}`);\nconsole.log(`\ud83e\udd16 Motivo IA: ${materia.motivo_ia}`);\nconsole.log(`\ud83d\udcc1 Categoria: ${materia.categoria_sugerida}`);\nconsole.log(`\ud83d\udcca Confian\u00e7a: ${(materia.confianca_ia * 100).toFixed(1)}%`);\n\nreturn [{\n json: {\n status: 'sucesso',\n materia_id: saved.id,\n titulo: materia.titulo_original,\n url: materia.url_original,\n categoria: materia.categoria_sugerida,\n timestamp: new Date().toISOString()\n }\n}];"
},
"id": "log-success",
"name": "Log de Sucesso",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
3850,
100
]
},
{
"parameters": {
"jsCode": "// Log de conte\u00fado irrelevante\nconst data = $json;\n\nconsole.log(`\u26a0\ufe0f Conte\u00fado marcado como IRRELEVANTE`);\nconsole.log(`\ud83d\udcdd T\u00edtulo: ${data.titulo_original}`);\nconsole.log(`\ud83d\udd17 URL: ${data.url_original}`);\nconsole.log(`\u274c Motivo: ${data.motivo_ia}`);\nconsole.log(`\ud83d\udcc1 Categoria: ${data.categoria_sugerida}`);\n\nreturn [{\n json: {\n status: 'ignorado',\n motivo: data.motivo_ia,\n titulo: data.titulo_original\n }\n}];"
},
"id": "log-irrelevant",
"name": "Log Irrelevante",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
3450,
300
]
},
{
"parameters": {
"jsCode": "// Estat\u00edsticas finais do processamento\nconst sourcesNode = $('Buscar Fontes RSS Ativas');\nconst feedNode = $('Ler Feed RSS');\nconst newItemsNode = $('IF: URL n\u00e3o existe?');\nconst relevantNode = $('IF: Conte\u00fado Relevante?');\nconst savedNode = $('Salvar Mat\u00e9ria no Banco');\n\nconst stats = {\n feeds_processados: sourcesNode.itemCount || 0,\n artigos_encontrados: feedNode.itemCount || 0,\n artigos_novos: newItemsNode.itemCount || 0,\n artigos_relevantes: relevantNode.itemCount || 0,\n artigos_salvos: savedNode.itemCount || 0,\n taxa_relevancia: newItemsNode.itemCount > 0 \n ? ((relevantNode.itemCount / newItemsNode.itemCount) * 100).toFixed(1) + '%'\n : '0%',\n timestamp: new Date().toISOString(),\n duracao: '{{ $execution.duration }}ms'\n};\n\nconsole.log('\\n\ud83d\udcca ========== ESTAT\u00cdSTICAS DO PROCESSAMENTO RSS ==========');\nconsole.log(`\ud83d\udd04 Feeds processados: ${stats.feeds_processados}`);\nconsole.log(`\ud83d\udcf0 Artigos encontrados: ${stats.artigos_encontrados}`);\nconsole.log(`\ud83c\udd95 Artigos novos (n\u00e3o duplicados): ${stats.artigos_novos}`);\nconsole.log(`\u2705 Artigos relevantes: ${stats.artigos_relevantes}`);\nconsole.log(`\ud83d\udcbe Artigos salvos: ${stats.artigos_salvos}`);\nconsole.log(`\ud83d\udcc8 Taxa de relev\u00e2ncia: ${stats.taxa_relevancia}`);\nconsole.log(`\u23f1\ufe0f Dura\u00e7\u00e3o total: ${stats.duracao}`);\nconsole.log(`\ud83d\udd50 Timestamp: ${stats.timestamp}`);\nconsole.log('========================================================\\n');\n\nreturn [{ json: stats }];"
},
"id": "final-stats",
"name": "Estat\u00edsticas Finais",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
4050,
200
]
}
],
"connections": {
"Schedule Trigger - 6h": {
"main": [
[
{
"node": "Buscar Fontes RSS Ativas",
"type": "main",
"index": 0
}
]
]
},
"Buscar Fontes RSS Ativas": {
"main": [
[
{
"node": "Loop Over RSS Sources",
"type": "main",
"index": 0
}
]
]
},
"Loop Over RSS Sources": {
"main": [
null,
[
{
"node": "Ler Feed RSS",
"type": "main",
"index": 0
}
]
]
},
"Ler Feed RSS": {
"main": [
[
{
"node": "Extrair URLs dos Itens",
"type": "main",
"index": 0
}
]
]
},
"Extrair URLs dos Itens": {
"main": [
[
{
"node": "Loop Over Feed Items",
"type": "main",
"index": 0
}
]
]
},
"Loop Over Feed Items": {
"main": [
null,
[
{
"node": "Preparar Dados para Verifica\u00e7\u00e3o",
"type": "main",
"index": 0
}
]
]
},
"Preparar Dados para Verifica\u00e7\u00e3o": {
"main": [
[
{
"node": "Verificar Duplicatas",
"type": "main",
"index": 0
}
]
]
},
"Verificar Duplicatas": {
"main": [
[
{
"node": "IF: URL n\u00e3o existe?",
"type": "main",
"index": 0
}
]
]
},
"IF: URL n\u00e3o existe?": {
"main": [
[
{
"node": "Scraping do Conte\u00fado",
"type": "main",
"index": 0
}
],
[
{
"node": "Loop Over Feed Items",
"type": "main",
"index": 0
}
]
]
},
"Scraping do Conte\u00fado": {
"main": [
[
{
"node": "Preparar Seletores CSS",
"type": "main",
"index": 0
}
]
]
},
"Preparar Seletores CSS": {
"main": [
[
{
"node": "Extrair com Seletores",
"type": "main",
"index": 0
}
]
]
},
"Extrair com Seletores": {
"main": [
[
{
"node": "Limpar HTML",
"type": "main",
"index": 0
}
]
]
},
"Limpar HTML": {
"main": [
[
{
"node": "IA: Avaliar Relev\u00e2ncia",
"type": "main",
"index": 0
}
]
]
},
"IA: Avaliar Relev\u00e2ncia": {
"main": [
[
{
"node": "Parsear Resposta IA",
"type": "main",
"index": 0
}
]
]
},
"Google Gemini Chat Model": {
"ai_languageModel": [
[
{
"node": "IA: Avaliar Relev\u00e2ncia",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Parsear Resposta IA": {
"main": [
[
{
"node": "IF: Conte\u00fado Relevante?",
"type": "main",
"index": 0
}
]
]
},
"IF: Conte\u00fado Relevante?": {
"main": [
[
{
"node": "Salvar Mat\u00e9ria no Banco",
"type": "main",
"index": 0
}
],
[
{
"node": "Log Irrelevante",
"type": "main",
"index": 0
}
]
]
},
"Salvar Mat\u00e9ria no Banco": {
"main": [
[
{
"node": "Disparar Gera\u00e7\u00e3o de Conte\u00fado",
"type": "main",
"index": 0
}
]
]
},
"Disparar Gera\u00e7\u00e3o de Conte\u00fado": {
"main": [
[
{
"node": "Log de Sucesso",
"type": "main",
"index": 0
}
]
]
},
"Log de Sucesso": {
"main": [
[
{
"node": "Estat\u00edsticas Finais",
"type": "main",
"index": 0
}
]
]
},
"Log Irrelevante": {
"main": [
[]
]
}
},
"settings": {
"executionOrder": "v1",
"saveManualExecutions": true,
"callerPolicy": "workflowsFromSameOwner",
"errorWorkflow": "error-handler"
},
"staticData": null,
"tags": [
{
"name": "automation",
"id": "1"
},
{
"name": "rss",
"id": "2"
},
{
"name": "content",
"id": "3"
}
],
"triggerCount": 1,
"updatedAt": "2025-01-15T10:00:00.000Z",
"versionId": "1"
}
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.
googlePalmApisupabaseApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
RSS Collector - Scraping and Validation. Uses supabase, rssFeedRead, httpRequest, agent. Scheduled trigger; 22 nodes.
Source: https://github.com/artubss/contentflow-automation/blob/92598bf6726e2866bef62d4ded75da913fb23b57/n8n-workflow-rss-collector.json — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
LinkedIn_Job_Hunt_and_Cover_Letter. Uses outputParserStructured, outputParserAutofixing, googleDrive, agent. Scheduled trigger; 85 nodes.
Automatically scan major financial newswires for biotech catalyst events, score them with AI sentiment analysis, and surface ranked trade candidates — all without manual monitoring.
Fully automated blog creation system using n8n + AI Agents + Image Generation
This project is an automated news publisher for LinkedIn. It uses RSS feeds to fetch news, processes the content with the Gemini API to generate precise summaries, and automatically publishes to Linke
kisisel asistan. Uses toolWorkflow, toolHttpRequest, toolCalculator, toolThink. Scheduled trigger; 43 nodes.