{
  "meta": {
    "aiBuilderAssisted": true,
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "7987c840-16b8-4e66-9422-7101cee44c29",
      "name": "Daily Morning Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        240,
        400
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "triggerAtHour": 8
            }
          ]
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "f2aeacc4-41ea-4af6-ab8d-68d833c7cac2",
      "name": "Define RSS Sources",
      "type": "n8n-nodes-base.code",
      "position": [
        528,
        400
      ],
      "parameters": {
        "jsCode": "var feeds = [\n  { url: \"http://news.ycombinator.com/rss\", source: \"Hacker News\" },\n  { url: \"https://techcrunch.com/feed/\", source: \"TechCrunch\" },\n  { url: \"http://www.theverge.com/rss/full.xml\", source: \"The Verge\" },\n  { url: \"http://venturebeat.com/feed/\", source: \"VentureBeat\" },\n  { url: \"https://blog.pragmaticengineer.com/rss/\", source: \"The Pragmatic Engineer\" },\n  { url: \"https://engineering.fb.com/feed/\", source: \"Engineering at Meta\" },\n  { url: \"https://engineering.atspotify.com/feed/\", source: \"Spotify Engineering\" },\n  { url: \"https://stripe.com/blog/feed.rss\", source: \"Stripe Blog\" },\n  { url: \"https://slack.engineering/feed\", source: \"Slack Engineering\" },\n  { url: \"https://blog.cloudflare.com/rss/\", source: \"Cloudflare Blog\" },\n  { url: \"https://shopifyengineering.myshopify.com/blogs/engineering.atom\", source: \"Shopify Engineering\" },\n  { url: \"https://openai.com/news/engineering/rss.xml\", source: \"OpenAI\" },\n  { url: \"http://googleresearch.blogspot.com/atom.xml\", source: \"Google AI Blog\" },\n  { url: \"https://deepmind.com/blog/feed/basic/\", source: \"DeepMind\" },\n  { url: \"http://news.mit.edu/rss/topic/artificial-intelligence2\", source: \"MIT News AI\" },\n  { url: \"https://www.amazon.science/index.rss\", source: \"Amazon Science\" },\n  { url: \"https://developer.nvidia.com/blog/feed\", source: \"NVIDIA Developer\" },\n  { url: \"http://firstround.com/review/feed.xml\", source: \"First Round Review\" },\n  { url: \"https://lethain.com/feeds/\", source: \"Irrational Exuberance\" },\n  { url: \"http://www.producthunt.com/feed\", source: \"Product Hunt\" },\n  { url: \"http://www.quantamagazine.org/feed/\", source: \"Quanta Magazine\" },\n  { url: \"https://www.sciencealert.com/rss\", source: \"ScienceAlert\" },\n  { url: \"https://singularityhub.com/feed/\", source: \"Singularity Hub\" },\n  { url: \"https://jvns.ca/atom.xml\", source: \"Julia Evans\" },\n  { url: \"https://danluu.com/atom.xml\", source: \"Dan Luu\" },\n  { url: \"https://overreacted.io/rss.xml\", source: \"Dan Abramov\" },\n  { url: \"https://www.joelonsoftware.com/feed/\", source: \"Joel on Software\" }\n];\nreturn feeds.map(function(f) { return { json: f }; });"
      },
      "typeVersion": 2
    },
    {
      "id": "8246b94e-9e1f-49bc-92b5-7626395b50b6",
      "name": "Fetch RSS Feeds",
      "type": "n8n-nodes-base.rssFeedRead",
      "onError": "continueRegularOutput",
      "position": [
        800,
        400
      ],
      "parameters": {
        "url": "={{ $json.url }}",
        "options": {
          "ignoreSSL": true
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "cdf20fa3-1c33-436b-8226-ebd73eae93b0",
      "name": "Clean and Prepare for AI",
      "type": "n8n-nodes-base.code",
      "position": [
        1088,
        400
      ],
      "parameters": {
        "jsCode": "var items = $input.all();\nvar seen = new Set();\nvar cleaned = [];\nfor (var i = 0; i < items.length; i++) {\n  var d = items[i].json;\n  var title = (d.title || \"\").trim();\n  var link = (d.link || \"\").trim();\n  if (!title || !link || seen.has(link)) continue;\n  seen.add(link);\n  var desc = (d.contentSnippet || d.content || d.description || \"\").replace(/<[^>]*>/g, \"\").trim();\n  if (desc.length > 250) desc = desc.substring(0, 250) + \"...\";\n  var pubDate = d.isoDate || d.pubDate || \"\";\n  var source = d.creator || \"\";\n  if (!source) { try { source = new URL(link).hostname.replace(\"www.\", \"\"); } catch(e) {} }\n  cleaned.push({ title: title, link: link, description: desc, pubDate: pubDate, source: source });\n}\ncleaned.sort(function(a, b) { return new Date(b.pubDate || 0) - new Date(a.pubDate || 0); });\ncleaned = cleaned.slice(0, 150);\nvar articleList = cleaned.map(function(a, idx) {\n  return \"[\" + idx + \"] \" + JSON.stringify(a.title) + \" (\" + (a.source || \"Unknown\") + \", \" + (a.pubDate ? a.pubDate.substring(0, 10) : \"No date\") + \")\\n   \" + (a.description || \"No description\");\n}).join(\"\\n\\n\");\nreturn [{ json: { articleCount: cleaned.length, articleList: articleList, articlesJson: JSON.stringify(cleaned) } }];"
      },
      "typeVersion": 2
    },
    {
      "id": "a5169a62-6a6b-478b-b93e-e97d65da1e26",
      "name": "AI Article Curator",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        1360,
        400
      ],
      "parameters": {
        "text": "=I have {{ $json.articleCount }} articles from various tech RSS feeds today. Please select the 30 most interesting, impactful, and diverse articles.\n\nHere are all the articles:\n\n{{ $json.articleList }}\n\nReturn ONLY a valid JSON object with this exact structure: {\"selected\": [0, 5, 12, ...]} where the numbers are the article indices from the list above.\n\nSelection criteria:\n1. Timely and newsworthy\n2. Diverse topics (AI, engineering, startups, science, design)\n3. Genuinely interesting to a tech professional\n4. Avoid duplicates or very similar stories\n5. Prioritize original insights over press releases",
        "options": {
          "systemMessage": "You are an expert tech news curator. Your job is to review a list of articles from various RSS feeds and select exactly 30 of the most interesting and diverse ones for a daily digest email. You must return ONLY valid JSON with the selected article indices in this format: {\"selected\": [index1, index2, ...]}. Do not include any other text, explanation, or formatting."
        },
        "promptType": "define"
      },
      "typeVersion": 3.1
    },
    {
      "id": "9dd360be-7c8c-41a6-a612-db060ee58943",
      "name": "OpenAI GPT-5 Mini",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        1360,
        624
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-5-mini"
        },
        "options": {},
        "builtInTools": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "5eb8206e-3128-4eba-9a06-53c080795a68",
      "name": "Build Digest Email",
      "type": "n8n-nodes-base.code",
      "position": [
        1648,
        400
      ],
      "parameters": {
        "jsCode": "var aiOutput = $input.first().json.output;\nvar allArticles = JSON.parse($(\"Clean and Prepare for AI\").first().json.articlesJson);\nvar selected;\ntry {\n  var jsonMatch = aiOutput.match(/\\{[\\s\\S]*\\}/);\n  var parsed = JSON.parse(jsonMatch ? jsonMatch[0] : aiOutput);\n  selected = parsed.selected || parsed.indices || [];\n} catch (e) {\n  var nums = aiOutput.match(/\\d+/g);\n  selected = nums ? nums.map(Number) : [];\n}\nvar articles = selected.filter(function(i) { return i >= 0 && i < allArticles.length; }).slice(0, 30).map(function(i) { return allArticles[i]; });\nvar today = new Date().toLocaleDateString(\"en-US\", { weekday: \"long\", year: \"numeric\", month: \"long\", day: \"numeric\" });\nvar h = \"<!DOCTYPE html><html><head><meta charset=\\\"utf-8\\\"><meta name=\\\"viewport\\\" content=\\\"width=device-width, initial-scale=1.0\\\"></head>\";\nh += \"<body style=\\\"margin:0;padding:0;background:#f1f5f9;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;\\\">\";\nh += \"<table width=\\\"100%\\\" cellpadding=\\\"0\\\" cellspacing=\\\"0\\\" style=\\\"background:#f1f5f9;padding:32px 0;\\\">\";\nh += \"<tr><td align=\\\"center\\\">\";\nh += \"<table width=\\\"640\\\" cellpadding=\\\"0\\\" cellspacing=\\\"0\\\" style=\\\"background:#fff;border-radius:16px;box-shadow:0 4px 24px rgba(0,0,0,0.06);overflow:hidden;max-width:640px;width:100%;\\\">\";\nh += \"<tr><td style=\\\"background:linear-gradient(135deg,#6366f1 0%,#8b5cf6 50%,#a855f7 100%);padding:48px 32px;text-align:center;\\\">\";\nh += \"<h1 style=\\\"margin:0;color:#fff;font-size:32px;font-weight:800;letter-spacing:-0.5px;\\\">&#128236; Tech Digest</h1>\";\nh += \"<p style=\\\"margin:10px 0 0;color:rgba(255,255,255,0.85);font-size:15px;\\\">\" + today + \" &#183; \" + articles.length + \" curated articles</p>\";\nh += \"</td></tr>\";\nh += \"<tr><td style=\\\"padding:28px 32px 12px;\\\"><p style=\\\"margin:0;color:#475569;font-size:15px;line-height:1.6;text-align:center;\\\">Your AI-curated daily selection of the most interesting tech articles from across the web.</p></td></tr>\";\nfor (var idx = 0; idx < articles.length; idx++) {\n  var a = articles[idx];\n  var desc = (a.description || \"\").substring(0, 200);\n  var src = a.source ? \" &#183; \" + a.source : \"\";\n  var dt = \"\";\n  try { dt = a.pubDate ? new Date(a.pubDate).toLocaleDateString(\"en-US\", { month: \"short\", day: \"numeric\" }) : \"\"; } catch(e) {}\n  var num = idx + 1;\n  h += \"<tr><td style=\\\"padding:6px 32px;\\\">\";\n  h += \"<table width=\\\"100%\\\" cellpadding=\\\"0\\\" cellspacing=\\\"0\\\" style=\\\"background:#f8fafc;border-radius:12px;border:1px solid #e2e8f0;\\\">\";\n  h += \"<tr><td style=\\\"padding:18px 20px;\\\">\";\n  h += \"<table cellpadding=\\\"0\\\" cellspacing=\\\"0\\\"><tr>\";\n  h += \"<td style=\\\"vertical-align:top;padding-right:14px;\\\"><span style=\\\"display:inline-block;width:28px;height:28px;border-radius:50%;background:#6366f1;color:#fff;font-size:12px;font-weight:700;line-height:28px;text-align:center;\\\">\" + num + \"</span></td>\";\n  h += \"<td>\";\n  h += \"<a href=\\\"\" + a.link + \"\\\" style=\\\"color:#1e293b;text-decoration:none;font-size:16px;font-weight:600;line-height:1.4;\\\">\" + a.title + \"</a>\";\n  if (desc) h += \"<p style=\\\"margin:6px 0 0;color:#64748b;font-size:13px;line-height:1.5;\\\">\" + desc + \"</p>\";\n  h += \"<p style=\\\"margin:8px 0 0;font-size:11px;color:#94a3b8;\\\">\" + dt + src + \"</p>\";\n  h += \"</td></tr></table>\";\n  h += \"</td></tr></table></td></tr>\";\n}\nh += \"<tr><td style=\\\"padding:28px 32px;text-align:center;border-top:1px solid #e2e8f0;\\\">\";\nh += \"<p style=\\\"margin:0;color:#94a3b8;font-size:13px;\\\">Curated with &#10084;&#65039; by your n8n RSS Digest workflow</p>\";\nh += \"<p style=\\\"margin:4px 0 0;color:#cbd5e1;font-size:11px;\\\">27 RSS sources &#183; AI-curated daily</p>\";\nh += \"</td></tr></table></td></tr></table></body></html>\";\nreturn [{ json: { emailHtml: h, emailSubject: \"Tech Digest - \" + today, articleCount: articles.length } }];"
      },
      "typeVersion": 2
    },
    {
      "id": "7a89c7f3-c608-4dbf-a1e9-f68cead749e1",
      "name": "Send Digest Email",
      "type": "n8n-nodes-base.gmail",
      "position": [
        1920,
        400
      ],
      "parameters": {
        "sendTo": "your@email.com",
        "message": "={{ $json.emailHtml }}",
        "options": {
          "senderName": "Tech Digest Bot",
          "appendAttribution": false
        },
        "subject": "={{ $json.emailSubject }}"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "5dd97a86-c72d-4501-b2a9-32160a39ec0f",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -352,
        -32
      ],
      "parameters": {
        "width": 576,
        "height": 768,
        "content": "Workflow: RSS to E-Mail (7 nodes + AI model)\n\n\n1. Daily Morning Trigger - Fires every day at 8:00 AM\n\n2. Define RSS Sources - Outputs 27 curated RSS feed URLs across 7 categories:\n\nTech News:\n Hacker News, TechCrunch, The Verge, VentureBeat\nEngineering: Meta, Spotify, Stripe, Slack, Cloudflare, Shopify, The Pragmatic Engineer\nAI & ML: OpenAI, Google AI, DeepMind, MIT News, Amazon Science, NVIDIA\n\nStartup: \nFirst Round Review, Irrational Exuberance\nProducts: Product Hunt\n\nScience: \nQuanta Magazine, ScienceAlert, Singularity Hub\n\nBloggers:\nJulia Evans, Dan Luu, Dan Abramov, Joel on Software\n3. Fetch RSS Feeds - Reads each feed (with error handling so one broken feed won't kill the workflow)\n\n4. Clean and Prepare for AI - Deduplicates by URL, strips HTML tags, truncates descriptions, sorts by date, keeps the 150 most recent articles\n\n5. AI Article Curator (GPT-5 Mini) - Reviews all articles and picks the 30 most interesting/diverse ones\n\n6. Build Digest Email - Generates a beautiful HTML email with a purple gradient header, numbered article cards with titles, descriptions, dates, and source attribution\n\n7. Send Digest Email - Sends via Gmail\n\nTo activate it, you need to:\n\nConnect your OpenAI credentials to the AI model node\nConnect your Gmail credentials to the Send node\nSet your email address in the \"Send Digest Email\" node (it's a placeholder right now)\nToggle the workflow to Active"
      },
      "typeVersion": 1
    },
    {
      "id": "7b59bcf8-c125-4466-8f3b-d32cda50212f",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        256,
        192
      ],
      "parameters": {
        "color": 7,
        "width": 416,
        "height": 384,
        "content": "1.Daily Morning Trigger Fires every day at 8:00 AM\n\n\n2. Define RSS Sources - Outputs 27 curated RSS feed URLs across 7 categories"
      },
      "typeVersion": 1
    },
    {
      "id": "c2ff02d1-5ce1-4f5d-aa6d-abcf7c8f9a1a",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        704,
        192
      ],
      "parameters": {
        "color": 7,
        "width": 592,
        "height": 352,
        "content": "3.Fetch RSS Feeds - Reads each feed (with error handling so one broken feed won't kill the workflow)\n\n\n4. Clean and Prepare for AI - Deduplicates by URL, strips HTML tags, truncates descriptions, sorts by date, keeps the 150 most recent articles"
      },
      "typeVersion": 1
    },
    {
      "id": "80483840-5b90-4943-b428-bdd8bdf88cc6",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1344,
        192
      ],
      "parameters": {
        "color": 7,
        "width": 256,
        "height": 512,
        "content": "5.Article Curator (GPT-5 Mini) - Reviews all articles and picks the 30 most interesting/diverse ones"
      },
      "typeVersion": 1
    },
    {
      "id": "53cdff73-8207-46b7-a672-d909eec13794",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1648,
        192
      ],
      "parameters": {
        "color": 7,
        "width": 448,
        "height": 384,
        "content": "6.Build Digest Email - Generates a beautiful HTML email with a purple gradient header, numbered article cards with titles, descriptions, dates, and source attribution\n\n7.Send Digest Email - Sends via Gmail"
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "Fetch RSS Feeds": {
      "main": [
        [
          {
            "node": "Clean and Prepare for AI",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI GPT-5 Mini": {
      "ai_languageModel": [
        [
          {
            "node": "AI Article Curator",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "AI Article Curator": {
      "main": [
        [
          {
            "node": "Build Digest Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Digest Email": {
      "main": [
        [
          {
            "node": "Send Digest Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Define RSS Sources": {
      "main": [
        [
          {
            "node": "Fetch RSS Feeds",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Daily Morning Trigger": {
      "main": [
        [
          {
            "node": "Define RSS Sources",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Clean and Prepare for AI": {
      "main": [
        [
          {
            "node": "AI Article Curator",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}