AutomationFlowsAI & RAG › Create AI News Digests From RSS Feeds with Groq and Send via Gmail

Create AI News Digests From RSS Feeds with Groq and Send via Gmail

ByRedowan Ahmed Farhan @redowanfarhan on n8n.io

RSS feeds from The Verge and TechCrunch are fetched on manual trigger Articles are merged, sorted newest-first, and prepared for AI processing Groq AI Agent 1 summarises articles in batches of 3 using a memory-buffered loop Groq AI Agent 2 assembles all summaries into a polished…

Manual trigger★★★★☆ complexityAI-powered26 nodesRSS Feed ReadAgentGmailGroq Chat
AI & RAG Trigger: Manual Nodes: 26 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow corresponds to n8n.io template #15450 — we link there as the canonical source.

This workflow follows the Agent → Gmail 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 →

Download .json
{
  "nodes": [
    {
      "id": "c8dae6f8-d64b-46c5-a28f-d8bd01575441",
      "name": "Main Overview",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -304,
        -128
      ],
      "parameters": {
        "color": 7,
        "width": 604,
        "height": 800,
        "content": "## \ud83d\udcf0 AI Newsletter Generator (RSS \u2192 Email)\n\nAutomatically fetches the latest AI and tech news, summarises it with AI, and delivers a clean newsletter to your inbox \u2014 on demand or on a schedule.\n\n**Perfect for:** developers, marketers, and teams who want a curated AI news digest without manually browsing multiple sources.\n\n---\n\n## How it works\n\n1. **Manual trigger** starts the workflow (replace with a Schedule Trigger for automatic runs).\n2. **RSS feeds** \u2014 The Verge and TechCrunch AI feeds are fetched in parallel.\n3. **Merge & sort** \u2014 All articles are combined and sorted newest-first.\n4. **24-hour filter** \u2014 Only articles published in the last 24 hours pass through. If none are found, the run exits cleanly.\n5. **Limit** \u2014 Caps at 6 articles to keep the newsletter concise and within token limits.\n6. **AI Summarisation loop (Groq)** \u2014 Articles are processed 2 at a time. Each batch is summarised by AI Agent 1 and the result is stored in workflow static memory.\n7. **Formatting** \u2014 Raw AI output is cleaned: escape characters normalised, dashes removed, paragraph spacing fixed.\n8. **Markdown \u2192 HTML** \u2014 Summaries are converted to email-ready HTML.\n9. **Memory collection** \u2014 All loop summaries are extracted, split, aggregated, and passed to the second AI agent.\n10. **AI Assembly (Groq)** \u2014 AI Agent 2 merges all summaries into a single, polished newsletter body.\n11. **Gmail** \u2014 Final newsletter is delivered to the configured recipient.\n\n---\n\n## Setup (~5 minutes)\n\n1. **Groq API** \u2014 Add your key in both *Groq Chat Model* nodes.\n2. **Gmail** \u2014 Connect via OAuth2 in the *Send a message1* node. Set `sendTo` to your recipient email. Update the subject line if desired.\n3. **RSS sources** \u2014 The Verge and TechCrunch AI feeds are pre-configured. Swap or add RSS Feed nodes to change sources.\n4. **Scheduling** \u2014 Replace the Manual Trigger with a Schedule Trigger (e.g. daily at 8 AM) for automatic delivery.\n5. **Run** \u2014 Click *Execute Workflow* to generate and send your first newsletter."
      },
      "typeVersion": 1
    },
    {
      "id": "37f29e22-9993-49b5-ad9c-cef9ac13b502",
      "name": "Section: Fetch & Filter",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        368,
        64
      ],
      "parameters": {
        "color": 5,
        "width": 1296,
        "height": 560,
        "content": "## 1\ufe0f\u20e3 Fetch, Filter & Prepare\n\nRSS feeds from The Verge and TechCrunch are fetched in parallel, merged, and sorted newest-first. A JavaScript filter discards any articles older than 24 hours. The remaining articles are capped at 6 items and trimmed to their content snippet before entering the summarisation loop."
      },
      "typeVersion": 1
    },
    {
      "id": "6d34f59f-934c-4d43-a49a-4d32678ae4ce",
      "name": "Section: AI Summarisation Loop",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1728,
        64
      ],
      "parameters": {
        "color": 3,
        "width": 1480,
        "height": 464,
        "content": "## 2\ufe0f\u20e3 AI Summarisation Loop\n\nArticles are processed in batches of 2. For each batch, AI Agent 1 (Groq Llama 3.3 70B) generates a structured professional summary. After formatting and Markdown-to-HTML conversion, the result is saved to workflow static memory. The loop continues until all articles are processed, then hands off to the assembly stage."
      },
      "typeVersion": 1
    },
    {
      "id": "3b5a082e-38e6-4752-bce6-85980afe865c",
      "name": "Section: Assembly & Send",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1936,
        560
      ],
      "parameters": {
        "color": 6,
        "width": 1680,
        "height": 404,
        "content": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n## 3\ufe0f\u20e3 Assembly & Delivery\n\nOnce the loop finishes, all stored summaries are extracted from memory, split into individual items, and re-aggregated into a single payload. AI Agent 2 (Groq) cleans up formatting and merges everything into a polished newsletter. The output is converted from Markdown to HTML and sent via Gmail."
      },
      "typeVersion": 1
    },
    {
      "id": "3dbff022-af42-43f0-9e01-d8e95f5bf597",
      "name": "Merge All RSS Items1",
      "type": "n8n-nodes-base.merge",
      "position": [
        656,
        368
      ],
      "parameters": {},
      "typeVersion": 3
    },
    {
      "id": "baf3a3d9-751f-41b3-8e64-dcdd62b07f0e",
      "name": "Sort by Date (Newest First)1",
      "type": "n8n-nodes-base.sort",
      "position": [
        880,
        368
      ],
      "parameters": {
        "options": {},
        "sortFieldsUi": {
          "sortField": [
            {
              "order": "descending",
              "fieldName": "pubDate"
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "2a7b65d9-384b-4b27-a121-d1cd271a14c8",
      "name": "Extract Key Fields1",
      "type": "n8n-nodes-base.set",
      "position": [
        1312,
        368
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "0e5bf66d-413f-4eca-a338-658e84f23d7f",
              "name": "contentSnippet",
              "type": "string",
              "value": "={{ $json.contentSnippet }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "af6ffb32-2f3b-4db8-bdce-51ffa8b54fd8",
      "name": "The verge1",
      "type": "n8n-nodes-base.rssFeedRead",
      "position": [
        416,
        224
      ],
      "parameters": {
        "url": "https://www.theverge.com/rss/ai-artificial-intelligence/index.xml",
        "options": {
          "ignoreSSL": true
        }
      },
      "typeVersion": 1
    },
    {
      "id": "7362b986-8f65-4e0b-9145-3bbcb09afd09",
      "name": "TechCrunch1",
      "type": "n8n-nodes-base.rssFeedRead",
      "position": [
        416,
        464
      ],
      "parameters": {
        "url": "https://techcrunch.com/category/artificial-intelligence/feed/",
        "options": {
          "ignoreSSL": true
        }
      },
      "typeVersion": 1
    },
    {
      "id": "93349678-b158-437f-8676-fe24e6c54333",
      "name": "AI Agent2",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        2064,
        240
      ],
      "parameters": {
        "text": "={{ $json.contentSnippet }}",
        "options": {
          "systemMessage": "=You are a professional content assistant.\n\nYour task is to analyze the provided data and create a clear, professional summary formatted as the body of an email.\n\nInstructions:\n\n1. Read all provided items carefully.\n2. Summarize each item in a concise and professional manner.\n3. Maintain a clean structure so the email is easy to read.\n4. Separate each summarized item with a clear paragraph gap.\n5. Use simple, professional language suitable for a business email.\n6. Do NOT include a subject line.\n7. Start the email body with a short introduction such as:\n   \"Here is the summary of the latest updates:\"\n8. Present each summary as a numbered section.\n\nOutput Format:\n\nStart with a short introduction, followed by numbered summaries.\n\nExample structure:\n\nHere is the summary of the latest updates:\n\n1. First Update\n   Provide a short and clear summary of the first item.\n\n2. Second Update\n   Provide a short and clear summary of the second item.\n\n3. Third Update\n   Provide a short and clear summary of the third item.\n\nEnsure the final output looks like a clean professional email body with proper spacing between sections.\n"
        },
        "promptType": "define"
      },
      "typeVersion": 3.1
    },
    {
      "id": "88493800-dccf-4821-a9b4-557598f616b7",
      "name": "Code in JavaScript1",
      "type": "n8n-nodes-base.code",
      "position": [
        1088,
        368
      ],
      "parameters": {
        "jsCode": "const now = Date.now();\nconst cutoff = now - 24 * 60 * 60 * 1000;\n\nconst filtered = items.filter(item => {\n  const dateStr = item.json.isoDate || item.json.pubDate || item.json.date || null;\n  if (!dateStr) return false;\n  const pubTime = new Date(dateStr).getTime();\n  if (isNaN(pubTime)) return false;\n  return pubTime >= cutoff;\n});\n\nif (filtered.length === 0) {\n  return [{\n    json: {\n      _noArticles: true,\n      message: \"No articles found in the last 24 hours.\",\n      checkedAt: new Date().toISOString()\n    }\n  }];\n}\n\nconsole.log(`\u2705 ${filtered.length} articles passed the 24h filter (out of ${items.length} total)`);\n\nreturn filtered;"
      },
      "typeVersion": 2
    },
    {
      "id": "d5aba26e-3d0c-486c-96b6-36af1a0f150f",
      "name": "Loop Over Items1",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        1728,
        304
      ],
      "parameters": {
        "options": {},
        "batchSize": 2
      },
      "typeVersion": 3
    },
    {
      "id": "58427726-0684-43e2-a08b-a1fb24300af5",
      "name": "Markdown2",
      "type": "n8n-nodes-base.markdown",
      "position": [
        2608,
        224
      ],
      "parameters": {
        "mode": "markdownToHtml",
        "options": {},
        "markdown": "={{ $json.professional_summary }}"
      },
      "typeVersion": 1
    },
    {
      "id": "b0b04dcc-3b1d-44a2-a677-fdfea6df9a38",
      "name": "Send a message",
      "type": "n8n-nodes-base.gmail",
      "position": [
        3472,
        592
      ],
      "parameters": {
        "sendTo": "user@example.com",
        "message": "={{ $json.output }}",
        "options": {
          "appendAttribution": false
        },
        "subject": "Your Weekly AI & Tech Newsletter"
      },
      "typeVersion": 2.2
    },
    {
      "id": "41931e4c-e450-475c-b79c-38d80caf4eea",
      "name": "Limit1",
      "type": "n8n-nodes-base.limit",
      "position": [
        1520,
        368
      ],
      "parameters": {
        "maxItems": 6
      },
      "typeVersion": 1
    },
    {
      "id": "01c1abf8-edb4-414c-897a-47df8405ef70",
      "name": "memory1",
      "type": "n8n-nodes-base.code",
      "position": [
        2848,
        240
      ],
      "parameters": {
        "jsCode": "// Access workflow static memory\nconst store = $getWorkflowStaticData('global');\n\n// Initialize storage array if it doesn't exist\nif (!store.collectedSummaries) {\n  store.collectedSummaries = [];\n}\n\n// Push current loop item\nstore.collectedSummaries.push({\n  professional_summary: $json.professional_summary,\n  data: $json.data\n});\n\n// Return current item so the loop continues\nreturn $input.item;"
      },
      "typeVersion": 2
    },
    {
      "id": "59c5fa83-3583-401f-b23a-ef433cae3fde",
      "name": "Groq Chat Model2",
      "type": "@n8n/n8n-nodes-langchain.lmChatGroq",
      "position": [
        2096,
        448
      ],
      "parameters": {
        "model": "llama-3.3-70b-versatile",
        "options": {}
      },
      "typeVersion": 1
    },
    {
      "id": "d4e0d226-e627-47f9-a002-9570847bdf5b",
      "name": "Next 3 Items1",
      "type": "n8n-nodes-base.noOp",
      "position": [
        3104,
        288
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "1d043251-5e0d-4848-a7db-71aafc0e334e",
      "name": "Extract Saved data1",
      "type": "n8n-nodes-base.code",
      "position": [
        2016,
        592
      ],
      "parameters": {
        "jsCode": "const store = $getWorkflowStaticData('global');\n\nconst results = store.collectedSummaries || [];\n\n// Optional: clear memory for next run\nstore.collectedSummaries = [];\n\nreturn [\n  {\n    json: {\n      all_summaries: results\n    }\n  }\n];"
      },
      "typeVersion": 2
    },
    {
      "id": "9cd43306-a227-470b-bc7d-8fe18ac87d8d",
      "name": "Edit Fields1",
      "type": "n8n-nodes-base.set",
      "position": [
        2656,
        608
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "ddcbc967-72d3-4cc4-9982-d95d481727cc",
              "name": "Data",
              "type": "string",
              "value": "={{ $json.data }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "baeb1c64-2bd8-426e-a6e6-a8469a36fb48",
      "name": "Split Out1",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        2224,
        592
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "all_summaries"
      },
      "typeVersion": 1
    },
    {
      "id": "3162e8b4-d11b-4296-b779-91c337a6ee4d",
      "name": "Aggregate1",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        2432,
        592
      ],
      "parameters": {
        "options": {},
        "fieldsToAggregate": {
          "fieldToAggregate": [
            {
              "fieldToAggregate": "data"
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "a25f482b-edd9-476d-af0d-6715e57e4a19",
      "name": "Formatting1",
      "type": "n8n-nodes-base.code",
      "position": [
        2384,
        240
      ],
      "parameters": {
        "jsCode": "// Ensure we are working with the input items\nreturn $input.all().map(item => {\n  // Capture the output from your AI Agent\n  let text = item.json.output || \"\";\n\n  // 1. Convert literal '\\n' strings into actual line breaks\n  let formatted = text.replace(/\\\\n/g, '\\n');\n\n  // 2. Remove the ugly dashed separators (-------)\n  formatted = formatted.replace(/-{3,}/g, '');\n\n  // 3. Fix paragraph spacing (ensuring a clean gap)\n  formatted = formatted.replace(/\\n{3,}/g, '\\n\\n').trim();\n\n  return {\n    json: {\n      professional_summary: formatted\n    }\n  };\n});"
      },
      "typeVersion": 2
    },
    {
      "id": "e7520ad2-9cd4-478d-b4e6-b888ab8b2a1c",
      "name": "AI Agent3",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        2880,
        576
      ],
      "parameters": {
        "text": "=you are a helpful assitant who helps to format scattered or unformatted data\n{{ $json.Data }}",
        "options": {
          "systemMessage": "you need to format the data in a ready made way to present to the user.\n\nInstructions:\nremove repetitive headlines, remove unnecessary gaps etc.\noutput:\njust give me the presentable data nothing more."
        },
        "promptType": "define"
      },
      "typeVersion": 3.1
    },
    {
      "id": "d5bc6659-ac78-4866-b4c9-a7203ff30047",
      "name": "Groq Chat Model3",
      "type": "@n8n/n8n-nodes-langchain.lmChatGroq",
      "position": [
        2880,
        784
      ],
      "parameters": {
        "model": "llama-3.3-70b-versatile",
        "options": {}
      },
      "typeVersion": 1
    },
    {
      "id": "808c0a36-9724-4055-a363-b523e1de568c",
      "name": "Markdown3",
      "type": "n8n-nodes-base.markdown",
      "position": [
        3232,
        576
      ],
      "parameters": {
        "mode": "markdownToHtml",
        "options": {},
        "markdown": "={{ $json.output }}"
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "Limit1": {
      "main": [
        [
          {
            "node": "Loop Over Items1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "memory1": {
      "main": [
        [
          {
            "node": "Next 3 Items1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Agent2": {
      "main": [
        [
          {
            "node": "Formatting1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Agent3": {
      "main": [
        [
          {
            "node": "Markdown3",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Markdown2": {
      "main": [
        [
          {
            "node": "memory1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Markdown3": {
      "main": [
        [
          {
            "node": "Send a message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Aggregate1": {
      "main": [
        [
          {
            "node": "Edit Fields1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Out1": {
      "main": [
        [
          {
            "node": "Aggregate1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "The verge1": {
      "main": [
        [
          {
            "node": "Merge All RSS Items1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Formatting1": {
      "main": [
        [
          {
            "node": "Markdown2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "TechCrunch1": {
      "main": [
        [
          {
            "node": "Merge All RSS Items1",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Edit Fields1": {
      "main": [
        [
          {
            "node": "AI Agent3",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Next 3 Items1": {
      "main": [
        [
          {
            "node": "Loop Over Items1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Groq Chat Model2": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent2",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Groq Chat Model3": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent3",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Items1": {
      "main": [
        [
          {
            "node": "Extract Saved data1",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "AI Agent2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code in JavaScript1": {
      "main": [
        [
          {
            "node": "Extract Key Fields1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Key Fields1": {
      "main": [
        [
          {
            "node": "Limit1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Saved data1": {
      "main": [
        [
          {
            "node": "Split Out1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge All RSS Items1": {
      "main": [
        [
          {
            "node": "Sort by Date (Newest First)1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Sort by Date (Newest First)1": {
      "main": [
        [
          {
            "node": "Code in JavaScript1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

RSS feeds from The Verge and TechCrunch are fetched on manual trigger Articles are merged, sorted newest-first, and prepared for AI processing Groq AI Agent 1 summarises articles in batches of 3 using a memory-buffered loop Groq AI Agent 2 assembles all summaries into a polished…

Source: https://n8n.io/workflows/15450/ — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

How it works: Daily Trigger: Every morning at 8 AM, the workflow is automatically triggered. Fetch Trending Topics: The workflow collects trending topics from external sources, such as news RSS feeds

RSS Feed Read, Reddit, Google Sheets +5
AI & RAG

This n8n workflow automatically analyzes your stock portfolio every day at 4 PM. It fetches portfolio data from Google Sheets, enriches it with latest market news via RSS, generates AI-powered stock i

Google Sheets, RSS Feed Read, Agent +2
AI & RAG

This workflow automatically generates 2–3 high-quality Indian stock investment ideas daily by combining trending stock data + latest market news, processing it with AI (Groq/OpenAI), avoiding duplicat

HTTP Request, Agent, RSS Feed Read +5
AI & RAG

(Google News + Groq + Gmail)

Google Sheets, RSS Feed Read, Agent +2
AI & RAG

BoomerBobBot.TP. Uses agent, telegramTrigger, telegram, memoryBufferWindow. Event-driven trigger; 95 nodes.

Agent, Telegram Trigger, Telegram +10