AutomationFlowsAI & RAG › Send Daily Google Alerts AI Digest with Gpt-4.1-mini and Gmail

Send Daily Google Alerts AI Digest with Gpt-4.1-mini and Gmail

ByIncrementors @incrementors on n8n.io

This workflow runs daily to fetch multiple Google Alerts RSS feeds, uses OpenAI GPT-4.1-mini to score and summarize each alert with sentiment and recommended actions, then compiles the most relevant items into a branded HTML digest and sends it via Gmail. Runs every 24 hours on…

Cron / scheduled trigger★★★★☆ complexityAI-powered18 nodesHTTP RequestAgentOpenAI ChatGmail
AI & RAG Trigger: Cron / scheduled Nodes: 18 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow corresponds to n8n.io template #16024 — 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
{
  "id": "msA82sOv00oj0Bxl",
  "name": "Google Alerts AI Monitor",
  "tags": [],
  "nodes": [
    {
      "id": "2e7ead43-be1f-492c-a7f4-5e078b15eb5a",
      "name": "Overview",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -640,
        -368
      ],
      "parameters": {
        "color": 4,
        "width": 508,
        "height": 1188,
        "content": "## Google Alerts AI Digest \u2014 RSS + GPT-4.1-mini + Gmail Daily Email\n\nFor brand managers, PR teams, and competitive intelligence analysts who want a daily summary of all their Google Alerts \u2014 automatically analyzed, scored by relevance, and delivered as a formatted HTML email digest. A schedule trigger fires daily. A Code node defines the Google Alerts RSS feed URLs with names and categories \u2014 add as many feeds as needed. HTTP fetches each feed as XML text. A Code node parses the Atom entries within the last 48 hours, cleans HTML entities, and extracts title, link, summary, and published date. An IF node skips feeds with no new results. GPT-4.1-mini analyzes each alert and returns a relevance score (1\u201310), a one-sentence insight, sentiment (Positive/Neutral/Negative), and a recommended action. A Code node parses the AI JSON output with fallbacks. An IF node keeps only alerts scoring 4 or above. An Aggregate node collects all filtered alerts into one array. A final Code node groups alerts by category, sorts by relevance, and builds a branded HTML email with a stats bar, colored relevance badges, and sentiment tags. Gmail sends the digest.\n\n## How it works\n- **1. Schedule \u2014 Every 24 Hours** triggers the pipeline daily\n- **2. Code \u2014 Set Alert Feed URLs** defines the RSS feed array with name, url, and category. Add multiple feeds by uncommenting the example entries\n- **3. HTTP \u2014 Fetch RSS Feed** fetches each RSS feed as plain text XML\n- **4. Code \u2014 Parse RSS Entries** parses Atom XML entries from the last 48 hours, strips HTML, and emits one item per article\n- **5. IF \u2014 Has Results?** \u2014 TRUE (has articles): proceeds to AI analysis | FALSE (empty feed): stops silently\n- **6. AI Agent \u2014 Analyze Alert** sends each article to GPT-4.1-mini for relevance score, insight, sentiment, and action recommendation\n- **OpenAI \u2014 GPT-4.1-mini Model** language model attached to the AI Agent (temp 0.2, max 250 tokens)\n- **7. Code \u2014 Parse AI Response** strips markdown fences, parses the JSON, validates sentiment, and merges with original article data\n- **8. IF \u2014 Filter Relevance (Score 4 or Above)** keeps only articles scoring 4 or higher\n- **9. Aggregate \u2014 Collect All Alerts** aggregates all filtered articles into a single data array\n- **10. Code \u2014 Build HTML Email Digest** groups by category, sorts by relevance score, builds the full HTML email with stat bar and colored cards\n- **11. Gmail \u2014 Send Digest Email** sends the HTML digest to your email address\n\n## Set up steps\n1. In **2. Code \u2014 Set Alert Feed URLs** \u2014 replace the example Google Alerts RSS URL with your own. Get your feed URL from google.com/alerts \u2192 your alert \u2192 RSS icon. Add multiple feeds by duplicating the object in the array\n2. In **OpenAI \u2014 GPT-4.1-mini Model** \u2014 connect your OpenAI API credential\n3. In **11. Gmail \u2014 Send Digest Email** \u2014 connect Gmail OAuth2 credential and replace `REPLACE_WITH_YOUR_EMAIL@example.com`\n4. In **10. Code \u2014 Build HTML Email Digest** \u2014 replace `YOUR_BRAND_NAME` in the footer with your company name"
      },
      "typeVersion": 1
    },
    {
      "id": "bcda9da1-3d32-424d-83e0-fa7b5ba659ac",
      "name": "Section \u2014 Schedule and Alert Feed URL Config",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        0,
        -96
      ],
      "parameters": {
        "color": 5,
        "width": 420,
        "height": 436,
        "content": "## Schedule and Alert Feed URL Config\nSchedule fires every 24 hours. Code node defines the RSS feed array \u2014 add name, URL, and category for each Google Alert feed. Multiple feeds are supported."
      },
      "typeVersion": 1
    },
    {
      "id": "9831a5ba-f91e-4d1b-a885-3eb68e86531b",
      "name": "Section \u2014 RSS Fetch and Entry Parse",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        448,
        -64
      ],
      "parameters": {
        "color": 6,
        "width": 404,
        "height": 340,
        "content": "## RSS Fetch and Entry Parse\nHTTP fetches the RSS XML for each feed. Code parses Atom entries within the last 48 hours, strips HTML entities, and emits one item per article."
      },
      "typeVersion": 1
    },
    {
      "id": "7c88bf14-78a9-4f69-982b-feeccd690bcd",
      "name": "Section \u2014 Has Results Check and GPT-4.1-mini Alert Analysis",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        896,
        -160
      ],
      "parameters": {
        "color": 6,
        "width": 516,
        "height": 628,
        "content": "## Has Results Check and GPT-4.1-mini Alert Analysis\nIF skips empty feeds silently. AI Agent analyzes each article \u2014 returns relevance 1\u201310, one-sentence insight, sentiment (Positive/Neutral/Negative), and action recommendation."
      },
      "typeVersion": 1
    },
    {
      "id": "e802f608-fbc1-45f9-a7d7-789305fe7607",
      "name": "Section \u2014 AI Response Parse, Relevance Filter, and Aggregate",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1472,
        -112
      ],
      "parameters": {
        "color": 6,
        "width": 644,
        "height": 420,
        "content": "## AI Response Parse, Relevance Filter, and Aggregate\nCode parses AI JSON with fallbacks. IF keeps only alerts scoring 4 or above. Aggregate collects all filtered alerts into one array for the email builder."
      },
      "typeVersion": 1
    },
    {
      "id": "64892b09-a394-439a-b9e8-296d3ce2434b",
      "name": "Section \u2014 HTML Digest Build and Gmail Send",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2144,
        -64
      ],
      "parameters": {
        "color": 4,
        "width": 484,
        "height": 340,
        "content": "## HTML Digest Build and Gmail Send\nCode groups alerts by category, sorts by relevance score, and builds the HTML email with stat bar and colored relevance and sentiment badges. Gmail sends the digest."
      },
      "typeVersion": 1
    },
    {
      "id": "98b5838d-6ed0-4e87-bf67-125024c7d8ba",
      "name": "1. Schedule \u2014 Every 24 Hours",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        48,
        64
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "hours",
              "hoursInterval": 24
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "587f6081-92ee-4e26-a13e-0a0e09584623",
      "name": "2. Code \u2014 Set Alert Feed URLs",
      "type": "n8n-nodes-base.code",
      "position": [
        288,
        64
      ],
      "parameters": {
        "jsCode": "const alertFeeds = [\n  {\n    name: \"YOUR_ALERT_NAME\",\n    url: \"YOUR_GOOGLE_ALERTS_RSS_URL\",\n    category: \"Brand Monitoring\"\n  }\n  // ADD MORE FEEDS:\n  // ,{ name: \"Competitor Alert\", url: \"YOUR_COMPETITOR_RSS_URL\", category: \"Competitor Intelligence\" }\n  // ,{ name: \"Industry News\", url: \"YOUR_INDUSTRY_RSS_URL\", category: \"Industry Intelligence\" }\n];\n// Get your RSS URL: google.com/alerts \u2192 your alert \u2192 RSS icon (feed icon at bottom)\nreturn alertFeeds.map(feed => ({ json: feed }));"
      },
      "typeVersion": 2
    },
    {
      "id": "8091ac49-514d-4029-bc40-588aa2be31c8",
      "name": "3. HTTP \u2014 Fetch RSS Feed",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        496,
        64
      ],
      "parameters": {
        "url": "={{ $json.url }}",
        "options": {
          "response": {
            "response": {
              "responseFormat": "text"
            }
          }
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "fc0ce615-33b9-4c90-8109-11d6754197ab",
      "name": "4. Code \u2014 Parse RSS Entries",
      "type": "n8n-nodes-base.code",
      "position": [
        720,
        64
      ],
      "parameters": {
        "jsCode": "const rssData  = $input.item.json.data || '';\nconst feedMeta = $('2. Code \u2014 Set Alert Feed URLs').item.json;\nconst feedName = feedMeta.name     || 'Unknown Feed';\nconst category = feedMeta.category || 'General';\n\nconst entries = [];\nconst entryRegex = /<entry>(.*?)<\\/entry>/gs;\nlet match;\n\nwhile ((match = entryRegex.exec(rssData)) !== null) {\n  const entry = match[1];\n\n  const titleMatch     = entry.match(/<title[^>]*>(.*?)<\\/title>/s);\n  const linkMatch      = entry.match(/<link[^>]*href=\"([^\"]+)\"/);\n  const contentMatch   = entry.match(/<content[^>]*>(.*?)<\\/content>/s);\n  const summaryMatch   = entry.match(/<summary[^>]*>(.*?)<\\/summary>/s);\n  const publishedMatch = entry.match(/<published>(.*?)<\\/published>/);\n\n  const clean = s => s\n    .replace(/<[^>]+>/g, '')\n    .replace(/&amp;/g, '&')\n    .replace(/&lt;/g, '<')\n    .replace(/&gt;/g, '>')\n    .replace(/&quot;/g, '\"')\n    .replace(/&#39;/g, \"'\")\n    .replace(/&apos;/g, \"'\")\n    .trim();\n\n  const title      = titleMatch    ? clean(titleMatch[1])   : '';\n  const link       = linkMatch     ? linkMatch[1]           : '';\n  const rawSummary = contentMatch  ? contentMatch[1] : (summaryMatch ? summaryMatch[1] : '');\n  const summary    = clean(rawSummary).substring(0, 600);\n  const published  = publishedMatch ? publishedMatch[1] : new Date().toISOString();\n\n  const pubDate   = new Date(published);\n  const hoursDiff = (Date.now() - pubDate.getTime()) / 3600000;\n\n  if (hoursDiff <= 48 && title) {\n    entries.push({ title, link, summary, published, feedName, category });\n  }\n}\n\nif (entries.length === 0) {\n  return [{ json: { noResults: true, feedName, category } }];\n}\n\nreturn entries.map(e => ({ json: e }));"
      },
      "typeVersion": 2
    },
    {
      "id": "ec63d605-1419-4635-a213-eb0873c48d6f",
      "name": "5. IF \u2014 Has Results?",
      "type": "n8n-nodes-base.if",
      "position": [
        944,
        64
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": false,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "operator": {
                "type": "boolean",
                "operation": "notEquals"
              },
              "leftValue": "={{ $json.noResults }}",
              "rightValue": true
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "600a7fc8-5c0e-4d4e-8f71-4fb0d24a5c2c",
      "name": "6. AI Agent \u2014 Analyze Alert",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        1168,
        64
      ],
      "parameters": {
        "text": "=You are an expert news analyst for brand and competitive intelligence.\n\nAnalyze the following news alert and respond ONLY with a valid JSON object.\nNo markdown, no explanation, no extra text \u2014 just raw JSON.\n\nAlert Details:\n- Category: {{ $json.category }}\n- Feed Name: {{ $json.feedName }}\n- Title: {{ $json.title }}\n- Summary: {{ $json.summary }}\n- Published: {{ $json.published }}\n\nReturn this exact JSON structure:\n{\n  \"relevance\": <number 1-10>,\n  \"insight\": \"<one clear sentence: why this matters>\",\n  \"sentiment\": \"<exactly one of: Positive, Neutral, Negative>\",\n  \"action\": \"<one short action: Monitor / Share internally / Respond publicly / Escalate to PR>\"\n}",
        "options": {
          "systemMessage": "You are a precise news analyst. Always respond with valid JSON only. No markdown fences, no preamble, no explanation. Just the raw JSON object."
        },
        "promptType": "define"
      },
      "typeVersion": 3.1
    },
    {
      "id": "07dc20f3-91cb-499b-852a-3926f26d1277",
      "name": "OpenAI \u2014 GPT-4.1-mini Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        1168,
        272
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini",
          "cachedResultName": "gpt-4.1-mini"
        },
        "options": {
          "maxTokens": 250,
          "temperature": 0.2
        },
        "builtInTools": {}
      },
      "typeVersion": 1.3
    },
    {
      "id": "0ed89959-2f11-4eb3-9abe-a28c2fe22a8d",
      "name": "7. Code \u2014 Parse AI Response",
      "type": "n8n-nodes-base.code",
      "position": [
        1520,
        64
      ],
      "parameters": {
        "jsCode": "const agentOutput = $input.item.json.output || '';\nconst prev = $('5. IF \u2014 Has Results?').item.json;\n\nlet analysis = {\n  relevance: 5,\n  insight: 'Could not analyze this alert.',\n  sentiment: 'Neutral',\n  action: 'Monitor'\n};\n\ntry {\n  const cleaned = agentOutput\n    .replace(/```json/gi, '')\n    .replace(/```/g, '')\n    .trim();\n  const jsonMatch = cleaned.match(/\\{[\\s\\S]*?\\}/);\n  if (jsonMatch) {\n    const parsed = JSON.parse(jsonMatch[0]);\n    analysis.relevance = Math.min(10, Math.max(1, Number(parsed.relevance) || 5));\n    analysis.insight   = String(parsed.insight  || analysis.insight);\n    analysis.sentiment = String(parsed.sentiment || analysis.sentiment);\n    analysis.action    = String(parsed.action    || analysis.action);\n  }\n} catch(e) { /* keep defaults */ }\n\nconst validSentiments = ['Positive', 'Neutral', 'Negative'];\nif (!validSentiments.includes(analysis.sentiment)) analysis.sentiment = 'Neutral';\n\nreturn [{ json: {\n  title:              prev.title     || '',\n  link:               prev.link      || '',\n  summary:            prev.summary   || '',\n  published:          prev.published || '',\n  feedName:           prev.feedName  || '',\n  category:           prev.category  || '',\n  analysis_relevance: analysis.relevance,\n  analysis_insight:   analysis.insight,\n  analysis_sentiment: analysis.sentiment,\n  analysis_action:    analysis.action\n}}];"
      },
      "typeVersion": 2
    },
    {
      "id": "9afc6d6f-44f3-4221-8308-c7a2b1d1059b",
      "name": "8. IF \u2014 Filter Relevance (Score 4 or Above)",
      "type": "n8n-nodes-base.if",
      "position": [
        1744,
        64
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "d432eef3-e8a4-4029-a4d0-6ed9abf9dd52",
              "operator": {
                "type": "number",
                "operation": "gte"
              },
              "leftValue": "={{ $json.analysis_relevance }}",
              "rightValue": 4
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "8ac83d47-b78d-4cca-8dc3-5d6766dc1165",
      "name": "9. Aggregate \u2014 Collect All Alerts",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        1968,
        64
      ],
      "parameters": {
        "options": {},
        "aggregate": "aggregateAllItemData"
      },
      "typeVersion": 1
    },
    {
      "id": "0d20a892-0231-4f22-8717-57b7b2555f08",
      "name": "10. Code \u2014 Build HTML Email Digest",
      "type": "n8n-nodes-base.code",
      "position": [
        2192,
        64
      ],
      "parameters": {
        "jsCode": "const items = $input.item.json.data || [];\n\nconst today      = new Date().toLocaleDateString('en-US', { weekday:'long', year:'numeric', month:'long', day:'numeric' });\nconst todayShort = new Date().toLocaleDateString('en-US', { month:'short', day:'numeric', year:'numeric' });\n\nif (!items.length) {\n  return [{ json: {\n    emailHtml: `<html><body style=\"font-family:Arial;padding:20px\"><h2>Daily Google Alerts Digest</h2><p>No relevant alerts found today (${todayShort}).</p></body></html>`,\n    subject: `Google Alerts Digest - No New Alerts | ${todayShort}`,\n    count: 0\n  }}];\n}\n\nconst grouped = {};\nitems.forEach(item => {\n  const cat = item.category || 'General';\n  if (!grouped[cat]) grouped[cat] = [];\n  grouped[cat].push(item);\n});\nObject.keys(grouped).forEach(cat =>\n  grouped[cat].sort((a,b) => (b.analysis_relevance||0) - (a.analysis_relevance||0))\n);\n\nconst sentColor = { Positive:'#27ae60', Neutral:'#2980b9', Negative:'#e74c3c' };\nconst borderCol = r => r >= 8 ? '#e74c3c' : r >= 6 ? '#e67e22' : '#3498db';\nconst highPri   = items.filter(i => i.analysis_relevance >= 8).length;\nconst posCount  = items.filter(i => i.analysis_sentiment === 'Positive').length;\n\nlet html = `<!DOCTYPE html><html><head><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n<style>\n*{box-sizing:border-box;margin:0;padding:0}\nbody{font-family:Arial,sans-serif;background:#f0f2f5}\n.wrap{max-width:680px;margin:20px auto;border-radius:10px;overflow:hidden;box-shadow:0 4px 20px rgba(0,0,0,.12)}\n.hdr{background:linear-gradient(135deg,#1a252f,#2c3e50);color:#fff;padding:28px 24px}\n.hdr h1{font-size:22px;margin-bottom:6px}\n.hdr p{font-size:13px;opacity:.75}\n.statsbar{background:#2471a3;display:flex}\n.stat{flex:1;padding:10px 16px;color:#fff;font-size:12px;border-right:1px solid rgba(255,255,255,.15)}\n.stat:last-child{border-right:none}\n.stat strong{font-size:18px;display:block}\n.cathead{background:#34495e;color:#fff;padding:10px 20px;font-size:13px;font-weight:bold;letter-spacing:.5px}\n.body{background:#fff}\n.card{border-left:4px solid #3498db;margin:14px 16px;padding:12px 14px;background:#fafbfc;border-radius:0 6px 6px 0}\n.card-title{font-size:14px;font-weight:bold;margin-bottom:5px}\n.card-title a{color:#1a252f;text-decoration:none}\n.card-meta{font-size:11px;color:#95a5a6;margin-bottom:7px}\n.card-insight{font-size:13px;color:#444;line-height:1.5;margin-bottom:8px}\n.badges{display:flex;gap:6px;flex-wrap:wrap}\n.badge{font-size:11px;padding:3px 9px;border-radius:20px;font-weight:bold;color:#fff}\n.b-rel{background:#2980b9}.b-act{background:#e67e22}\n.footer{background:#ecf0f1;padding:14px 20px;text-align:center;font-size:11px;color:#7f8c8d}\n</style></head><body>\n<div class=\"wrap\">\n<div class=\"hdr\"><h1>Daily Google Alerts Digest</h1><p>${today}</p></div>\n<div class=\"statsbar\">\n  <div class=\"stat\"><strong>${items.length}</strong>Total Alerts</div>\n  <div class=\"stat\"><strong>${Object.keys(grouped).length}</strong>Categories</div>\n  <div class=\"stat\"><strong>${highPri}</strong>High Priority</div>\n  <div class=\"stat\"><strong>${posCount}</strong>Positive</div>\n</div>\n<div class=\"body\">`;\n\nObject.entries(grouped).forEach(([cat, alerts]) => {\n  html += `<div class=\"cathead\">${cat} \u00b7 ${alerts.length} alert${alerts.length>1?'s':''}</div>`;\n  alerts.forEach(a => {\n    const sc  = sentColor[a.analysis_sentiment] || '#2980b9';\n    const bc  = borderCol(a.analysis_relevance || 5);\n    const pub = (() => { try { return new Date(a.published).toLocaleString('en-US',{month:'short',day:'numeric',hour:'2-digit',minute:'2-digit'}); } catch(e){ return a.published; } })();\n    const actualUrl = a.link.includes('google.com/url')\n      ? decodeURIComponent(a.link.match(/url=([^&]+)/)?.[1] || a.link)\n      : a.link;\n    html += `\n<div class=\"card\" style=\"border-left-color:${bc}\">\n  <div class=\"card-title\"><a href=\"${actualUrl}\" target=\"_blank\">${a.title}</a></div>\n  <div class=\"card-meta\">${a.feedName} | ${pub}</div>\n  <div class=\"card-insight\">${a.analysis_insight}</div>\n  <div class=\"badges\">\n    <span class=\"badge b-rel\">${a.analysis_relevance}/10</span>\n    <span class=\"badge\" style=\"background:${sc}\">${a.analysis_sentiment}</span>\n    ${a.analysis_action ? `<span class=\"badge b-act\">${a.analysis_action}</span>` : ''}\n  </div>\n</div>`;\n  });\n});\n\nhtml += `</div><div class=\"footer\">Powered by n8n + GPT-4.1-mini | YOUR_BRAND_NAME | Relevance 4 or above</div></div></body></html>`;\n\nreturn [{ json: {\n  emailHtml: html,\n  subject:   `Google Alerts Digest \u2014 ${items.length} Alert${items.length>1?'s':''} | ${todayShort}`,\n  count:     items.length\n}}];"
      },
      "typeVersion": 2
    },
    {
      "id": "3a32956c-6b9e-4a4e-b7c7-bd46bf9871a7",
      "name": "11. Gmail \u2014 Send Digest Email",
      "type": "n8n-nodes-base.gmail",
      "position": [
        2416,
        64
      ],
      "parameters": {
        "sendTo": "user@example.com",
        "message": "={{ $json.emailHtml }}",
        "options": {
          "appendAttribution": false
        },
        "subject": "={{ $json.subject }}"
      },
      "typeVersion": 2.1
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "executionOrder": "v1"
  },
  "versionId": "7bf248f0-030b-4c23-aedb-dba1e8b10b55",
  "connections": {
    "5. IF \u2014 Has Results?": {
      "main": [
        [
          {
            "node": "6. AI Agent \u2014 Analyze Alert",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "3. HTTP \u2014 Fetch RSS Feed": {
      "main": [
        [
          {
            "node": "4. Code \u2014 Parse RSS Entries",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "4. Code \u2014 Parse RSS Entries": {
      "main": [
        [
          {
            "node": "5. IF \u2014 Has Results?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "6. AI Agent \u2014 Analyze Alert": {
      "main": [
        [
          {
            "node": "7. Code \u2014 Parse AI Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "7. Code \u2014 Parse AI Response": {
      "main": [
        [
          {
            "node": "8. IF \u2014 Filter Relevance (Score 4 or Above)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI \u2014 GPT-4.1-mini Model": {
      "ai_languageModel": [
        [
          {
            "node": "6. AI Agent \u2014 Analyze Alert",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "1. Schedule \u2014 Every 24 Hours": {
      "main": [
        [
          {
            "node": "2. Code \u2014 Set Alert Feed URLs",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "2. Code \u2014 Set Alert Feed URLs": {
      "main": [
        [
          {
            "node": "3. HTTP \u2014 Fetch RSS Feed",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "9. Aggregate \u2014 Collect All Alerts": {
      "main": [
        [
          {
            "node": "10. Code \u2014 Build HTML Email Digest",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "10. Code \u2014 Build HTML Email Digest": {
      "main": [
        [
          {
            "node": "11. Gmail \u2014 Send Digest Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "8. IF \u2014 Filter Relevance (Score 4 or Above)": {
      "main": [
        [
          {
            "node": "9. Aggregate \u2014 Collect All Alerts",
            "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

This workflow runs daily to fetch multiple Google Alerts RSS feeds, uses OpenAI GPT-4.1-mini to score and summarize each alert with sentiment and recommended actions, then compiles the most relevant items into a branded HTML digest and sends it via Gmail. Runs every 24 hours on…

Source: https://n8n.io/workflows/16024/ — 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

This n8n automation workflow automates the creation, scripting, production, and posting of YouTube videos. It leverages AI (OpenAI), image generation (PIAPI), video rendering (Shotstack), and platform

Agent, OpenAI Chat, Airtable Tool +7
AI & RAG

Created by: Peyton Leveillee Last updated: October 2025

OpenAI Chat, Google Sheets, HTTP Request +5
AI & RAG

The Multi-Model Agency Content Engine is a high-performance editorial system designed for agencies. It solves the "blank page" problem by alternating between real-world social proof and strategic expe

Google Sheets, Gmail, Google Drive +6
AI & RAG

This workflow automates the creation, rendering, approval, and posting of TikTok-style POV (Point of View) videos to Instagram, with cross-posting to Facebook and YouTube. It eliminates manual video p

OpenAI Chat, Output Parser Item List, HTTP Request +10
AI & RAG

Generate SEO-friendly WordPress blog drafts from a Google Sheets queue using OpenAI. This workflow writes full HTML blog content, selects a relevant Pexels featured image with a second AI Agent, uploa

HTTP Request, Agent, Google Sheets +4