Regelmäßige n8n-Release Notes an Gmail senden

Experte

Dies ist ein Personal Productivity, AI Summarization-Bereich Automatisierungsworkflow mit 16 Nodes. Hauptsächlich werden Set, Code, Html, Gmail, HttpRequest und andere Nodes verwendet. KI-gestützte n8n-Veröffentlichungsnotiz-Zusammenfassung (über Gmail mit GPT-5-Mini)

Voraussetzungen
  • Google-Konto + Gmail API-Anmeldedaten
  • Möglicherweise sind Ziel-API-Anmeldedaten erforderlich
  • OpenAI API Key
Workflow-Vorschau
Visualisierung der Node-Verbindungen, mit Zoom und Pan
Workflow exportieren
Kopieren Sie die folgende JSON-Konfiguration und importieren Sie sie in n8n
{
  "id": "z301sXBDAZd8EDCw",
  "meta": {
    "instanceId": "2e134e0f94da86d43329d3d8d3284f5c8c835c03cb84be5ca46f772b2cf7a103",
    "templateCredsSetupCompleted": true
  },
  "name": "Send scheduled n8n release notes notifications to Gmail",
  "tags": [
    {
      "id": "W3G9QjFn5zCWN18M",
      "name": "Notifications",
      "createdAt": "2025-10-27T20:32:25.385Z",
      "updatedAt": "2025-10-27T20:32:25.385Z"
    },
    {
      "id": "dF0HqEuaD5GnFCI0",
      "name": "n8n",
      "createdAt": "2025-10-27T20:32:30.037Z",
      "updatedAt": "2025-10-27T20:32:30.037Z"
    },
    {
      "id": "CF6Q37w8HHllwE7l",
      "name": "gmail",
      "createdAt": "2025-10-27T20:32:34.939Z",
      "updatedAt": "2025-10-27T20:32:34.939Z"
    }
  ],
  "nodes": [
    {
      "id": "09d6bcf3-9cf2-40da-83b5-89833fe663d6",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        648,
        224
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-5-mini",
          "cachedResultName": "gpt-5-mini"
        },
        "options": {}
      },
      "typeVersion": 1.2
    },
    {
      "id": "a3e60adf-ed32-4f6b-9903-39094c5697d3",
      "name": "Structured Output Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        776,
        224
      ],
      "parameters": {
        "jsonSchemaExample": "{\n\t\"releaseBugFixes\": [\"\"],\n\t\"releaseFeatures\": [\"\"]\n}"
      },
      "typeVersion": 1.3
    },
    {
      "id": "d3d79b32-6405-405a-864a-4953f824ca6b",
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -256,
        0
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "triggerAtHour": 8
            }
          ]
        }
      },
      "executeOnce": false,
      "notesInFlow": false,
      "typeVersion": 1.2,
      "alwaysOutputData": false
    },
    {
      "id": "7a1ec69a-dc91-4365-9686-9d0b2a361736",
      "name": "HTML für Updates extrahieren",
      "type": "n8n-nodes-base.html",
      "position": [
        192,
        0
      ],
      "parameters": {
        "options": {},
        "operation": "extractHtmlContent",
        "extractionValues": {
          "values": [
            {
              "key": "sections",
              "cssSelector": "section",
              "returnArray": true,
              "returnValue": "html"
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "160368b0-4fcd-4eca-b478-4154d9aa35c9",
      "name": "Daten formatieren und nach Trigger filtern",
      "type": "n8n-nodes-base.code",
      "position": [
        416,
        0
      ],
      "parameters": {
        "jsCode": "const cheerio = require('cheerio');\n\n// Get the array of section HTML strings\nconst allSections = $input.first().json.sections;\n\n// Get schedule trigger configuration\nconst scheduleParams = $(\"Schedule Trigger\").params;\nlet checkWindowHours = 24; // Default fallback\n\n// Calculate the time window based on schedule trigger settings\nif (scheduleParams?.rule?.interval?.[0]) {\n  const interval = scheduleParams.rule.interval[0];\n  const field = interval.field;\n  \n  if (field === 'days' && interval.daysInterval) {\n    checkWindowHours = interval.daysInterval * 24;\n  } else if (field === 'hours' && interval.hoursInterval) {\n    checkWindowHours = interval.hoursInterval;\n  } else if (field === 'minutes' && interval.minutesInterval) {\n    checkWindowHours = (interval.minutesInterval / 60);\n  } else if (field === 'seconds' && interval.secondsInterval) {\n    checkWindowHours = (interval.secondsInterval / 3600);\n  } else if (field === 'weeks' && interval.weeksInterval) {\n    checkWindowHours = interval.weeksInterval * 7 * 24;\n  } else if (field === 'months' && interval.monthsInterval) {\n    checkWindowHours = interval.monthsInterval * 30 * 24;\n  }\n}\n\nconsole.log(`Using time window of ${checkWindowHours} hours based on schedule trigger`);\n\n// Get current date/time\nconst now = DateTime.now();\n\nconst results = [];\n\n// Process each section HTML string\nallSections.forEach((sectionHtml, index) => {\n  // Load this section's HTML with cheerio\n  const $ = cheerio.load(sectionHtml);\n  \n  // Get the relative time element's datetime attribute\n  const relativeTime = $('relative-time');\n  if (relativeTime.length === 0) return;\n  \n  const dateTimeAttr = relativeTime.attr('datetime');\n  if (!dateTimeAttr) return;\n  \n  // Parse the ISO datetime (format: \"2025-10-27T12:23:36Z\")\n  const releaseDateTime = DateTime.fromISO(dateTimeAttr);\n  \n  if (!releaseDateTime.isValid) {\n    console.log(`Failed to parse datetime: ${dateTimeAttr}`);\n    return;\n  }\n  \n  // Check if within the dynamic time window based on schedule trigger\n  const diffInHours = now.diff(releaseDateTime, 'hours').hours;\n  if (diffInHours > checkWindowHours || diffInHours < 0) return;\n  \n  // Extract releaseVersion from first h2\n  const firstH2 = $('h2').first();\n  const releaseVersion = firstH2.text().trim();\n  \n  // Format releaseDate\n  const releaseDate = releaseDateTime.toFormat('d MMMM, yyyy HH:mm');\n  \n  // Extract releaseLink from div.markdown-body > h2 > a\n  const markdownBody = $('div.markdown-body');\n \n  const releaseLink2 = $('div.flex-1 span.f1 a.Link--primary').attr('href') || '';\n  const releaseLink = releaseLink2 ? ('https://github.com/'+releaseLink2) :''\n  \n  // Extract bug fixes and features\n  let releaseBugFixes = [];\n  let releaseFeatures = [];\n  \n  if (markdownBody.length > 0) {\n    markdownBody.find('h3').each((i, h3Element) => {\n      const h3 = $(h3Element);\n      const h3Text = h3.text().trim();\n      \n      // Find Bug Fixes\n      if (h3Text === 'Bug Fixes' || h3Text.includes('Bug Fix')) {\n        let nextEl = h3.next();\n        // Look for next ul, but stop at next heading\n        while (nextEl.length > 0 && !nextEl.is('ul')) {\n          if (nextEl.is('h2, h3')) break;\n          nextEl = nextEl.next();\n        }\n        if (nextEl.is('ul')) {\n          nextEl.find('li').each((j, li) => {\n            releaseBugFixes.push($(li).text().trim());\n          });\n        }\n      }\n      \n      // Find Features\n      if (h3Text === 'Features' || h3Text.includes('Feature')) {\n        let nextEl = h3.next();\n        // Look for next ul, but stop at next heading\n        while (nextEl.length > 0 && !nextEl.is('ul')) {\n          if (nextEl.is('h2, h3')) break;\n          nextEl = nextEl.next();\n        }\n        if (nextEl.is('ul')) {\n          nextEl.find('li').each((j, li) => {\n            releaseFeatures.push($(li).text().trim());\n          });\n        }\n      }\n    });\n  }\n  \n  results.push({\n    releaseVersion,\n    releaseDate,\n    releaseLink,\n    releaseBugFixes,\n    releaseFeatures\n  });\n});\n\n// Return results in n8n format\nreturn results.map(item => ({ json: item }));"
      },
      "typeVersion": 2
    },
    {
      "id": "d60758f6-313d-4d95-a5a4-6f22df51f4d0",
      "name": "Daten formatieren",
      "type": "n8n-nodes-base.set",
      "position": [
        992,
        0
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "38260412-2d4d-4f9e-ab33-1839ea1e5b6a",
              "name": "releaseVersion",
              "type": "string",
              "value": "={{ $('Format Data and Filter based on Trigger').item.json.releaseVersion }}"
            },
            {
              "id": "601016bd-9724-4608-bd41-cd4127c21268",
              "name": "releaseDate",
              "type": "string",
              "value": "={{ $('Format Data and Filter based on Trigger').item.json.releaseDate }}"
            },
            {
              "id": "70fdeddb-fd07-439c-8ec8-a2b7b9bfc1d4",
              "name": "releaseLink",
              "type": "string",
              "value": "={{ $('Format Data and Filter based on Trigger').item.json.releaseLink }}"
            },
            {
              "id": "dda79d93-e36a-40b2-9874-5564f6d4336f",
              "name": "output.releaseFeatures",
              "type": "array",
              "value": "={{ $json.output.releaseFeatures }}"
            },
            {
              "id": "ae95cbf9-531e-4a3b-8d59-cb5162209d03",
              "name": "output.releaseBugFixes",
              "type": "array",
              "value": "={{ $json.output.releaseBugFixes }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "796aa3f1-6f22-4583-b6cc-ace9616c3fe1",
      "name": "HTML-Vorlage generieren",
      "type": "n8n-nodes-base.code",
      "position": [
        1216,
        0
      ],
      "parameters": {
        "jsCode": "// Get the input data\nconst items = $input.all();\n\n// Start building the HTML\nlet html = `\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>n8n Daily Update</title>\n    <style>\n        body {\n            font-family: Arial, sans-serif;\n            line-height: 1.6;\n            color: #333;\n            max-width: 800px;\n            margin: 0 auto;\n            padding: 20px;\n            background-color: #f4f4f4;\n        }\n        .container {\n            background-color: #ffffff;\n            border-radius: 8px;\n            padding: 30px;\n            box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n        }\n        .header {\n            text-align: center;\n            border-bottom: 3px solid #d62854;\n            padding-bottom: 20px;\n            margin-bottom: 30px;\n        }\n        .header h1 {\n            color: #d62854;\n            margin: 0;\n            font-size: 28px;\n        }\n        .header p {\n            color: #666;\n            margin: 10px 0 0 0;\n        }\n        .release {\n            margin-bottom: 40px;\n            border-left: 4px solid #d62854;\n            padding-left: 20px;\n        }\n        .release-header {\n            margin-bottom: 15px;\n        }\n        .release-version {\n            font-size: 22px;\n            font-weight: bold;\n            color: #333;\n            margin: 0 0 5px 0;\n        }\n        .release-date {\n            color: #666;\n            font-size: 14px;\n            margin: 0 0 10px 0;\n        }\n        .release-link {\n            display: inline-block;\n            color: #d62854;\n            text-decoration: none;\n            font-size: 14px;\n            font-weight: 500;\n        }\n        .release-link:hover {\n            text-decoration: underline;\n        }\n        .section {\n            margin-top: 20px;\n        }\n        .section-title {\n            font-size: 16px;\n            font-weight: bold;\n            color: #d62854;\n            margin-bottom: 10px;\n            text-transform: uppercase;\n            letter-spacing: 0.5px;\n        }\n        .items-list {\n            margin: 0;\n            padding-left: 20px;\n        }\n        .items-list li {\n            margin-bottom: 10px;\n            color: #555;\n        }\n        .no-items {\n            color: #999;\n            font-style: italic;\n        }\n        .footer {\n            text-align: center;\n            margin-top: 40px;\n            padding-top: 20px;\n            border-top: 1px solid #ddd;\n            color: #666;\n            font-size: 12px;\n        }\n    </style>\n</head>\n<body>\n    <div class=\"container\">\n        <div class=\"header\">\n            <h1>🚀 n8n Updates</h1>\n            <p>Latest releases, features, and bug fixes</p>\n        </div>\n`;\n\n// Loop through each release\nitems.forEach((item) => {\n    const data = item.json;\n    const version = data.releaseVersion || 'Unknown Version';\n    const date = data.releaseDate || 'Unknown Date';\n    const link = data.releaseLink || '#';\n    const features = data.output?.releaseFeatures || [];\n    const bugFixes = data.output?.releaseBugFixes || [];\n\n    html += `\n        <div class=\"release\">\n            <div class=\"release-header\">\n                <h2 class=\"release-version\">${version}</h2>\n                <p class=\"release-date\">📅 ${date}</p>\n                <a href=\"${link}\" class=\"release-link\" target=\"_blank\">View on GitHub →</a>\n            </div>\n    `;\n\n    // Add Features section\n    html += `<div class=\"section\"><div class=\"section-title\">🎉 New Features</div>`;\n    \n    if (features.length > 0) {\n        html += `<ul class=\"items-list\">`;\n        features.forEach(feature => {\n            html += `<li>${feature}</li>`;\n        });\n        html += `</ul>`;\n    } else {\n        html += `<p class=\"no-items\">No new features in this release</p>`;\n    }\n    html += `</div>`;\n\n    // Add Bug Fixes section\n    html += `<div class=\"section\"><div class=\"section-title\">🔧 Bug Fixes</div>`;\n    \n    if (bugFixes.length > 0) {\n        html += `<ul class=\"items-list\">`;\n        bugFixes.forEach(fix => {\n            html += `<li>${fix}</li>`;\n        });\n        html += `</ul>`;\n    } else {\n        html += `<p class=\"no-items\">No bug fixes in this release</p>`;\n    }\n    html += `</div></div>`;\n});\n\n// Return the HTML\nreturn [{ json: { html } }];"
      },
      "typeVersion": 2
    },
    {
      "id": "4d8a12ea-5ae3-4e4a-9e93-df5dc53cdb06",
      "name": "n8n Update-Daten zusammenfassen",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        640,
        0
      ],
      "parameters": {
        "text": "=Give me a summary of the Release Bug Fixes and Release Features as a list of important releases. Include only the important ones, and summarize as much as possible. Use simple language.\n\n{releaseBugFixes: {{ $json.releaseBugFixes }},\nreleaseFeatures: {{ $json.releaseFeatures }}\n} ",
        "options": {
          "maxIterations": 3
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 3
    },
    {
      "id": "12e67c90-bc13-458d-a45b-14ab5881d31c",
      "name": "Kurznotiz",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -688,
        -352
      ],
      "parameters": {
        "width": 368,
        "height": 528,
        "content": "## n8n Release Notifications Workflow\n\n**Stay updated with the latest n8n releases automatically!**\n\n## What this workflow does:\n- Runs on a schedule (configurable)\n- Fetches latest release notes from n8n GitHub\n- Uses AI to summarize key features and bug fixes\n- Sends formatted email notifications via Gmail\n\n## Setup required:\n1. **Schedule Trigger** - Adjust frequency if needed\n2. **OpenAI credentials** - Add your API key or connect different LLM\n3. **Gmail credentials** - Connect your Google account\n4. **Recipient email** - Set the \"To\" address in the Gmail node"
      },
      "typeVersion": 1
    },
    {
      "id": "be26a459-0049-46a8-b4a7-4efd9549a30c",
      "name": "Kurznotiz1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -296,
        -128
      ],
      "parameters": {
        "color": 7,
        "width": 176,
        "height": 304,
        "content": "### 1. Schedule Trigger\n\nSet your preferred frequency."
      },
      "typeVersion": 1
    },
    {
      "id": "1baae255-a154-46bd-af66-fdaed8ad6d95",
      "name": "Kurznotiz2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -88,
        -224
      ],
      "parameters": {
        "color": 7,
        "width": 656,
        "height": 400,
        "content": "### 2. Get n8n release notes and filter\n\n- Get all release notes\n- Filters releases based on timeframe\n- Formats data\n\nNo configuration needed - it's automatic!"
      },
      "typeVersion": 1
    },
    {
      "id": "9f097a51-1167-4c61-a17d-8c574140c0bd",
      "name": "n8n Veröffentlichungshinweise abrufen",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -32,
        0
      ],
      "parameters": {
        "url": "https://github.com/n8n-io/n8n/releases",
        "options": {}
      },
      "typeVersion": 4.2
    },
    {
      "id": "a9dcc608-56f9-4e94-ab8a-2401c1675484",
      "name": "Kurznotiz3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        608,
        -272
      ],
      "parameters": {
        "color": 7,
        "width": 288,
        "height": 640,
        "content": "### AI Summarization\n\nOpenAI analyzes release notes and extracts:\n-  Important bug fixes\n-  New features\n\n**⚠️Setup Required:**\nAdd your OpenAI API credentials here or connect a different LLM provider."
      },
      "typeVersion": 1
    },
    {
      "id": "7d414dfc-9171-4bf2-9e79-64f9e52b637e",
      "name": "Kurznotiz4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        960,
        -144
      ],
      "parameters": {
        "color": 7,
        "width": 384,
        "height": 304,
        "content": "### Format for Email\n\nBuild an HTML template for email."
      },
      "typeVersion": 1
    },
    {
      "id": "f1260b97-38b0-4791-baa4-08a4a4aad868",
      "name": "Kurznotiz5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1392,
        -224
      ],
      "parameters": {
        "color": 7,
        "height": 384,
        "content": "### Send Email\n\nSend via Gmail.\n\n**⚠️ Setup Required:**\n1. Add Gmail credentials\n2. Set recipient email address in the \"To\" field"
      },
      "typeVersion": 1
    },
    {
      "id": "fafd7a5e-0e9a-49ec-b097-6019d068c1cd",
      "name": "Nachricht senden",
      "type": "n8n-nodes-base.gmail",
      "position": [
        1456,
        0
      ],
      "webhookId": "405dc9ef-79d6-493a-963f-08ecead7bd06",
      "parameters": {
        "message": "={{ $json.html }}",
        "options": {
          "appendAttribution": false
        },
        "subject": "=n8n Updates -  {{ $now.format('DDD') }}"
      },
      "typeVersion": 2.1
    }
  ],
  "active": false,
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "0f73b185-10b8-4ab7-87a8-c441fd924d13",
  "connections": {
    "d60758f6-313d-4d95-a5a4-6f22df51f4d0": {
      "main": [
        [
          {
            "node": "796aa3f1-6f22-4583-b6cc-ace9616c3fe1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "d3d79b32-6405-405a-864a-4953f824ca6b": {
      "main": [
        [
          {
            "node": "9f097a51-1167-4c61-a17d-8c574140c0bd",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "09d6bcf3-9cf2-40da-83b5-89833fe663d6": {
      "ai_languageModel": [
        [
          {
            "node": "4d8a12ea-5ae3-4e4a-9e93-df5dc53cdb06",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "9f097a51-1167-4c61-a17d-8c574140c0bd": {
      "main": [
        [
          {
            "node": "7a1ec69a-dc91-4365-9686-9d0b2a361736",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "796aa3f1-6f22-4583-b6cc-ace9616c3fe1": {
      "main": [
        [
          {
            "node": "fafd7a5e-0e9a-49ec-b097-6019d068c1cd",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "7a1ec69a-dc91-4365-9686-9d0b2a361736": {
      "main": [
        [
          {
            "node": "160368b0-4fcd-4eca-b478-4154d9aa35c9",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "a3e60adf-ed32-4f6b-9903-39094c5697d3": {
      "ai_outputParser": [
        [
          {
            "node": "4d8a12ea-5ae3-4e4a-9e93-df5dc53cdb06",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "4d8a12ea-5ae3-4e4a-9e93-df5dc53cdb06": {
      "main": [
        [
          {
            "node": "d60758f6-313d-4d95-a5a4-6f22df51f4d0",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "160368b0-4fcd-4eca-b478-4154d9aa35c9": {
      "main": [
        [
          {
            "node": "4d8a12ea-5ae3-4e4a-9e93-df5dc53cdb06",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Häufig gestellte Fragen

Wie verwende ich diesen Workflow?

Kopieren Sie den obigen JSON-Code, erstellen Sie einen neuen Workflow in Ihrer n8n-Instanz und wählen Sie "Aus JSON importieren". Fügen Sie die Konfiguration ein und passen Sie die Anmeldedaten nach Bedarf an.

Für welche Szenarien ist dieser Workflow geeignet?

Experte - Persönliche Produktivität, KI-Zusammenfassung

Ist es kostenpflichtig?

Dieser Workflow ist völlig kostenlos. Beachten Sie jedoch, dass Drittanbieterdienste (wie OpenAI API), die im Workflow verwendet werden, möglicherweise kostenpflichtig sind.

Workflow-Informationen
Schwierigkeitsgrad
Experte
Anzahl der Nodes16
Kategorie2
Node-Typen10
Schwierigkeitsbeschreibung

Für fortgeschrittene Benutzer, komplexe Workflows mit 16+ Nodes

Externe Links
Auf n8n.io ansehen

Diesen Workflow teilen

Kategorien

Kategorien: 34