Este flujo automatiza la recopilación, análisis y envío por mail de las 10 noticias más importantes de SEO de la semana anterior.

  • Busca en 7 fuentes confiables (Google Search Central, Moz, Ahrefs, etc.)  
  • Usa GPT-4o para resumir y rankear las notas  
  • Filtra por relevancia, impacto y temática  
  • Envía un resumen por email todos los lunes al mediodía  

Solo necesitás:

  • Cuenta de N8N
  • API key de OpenAI
  • Gmail conectado

Cómo descargar el código del newsletter

Acá podés descargar el JSON completo en este link, o copiando el archivo el siguiente código 👇

{
  "name": "Eleven bot - Semanal",
  "nodes": [
    {
      "parameters": {
        "mode": "raw",
        "jsonOutput": "{\n  \"rss_feeds\": [\n    {\n      \"name\": \"Google Search Central (histórico, vía FeedBurner)\",\n      \"url\": \"https://feeds.feedburner.com/blogspot/amDG\"\n    },\n    {\n      \"name\": \"Moz Blog\",\n      \"url\": \"https://moz.com/posts/rss/blog\"\n    },\n    {\n      \"name\": \"Search Engine Roundtable\",\n      \"url\": \"https://www.seroundtable.com/index.xml\"\n    },\n    {\n      \"name\": \"Search Engine Journal\",\n      \"url\": \"https://www.searchenginejournal.com/feed/\"\n    },\n    {\n      \"name\": \"Search Engine Land\",\n      \"url\": \"https://searchengineland.com/feed\"\n    },\n    {\n      \"name\": \"SEMrush Blog\",\n      \"url\": \"https://www.semrush.com/blog/feed/\"\n    },\n    {\n      \"name\": \"Ahrefs Blog\",\n      \"url\": \"https://ahrefs.com/blog/feed/\"\n    }\n  ]\n}",
        "options": {}
      },
      "id": "08f327ac-791a-4b64-b77d-cde9d8d450b5",
      "name": "Set Tech News RSS Feeds",
      "type": "n8n-nodes-base.set",
      "position": [
        3220,
        400
      ],
      "typeVersion": 3.4,
      "credentials": {}
    },
    {
      "parameters": {
        "url": "={{ $json.url }}",
        "options": {
          "ignoreSSL": false
        }
      },
      "id": "3b4e9bd9-c669-4cee-a8a1-31539b0045d5",
      "name": "Read RSS News Feeds",
      "type": "n8n-nodes-base.rssFeedRead",
      "position": [
        3640,
        400
      ],
      "typeVersion": 1.1,
      "credentials": {}
    },
    {
      "parameters": {
        "fieldToSplitOut": "=rss_feeds",
        "options": {}
      },
      "type": "n8n-nodes-base.splitOut",
      "typeVersion": 1,
      "position": [
        3400,
        400
      ],
      "id": "c037fafa-96a0-4a43-84c4-231b468ef417",
      "name": "Split Out",
      "credentials": {}
    },
    {
      "parameters": {
        "jsCode": "/**\n * Filtra los artículos cuya isoDate sea\n * de los 7 días corridos anteriores a “ahora”\n * en la zona America/Argentina/Buenos_Aires.\n */\n\nconst TZ = 'America/Argentina/Buenos_Aires';\n\n// --- fecha/hora local “ahora” ---\nconst nowLocal = new Date(\n  new Date().toLocaleString('en-US', { timeZone: TZ })\n);\n\n// pivot: final del día de ayer 23:59:59\nconst end = new Date(nowLocal);\nend.setDate(end.getDate() - 1);\nend.setHours(23, 59, 59, 999);\n\n// inicio: 7 días antes, 00:00:00\nconst start = new Date(end);\nstart.setDate(start.getDate() - 6);   // 7 días en total\nstart.setHours(0, 0, 0, 0);\n\n// --- filtrar ---\nconst output = [];\n\nfor (const itm of $input.all()) {\n  const iso = itm.json.isoDate;\n  if (!iso) continue;\n\n  const pub = new Date(iso);\n  if (pub >= start && pub <= end) {\n    output.push(itm);\n  }\n}\n\nreturn output;"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        3880,
        400
      ],
      "id": "0af5f555-ff31-4fc8-89b4-84709df885d6",
      "name": "Code1",
      "credentials": {}
    },
    {
      "parameters": {
        "url": "={{'https://r.jina.ai/http://' + $json[\"link\"].replace(/^https?:\\/\\//, '')}}",
        "options": {
          "batching": {
            "batch": {
              "batchSize": 3,
              "batchInterval": 2000
            }
          },
          "response": {
            "response": {
              "responseFormat": "text",
              "outputPropertyName": "article"
            }
          },
          "timeout": 60000
        }
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        4120,
        400
      ],
      "id": "9c2444e2-c550-416e-aeef-59c220457d57",
      "name": "Fetch Full Article",
      "retryOnFail": true,
      "alwaysOutputData": false,
      "executeOnce": false,
      "notesInFlow": false,
      "waitBetweenTries": 3000,
      "onError": "continueErrorOutput",
      "credentials": {}
    },
    {
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "/**\n * Recorta cada artículo a máx. 8 000 caracteres\n * y quita espacios en blanco al inicio/final.\n */\nconst MAX = 8000;\n\nlet text = item.json.article || '';\nitem.json.article = text.trim().slice(0, MAX);\n\nreturn item;\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        4720,
        400
      ],
      "id": "f0f8566e-8bb5-43f5-8359-9bc0d07827e0",
      "name": "Clean & Trim",
      "credentials": {}
    },
    {
      "parameters": {
        "aggregate": "aggregateAllItemData",
        "destinationFieldName": "articles",
        "options": {}
      },
      "type": "n8n-nodes-base.aggregate",
      "typeVersion": 1,
      "position": [
        5580,
        380
      ],
      "id": "5f3f305c-14cb-480e-9f2a-d344aa10b2f3",
      "name": "Aggregate",
      "credentials": {}
    },
    {
      "parameters": {
        "modelId": {
          "__rl": true,
          "value": "gpt-4o",
          "mode": "list",
          "cachedResultName": "GPT-4O"
        },
        "messages": {
          "values": [
            {
              "content": "Eres editor senior de noticias sobre SEO y búsqueda orgánica.\n\nDevuelve SIEMPRE un JSON con:\n\n  title       – título en español neutro, ≤12 palabras\n  source      – dominio\n  link        – URL\n  summary     – 1 oración en español (≤25 palabras)\n  topic       – UNA de las etiquetas:\n                search_central, ai_overview, geo, aeo, sxo,\n                search_update, seo_generic, other, ads, corporate\n  raw_impact  – entero 1-10 ponderado:\n                • Relevancia SEO          40 %\n                • Alcance global          25 %\n                • Novedad                 20 %\n                • Autoridad de la fuente  10 %\n                • Potencial de acción      5 %\n  rationale   – 1 frase (≤15 palabras) que justifique raw_impact\n\nCriterio de topic:\n  • search_central  → source contiene developers.google.com/search\n  • ai_overview     → texto contiene “AI Overview” o “AI Mode”\n  • geo/aeo/sxo     → aparece la sigla o frase completa\n  • search_update   → core update, ranking update, volatility…\n  • ads             → Merchant Center, Google Ads, Paid\n  • corporate       → despidos, finanzas, adquisiciones\n  • seo_generic     → guías, estudios, herramientas SEO\n  • other           → no encaja en los anteriores\n\nNo añadas texto fuera del JSON.",
              "role": "system"
            },
            {
              "content": "=TITLE: {{$json.title}}\nLINK:  {{$json.link}}\nTEXT:\n{{$json.article}}"
            }
          ]
        },
        "jsonOutput": true,
        "options": {
          "temperature": 0.3,
          "topP": 1
        }
      },
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "typeVersion": 1.8,
      "position": [
        5200,
        400
      ],
      "id": "862d0d4e-8200-477e-843a-57b9dfdc7735",
      "name": "Summarize",
      "retryOnFail": true,
      "waitBetweenTries": 5000,
      "credentials": {},
      "onError": "continueErrorOutput"
    },
    {
      "parameters": {
        "modelId": {
          "__rl": true,
          "value": "gpt-4o",
          "mode": "list",
          "cachedResultName": "GPT-4O"
        },
        "messages": {
          "values": [
            {
              "content": "Eres editor jefe de SEO/búsqueda.\n\nRecibes un ARRAY \"articles\" con:\n  title, link, source, summary, topic, raw_impact, rationale.\n\nReglas para calcular final_impact (0-10, 1 decimal):\n  • Empieza en raw_impact.\n  • +2    si topic = search_central\n  • +1.5  si topic = ai_overview\n  • +1    si topic ∈ {geo, aeo, sxo, search_update}\n  • +0.5  si summary contiene “ranking”, “visibilidad” o “tráfico orgánico”\n  • −2    si topic ∈ {ads, corporate}\n       ↳ EXCEPCIÓN: si summary menciona “resultados de búsqueda”\n         o “CTR orgánico”, NO restes.\n  • Si dos notas quedan a <0.2 de diferencia, prefiere distinta source.\n  • No repitas exactamente el mismo final_impact dentro del mismo source.\n\nTareas:\n1. Calcula final_impact aplicando las reglas.\n2. Elige las 10 notas con mayor final_impact.\n3. Ordénalas de mayor a menor final_impact.\n4. Devuelve sólo:\n\n{\n  \"chosen\":[\n    {title, link, source, summary, final_impact, rationale},\n    …\n  ]\n}\n\nNo añadas texto fuera del JSON.",
              "role": "system"
            },
            {
              "content": "=ARTICLES:\n{{ JSON.stringify($json.articles) }}\n"
            }
          ]
        },
        "jsonOutput": true,
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "typeVersion": 1.8,
      "position": [
        5980,
        380
      ],
      "id": "8ac890a8-ecca-4412-91ba-8fcef6cbbef6",
      "name": "Rank & Pick",
      "retryOnFail": true,
      "waitBetweenTries": 5000,
      "maxTries": 3,
      "credentials": {},
      "onError": "continueErrorOutput"
    },
    {
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "/**\n * Añade al ítem:\n *   • chosen : array con las 10 noticias\n *   • rango  : \"del DD/MM al DD/MM\" de la semana pasada\n */\n\nconst TZ = 'America/Argentina/Buenos_Aires';\n\n// ------------ 1) Fecha local “ahora” ------------\nconst nowLocal = new Date(\n  new Date().toLocaleString('en-US', { timeZone: TZ })\n);\n\n// ------------ 2) Domingo recién terminado ------------\nconst end = new Date(nowLocal);\nend.setDate(end.getDate() - 1);      // ayer (domingo si hoy es lunes)\nend.setHours(23,59,59,999);\n\n// ------------ 3) Lunes de esa misma semana ------------\nconst start = new Date(end);\nstart.setDate(end.getDate() - 6);    // seis días antes, 00:00\nstart.setHours(0,0,0,0);\n\n// ------------ 4) Formatear DD/MM ------------\nconst fmt = d => d.toLocaleDateString('es-AR', {\n  day: '2-digit', month: '2-digit', timeZone: TZ\n});\n\n// ------------ 5) Guardar en el ítem ------------\nitem.json.rango  = `del ${fmt(start)} al ${fmt(end)}`;\n\n// Si aún no simplificaste output:\nitem.json.chosen = item.json.message?.content?.chosen ?? item.json.chosen;\n\nreturn item;\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        6400,
        360
      ],
      "id": "48613151-a0fc-4091-87a8-484dd310c11b",
      "name": "Code",
      "credentials": {}
    },
    {
      "parameters": {
        "url": "={{'https://r.jina.ai/http://' + $json[\"link\"].replace(/^https?:\\/\\//, '')}}",
        "options": {
          "batching": {
            "batch": {
              "batchSize": 1,
              "batchInterval": 4000
            }
          },
          "response": {
            "response": {
              "responseFormat": "text",
              "outputPropertyName": "article"
            }
          },
          "timeout": 90000
        }
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        4300,
        620
      ],
      "id": "eeb43570-d9eb-4494-bc67-c102c4e0a44c",
      "name": "Fetch Alt Parser",
      "retryOnFail": true,
      "alwaysOutputData": false,
      "executeOnce": false,
      "notesInFlow": false,
      "waitBetweenTries": 5000,
      "maxTries": 2,
      "onError": "continueErrorOutput",
      "credentials": {}
    },
    {
      "parameters": {
        "sendTo": "<REDACTED_EMAIL>",
        "subject": "=Resumen SEOmanal {{ $json.rango }}",
        "emailType": "text",
        "message": "=Estas son la 10 noticias más importantes {{ $json.rango }}:  \n\n1) {{ $json.message.content.chosen[0].summary }} \n{{ $json.message.content.chosen[0].link }}  \n\n2) {{ $json.message.content.chosen[1].summary }} \n{{ $json.message.content.chosen[1].link }}  \n\n3) {{ $json.message.content.chosen[2].summary }} \n{{ $json.message.content.chosen[2].link }}  \n\n4) {{ $json.message.content.chosen[3].summary }} \n{{ $json.message.content.chosen[3].link }}  \n\n5) {{ $json.message.content.chosen[4].summary }} \n{{ $json.message.content.chosen[4].link }}  \n\n6) {{ $json.message.content.chosen[5].summary }} \n{{ $json.message.content.chosen[5].link }}  \n\n7) {{ $json.message.content.chosen[6].summary }} \n{{ $json.message.content.chosen[6].link }}  \n\n8) {{ $json.message.content.chosen[7].summary }} \n{{ $json.message.content.chosen[7].link }}  \n\n9) {{ $json.message.content.chosen[8].summary }} \n{{ $json.message.content.chosen[8].link }}  \n\n10) {{ $json.message.content.chosen[9].summary }} \n{{ $json.message.content.chosen[9].link }}",
        "options": {}
      },
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.1,
      "position": [
        6580,
        380
      ],
      "id": "f1ac8405-c6c0-4569-bdd2-ac7a03b4f348",
      "name": "Gmail",
      "credentials": {}
    },
    {
      "parameters": {
        "mode": "combine",
        "combineBy": "combineByPosition",
        "options": {
          "includeUnpaired": true
        }
      },
      "type": "n8n-nodes-base.merge",
      "typeVersion": 3.2,
      "position": [
        4500,
        400
      ],
      "id": "c453e978-b187-4937-8508-0db5e0a4a0fd",
      "name": "Merge",
      "credentials": {}
    },
    {
      "parameters": {
        "jsCode": "/**\n * Deja los campos necesarios para el ranking\n * y reduce tokens a la mitad.\n */\nreturn $input.all().map(item => {\n  item.json.articles_compact = (item.json.articles || []).map(a => ({\n    title:      a.title,\n    source:     a.source,\n    link:       a.link,\n    summary:    a.summary,   // lo necesitamos para el Slack final\n    topic:      a.topic,\n    raw_impact: a.raw_impact\n  }));\n  return item;\n});"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        5760,
        380
      ],
      "id": "dbcb566d-18c1-48af-ac90-eb96768e288b",
      "name": "Code2",
      "credentials": {}
    },
    {
      "parameters": {
        "amount": 1
      },
      "type": "n8n-nodes-base.wait",
      "typeVersion": 1.1,
      "position": [
        4960,
        400
      ],
      "id": "ac7702d2-1482-4f83-a6a2-e89464b3b8d2",
      "name": "Wait",
      "credentials": {}
    },
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "weeks",
              "triggerAtDay": [
                1
              ],
              "triggerAtHour": 12
            }
          ]
        }
      },
      "id": "878626e6-d99d-4f8b-9868-799e0e49cbaa",
      "name": "Get Articles",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        3020,
        400
      ],
      "typeVersion": 1.2,
      "credentials": {}
    }
  ],
  "pinData": {},
  "connections": {
    "Read RSS News Feeds": {
      "main": [
        [
          {
            "node": "Code1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Tech News RSS Feeds": {
      "main": [
        [
          {
            "node": "Split Out",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Out": {
      "main": [
        [
          {
            "node": "Read RSS News Feeds",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code1": {
      "main": [
        [
          {
            "node": "Fetch Full Article",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Full Article": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Fetch Alt Parser",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Clean & Trim": {
      "main": [
        [
          {
            "node": "Wait",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Aggregate": {
      "main": [
        [
          {
            "node": "Code2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Summarize": {
      "main": [
        [
          {
            "node": "Aggregate",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Rank & Pick": {
      "main": [
        [
          {
            "node": "Code",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code": {
      "main": [
        [
          {
            "node": "Gmail",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Alt Parser": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Gmail": {
      "main": [
        []
      ]
    },
    "Merge": {
      "main": [
        [
          {
            "node": "Clean & Trim",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code2": {
      "main": [
        [
          {
            "node": "Rank & Pick",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait": {
      "main": [
        [
          {
            "node": "Summarize",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Articles": {
      "main": [
        [
          {
            "node": "Set Tech News RSS Feeds",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": true,
  "settings": {
    "executionOrder": "v1",
    "callerPolicy": "workflowsFromSameOwner"
  },
  "meta": {
    "templateId": "3986",
    "templateCredsSetupCompleted": true
  },
  "tags": []
}

Cómo podemos ayudar Emoji

Consultoría SEO

Aumenta tu visibilidad orgánica con nuestra asesoría personalizada, estratégica e integral.

Cómo podemos
ayudar Emoji

Consultoría SEO

Aumenta tu visibilidad orgánica con nuestra asesoría personalizada, estratégica e integral.

¡Comparte esta info! 🤩

Artículos relacionados