{
  "name": "AI News Digest (RSS → ranked summary → Email/Telegram)",
  "nodes": [
    {
      "id": "77da8258-d6d2-54dd-8da8-e4c9ffdc3f84",
      "name": "Every morning 7:00",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        0,
        0
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "days",
              "triggerAtHour": 7
            }
          ]
        }
      }
    },
    {
      "id": "2804781c-cba0-5ca3-a1e2-51ca097e1dc0",
      "name": "Run now (test)",
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [
        0,
        200
      ],
      "parameters": {}
    },
    {
      "id": "ead65636-1fdc-51d3-bb24-daab15923cbd",
      "name": "Settings",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        220,
        100
      ],
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "a1",
              "name": "maxStories",
              "value": 8,
              "type": "number"
            },
            {
              "id": "a2",
              "name": "emailTo",
              "value": "you@example.com",
              "type": "string"
            }
          ]
        },
        "options": {}
      }
    },
    {
      "id": "9ffa89ba-9256-56e0-865b-273b31aa935c",
      "name": "TechCrunch AI",
      "type": "n8n-nodes-base.rssFeedRead",
      "typeVersion": 1.1,
      "position": [
        460,
        -100
      ],
      "parameters": {
        "url": "https://techcrunch.com/category/artificial-intelligence/feed/",
        "options": {}
      },
      "executeOnce": true,
      "onError": "continueRegularOutput"
    },
    {
      "id": "b8c43f4c-f166-52d1-be66-44ae476000df",
      "name": "The Verge AI",
      "type": "n8n-nodes-base.rssFeedRead",
      "typeVersion": 1.1,
      "position": [
        460,
        100
      ],
      "parameters": {
        "url": "https://www.theverge.com/rss/ai-artificial-intelligence/index.xml",
        "options": {}
      },
      "executeOnce": true,
      "onError": "continueRegularOutput"
    },
    {
      "id": "3b7973b7-5b41-5864-86a1-980bbbaf45a3",
      "name": "Hacker News (AI, 50+ pts)",
      "type": "n8n-nodes-base.rssFeedRead",
      "typeVersion": 1.1,
      "position": [
        460,
        300
      ],
      "parameters": {
        "url": "https://hnrss.org/newest?q=AI+OR+LLM+OR+agent&points=50",
        "options": {}
      },
      "executeOnce": true,
      "onError": "continueRegularOutput"
    },
    {
      "id": "c1dbb1f4-311f-5e53-a3b2-9466d6bee2a4",
      "name": "Combine feeds",
      "type": "n8n-nodes-base.merge",
      "typeVersion": 3,
      "position": [
        700,
        100
      ],
      "parameters": {
        "numberInputs": 3
      }
    },
    {
      "id": "9c8b52a1-9f75-5d3e-aaf9-376434ed2ab3",
      "name": "Rank & summarize",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        920,
        100
      ],
      "parameters": {
        "jsCode": "// Dedupe, keep last 36h, score by keywords, make a 1-2 sentence summary. No API key needed.\nconst KEYWORDS = ['agent','automation','openai','anthropic','gemini','llm','model','open-source','workflow','n8n','api','launch','release'];\nconst HOURS = 36;\nconst cutoff = Date.now() - HOURS * 3600 * 1000;\nconst seen = new Set();\nconst out = [];\nfor (const item of $input.all()) {\n  const j = item.json;\n  const title = (j.title || '').trim();\n  const link = j.link || j.guid || '';\n  const key = title.toLowerCase().replace(/[^a-z0-9]+/g, ' ').slice(0, 80);\n  if (!title || seen.has(key)) continue;\n  seen.add(key);\n  const date = new Date(j.isoDate || j.pubDate || Date.now());\n  if (date.getTime() < cutoff) continue;\n  const text = (j.contentSnippet || j.content || '').replace(/<[^>]+>/g, ' ').replace(/(Article URL|Comments URL|Points|# Comments):\\s*\\S+/g, ' ').replace(/\\s+/g, ' ').trim();\n  const sentences = text.match(/[^.!?]+[.!?]+/g) || [text];\n  let summary = sentences.slice(0, 2).join(' ').trim();\n  if (summary.length > 240) summary = summary.slice(0, 237).replace(/\\s+\\S*$/, '') + '...';\n  const hay = (title + ' ' + text).toLowerCase();\n  const score = KEYWORDS.reduce((s, k) => s + (hay.includes(k) ? 1 : 0), 0) + (String(j.comments || j.guid || '').includes('news.ycombinator.com') ? 1 : 0);\n  let source = 'News';\n  const hm = String(link).match(/^https?:\\/\\/([^\\/?#]+)/i);\n  if (hm) source = hm[1].replace(/^www\\./, '');\n  out.push({ json: { title, link, summary: summary || '(no summary in feed)', source, published: date.toISOString(), score } });\n}\nout.sort((a, b) => b.json.score - a.json.score || b.json.published.localeCompare(a.json.published));\nreturn out.slice(0, $('Settings').first().json.maxStories);"
      }
    },
    {
      "id": "9b43cfd8-08ba-558c-9abb-2afef50ca5a4",
      "name": "Build digest",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1140,
        100
      ],
      "parameters": {
        "jsCode": "// Turn the top stories into one HTML email + a plain-text/Telegram version.\nconst items = $input.all().map(i => i.json);\nconst today = new Date().toLocaleDateString('en-US', { weekday: 'long', month: 'short', day: 'numeric' });\nconst html = `<div style=\"font-family:Arial,sans-serif;max-width:620px\">\n<h2 style=\"color:#2563eb\">AI Daily Digest – ${today}</h2>\n<p style=\"color:#555\">${items.length} stories worth your time, ranked by relevance.</p>\n${items.map((s, i) => `<div style=\"margin:14px 0;padding:12px;border-left:4px solid #ffd60a;background:#f7f8fb\">\n<b>${i + 1}. <a href=\"${s.link}\">${s.title}</a></b><br><span style=\"color:#888;font-size:12px\">${s.source}</span>\n<p style=\"margin:6px 0 0\">${s.summary}</p></div>`).join('')}\n<p style=\"color:#999;font-size:12px\">Built with n8n.</p></div>`;\nconst text = `AI Daily Digest – ${today}\\n\\n` + items.map((s, i) => `${i + 1}. ${s.title}\\n${s.summary}\\n${s.link}`).join('\\n\\n');\nreturn [{ json: { subject: `AI Daily Digest – ${today} (${items.length} stories)`, html, text: text.slice(0, 4000), count: items.length } }];"
      }
    },
    {
      "id": "43693405-76c8-58a4-8773-fdb01dcced19",
      "name": "Send email",
      "type": "n8n-nodes-base.emailSend",
      "typeVersion": 2.1,
      "position": [
        1380,
        0
      ],
      "parameters": {
        "fromEmail": "digest@example.com",
        "toEmail": "={{ $('Settings').first().json.emailTo }}",
        "subject": "={{ $json.subject }}",
        "html": "={{ $json.html }}",
        "options": {}
      },
      "credentials": {
        "smtp": {
          "id": "REPLACE_ME",
          "name": "SMTP – REPLACE_ME (Gmail app password, Brevo free SMTP, etc.)"
        }
      },
      "disabled": true
    },
    {
      "id": "ce05a6e4-6efe-5e4b-a9b8-ea673e51e394",
      "name": "Send to Telegram",
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        1380,
        200
      ],
      "parameters": {
        "chatId": "REPLACE_WITH_YOUR_CHAT_ID",
        "text": "={{ $json.text }}",
        "additionalFields": {
          "disable_web_page_preview": true
        }
      },
      "credentials": {
        "telegramApi": {
          "id": "REPLACE_ME",
          "name": "Telegram bot – REPLACE_ME (free from @BotFather)"
        }
      },
      "disabled": true
    },
    {
      "id": "a2bf1859-0015-5670-90c1-5a031b9218dc",
      "name": "How it works",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -40,
        -330
      ],
      "parameters": {
        "content": "## AI News Digest\n1. Pulls 3 free RSS feeds (no API keys)\n2. Dedupes, keeps the last 36h, ranks by your keywords\n3. Writes a short summary per story\n4. Sends one email and/or Telegram message\n\n**Setup:** add an SMTP or Telegram credential, enable that node, set your email in *Settings*.\n\nOptional: swap *Rank & summarize* for a local Ollama call (see README).",
        "width": 700,
        "height": 250,
        "color": 5
      }
    }
  ],
  "connections": {
    "Every morning 7:00": {
      "main": [
        [
          {
            "node": "Settings",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Run now (test)": {
      "main": [
        [
          {
            "node": "Settings",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Settings": {
      "main": [
        [
          {
            "node": "TechCrunch AI",
            "type": "main",
            "index": 0
          },
          {
            "node": "The Verge AI",
            "type": "main",
            "index": 0
          },
          {
            "node": "Hacker News (AI, 50+ pts)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "TechCrunch AI": {
      "main": [
        [
          {
            "node": "Combine feeds",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "The Verge AI": {
      "main": [
        [
          {
            "node": "Combine feeds",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Hacker News (AI, 50+ pts)": {
      "main": [
        [
          {
            "node": "Combine feeds",
            "type": "main",
            "index": 2
          }
        ]
      ]
    },
    "Combine feeds": {
      "main": [
        [
          {
            "node": "Rank & summarize",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Rank & summarize": {
      "main": [
        [
          {
            "node": "Build digest",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build digest": {
      "main": [
        [
          {
            "node": "Send email",
            "type": "main",
            "index": 0
          },
          {
            "node": "Send to Telegram",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  },
  "pinData": {},
  "active": false
}