Sicherheits- und Datenschutz-Konformitäts-Feed-Intelligentes Zusammenfassung

Experte

Dies ist ein AI, SecOps-Bereich Automatisierungsworkflow mit 43 Nodes. Hauptsächlich werden Set, Code, Sort, Gmail, Filter und andere Nodes verwendet, kombiniert mit KI-Technologie für intelligente Automatisierung. Intelligente KI-Zusammenfassung für sicherheits-, datenschutz- und compliancebezogene Quellen

Voraussetzungen
  • Google-Konto + Gmail API-Anmeldedaten
  • Google Gemini 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": "dXrHZjJdzpNh79lJ",
  "meta": {
    "instanceId": "c62c01f3e843893075a10f252ec7d6d69e5ab593af019f50055d506cb3081b99"
  },
  "name": "Intelligent AI Digest for Security, Privacy, and Compliance Feeds",
  "tags": [
    {
      "id": "bteUZZnDWPlLufzn",
      "name": "prod",
      "createdAt": "2025-04-18T15:09:08.645Z",
      "updatedAt": "2025-04-18T15:09:08.645Z"
    },
    {
      "id": "MbPHhZHgb39Syuoa",
      "name": "security",
      "createdAt": "2025-04-20T05:18:20.689Z",
      "updatedAt": "2025-04-20T05:18:20.689Z"
    },
    {
      "id": "TzfZgDmxmc5R1gyA",
      "name": "ai",
      "createdAt": "2025-04-27T14:57:46.973Z",
      "updatedAt": "2025-04-27T14:57:46.973Z"
    }
  ],
  "nodes": [
    {
      "id": "828bdcf3-09a4-4235-8dbb-2153f0928037",
      "name": "KI-Agent - Datenschutz-Intelligenz",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        -740,
        4180
      ],
      "parameters": {
        "text": "={{ $json.subject }}\n{{ $json.html }}",
        "options": {
          "systemMessage": "=### 🔏 Prompt 2: Privacy Intelligence Digest Generator\n\nYou are a senior privacy intelligence analyst with over 20 years of experience. Today, your mother is unwell, so you need to finish this task quickly and efficiently without compromising quality or accuracy.\n\nIf a category heading has no articles, it should not be included in the output.\n\n#### **Tasks:**\n\n1. Parse the HTML and extract articles.\n2. Remove duplicates.\n3. Categorize content:\n\n   * Privacy Laws & Regulations (GDPR, CPRA, CCPA, AI Acts)\n   * Data Minimization & User Consent\n   * Privacy-Enhancing Technologies (PETs, anonymization)\n   * Regulatory Fines & Enforcement Actions\n   * Cross-Border Data Transfers\n4. Summarize each article in under 2 lines.\n5. Dynamically identify and list critical privacy alerts. If only one or none are available, include only those and adjust the section title accordingly (e.g., 'Critical Privacy Alert').\n6. Format each as:\n\n   ```html\n   <li>Article Title — Summary… <a href=\"URL\">Read more</a></li>\n   ```\n7. Output HTML structure with headers for top 5 and each category.\n8. Add:\n\n   ```html\n   <p><em>This privacy update was compiled on [Month Day, Year].</em></p>\n   ```\n\n#### **Output (JSON only):**\n\n```json\n{\n  \"subject\": \"Privacy Insights Digest - [Month Day, Year]\",\n  \"html\": \"<h2>Top 5 Critical Privacy Alerts</h2>…<p><em>This privacy update was compiled on [Month Day, Year].</em></p>\"\n}\n```"
        },
        "promptType": "define"
      },
      "retryOnFail": true,
      "typeVersion": 1.9
    },
    {
      "id": "7be7a9fe-e8f5-4a56-a77d-7ca098d52479",
      "name": "KI-Agent - Sicherheits-Intelligenz",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        -720,
        3520
      ],
      "parameters": {
        "text": "={{ $json.subject }}\n{{ $json.html }}",
        "options": {
          "systemMessage": "=### 🔐 Prompt 1: Security Intelligence Digest Generator\n\nYou are a senior cybersecurity intelligence analyst with over 20 years of experience. Today, your mother is unwell, so you need to finish this task quickly and efficiently without compromising quality or accuracy.\n\n#### **Inputs:**\n\n* Raw newsletter subject: `{{ $json.subject }}`\n* Raw newsletter HTML body: `{{ $json.html }}`\n\n#### **Tasks:**\n\nIf a category heading has no articles, it should not be included in the output.\n\n1. Parse the provided HTML.\n2. Remove duplicate articles based on title, summary, or URL.\n3. Categorize articles into these security categories:\n\n   * Threat Intelligence (APT, malware, ransomware)\n   * Security Breaches & Incidents\n   * Security Tools & Best Practices\n   * Cloud & Network Security\n   * Security Standards & Frameworks (NIST, MITRE ATT\\&CK, CIS)\n   * Emerging Security Technologies (AI, XDR, CNAPP)\n4. Summarize each article in 1–2 lines.\n5. Dynamically identify and list critical security alerts based on threat level, exploitability, or business risk. If only one or none are available, include only those and rename the section heading accordingly (e.g., 'Critical Security Alert').\n6. Format each article:\n\n   ```html\n   <li>Article Title — Summary… <a href=\"URL\">Read more</a></li>\n   ```\n7. Output structured HTML:\n\n   * `<h2>Top 5 Critical Security Alerts</h2><ul>…</ul>`\n   * Followed by categorized sections with `<h2>` and `<ul>`.\n8. Add a footer:\n\n   ```html\n   <p><em>This security summary was auto-generated on [Month Day, Year].</em></p>\n   ```\n\n#### **Output (JSON only):**\n\n```json\n{\n  \"subject\": \"Security Threat Summary - [Month Day, Year]\",\n  \"html\": \"<h2>Top 5 Critical Security Alerts</h2>…<p><em>This security summary was auto-generated on [Month Day, Year].</em></p>\"\n}\n```"
        },
        "promptType": "define"
      },
      "retryOnFail": true,
      "typeVersion": 1.9
    },
    {
      "id": "bb59ecfa-b197-47c4-a32e-0834c187100e",
      "name": "KI-Agent - Compliance-Intelligenz",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        -740,
        4840
      ],
      "parameters": {
        "text": "={{ $json.subject }}\n{{ $json.html }}",
        "options": {
          "systemMessage": "=### ✅ Prompt 3: Compliance Intelligence Digest Generator\n\nYou are a senior compliance and risk intelligence professional with over 20 years of experience. Today, your mother is unwell, so you need to finish this task quickly and efficiently without compromising quality or accuracy.\n\n#### **Inputs:**\n\n* Raw newsletter subject: `{{ $json.subject }}`\n* Raw newsletter HTML body: `{{ $json.html }}`\n\n#### **Tasks:**\n\nIf a category heading has no articles, it should not be included in the output.\n\n1. Parse the HTML and extract article data.\n2. De-duplicate articles.\n3. Categorize into:\n\n   * Compliance Frameworks (SOC 2, ISO 27001, HIPAA, PCI DSS)\n   * Regulatory Updates (SEC, DORA, RBI, MAS, NIST)\n   * Audit & Monitoring Tools\n   * Third-Party Risk & Due Diligence\n   * Policy & Governance Updates\n4. Summarize each item concisely.\n5. Dynamically identify and list critical compliance alerts. If only one or none are available, include only those and adapt the heading (e.g., 'Critical Compliance Alert').\n6. Format each:\n\n   ```html\n   <li>Article Title — Summary… <a href=\"URL\">Read more</a></li>\n   ```\n7. Output HTML with top 5 and categorized sections.\n8. Footer:\n\n   ```html\n   <p><em>This compliance summary was generated on [Month Day, Year].</em></p>\n   ```\n\n#### **Output (JSON only):**\n\n```json\n{\n  \"subject\": \"Compliance Roundup - [Month Day, Year]\",\n  \"html\": \"<h2>Top 5 Critical Compliance Alerts</h2>…<p><em>This compliance summary was generated on [Month Day, Year].</em></p>\"\n}\n```"
        },
        "promptType": "define"
      },
      "retryOnFail": true,
      "typeVersion": 1.9
    },
    {
      "id": "328bb06a-edfd-4a14-9011-68cdd00bcd8e",
      "name": "Tägliche Zusammenfassung auslösen",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -3040,
        4280
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "triggerAtHour": 1,
              "triggerAtMinute": 35
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "351774d8-7adc-4041-8639-bc35f9c37183",
      "name": "Datenschutz-Feeds abrufen",
      "type": "n8n-nodes-base.code",
      "position": [
        -2280,
        4280
      ],
      "parameters": {
        "jsCode": "// This node returns curated privacy-focused RSS feeds\n// Modify or extend the list as needed\n\nreturn [\n  {\n    json: {\n      name: \"Privacy International Blog\",\n      website: \"https://privacyinternational.org\",\n      rss_url: \"https://privacyinternational.org/rss.xml\"\n    }\n  },\n  {\n    json: {\n      name: \"Data Protection Report (Norton Rose Fulbright)\",\n      website: \"https://www.dataprotectionreport.com\",\n      rss_url: \"https://www.dataprotectionreport.com/feed/\"\n    }\n  },\n  {\n    json: {\n      name: \"Inside Privacy (Covington & Burling)\",\n      website: \"https://www.insideprivacy.com\",\n      rss_url: \"https://www.insideprivacy.com/feed/\"\n    }\n  },\n  {\n    json: {\n      name: \"PogoWasRight\",\n      website: \"https://pogowasright.org\",\n      rss_url: \"https://pogowasright.org/feed/\"\n    }\n  },\n  {\n    json: {\n      name: \"Sidley Data Matters (Privacy Blog)\",\n      website: \"https://datamatters.sidley.com\",\n      rss_url: \"https://datamatters.sidley.com/feed/\"\n    }\n  }\n];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "d0a93584-a1bc-4da8-9aaf-129adf7e4cae",
      "name": "Compliance-Feeds abrufen",
      "type": "n8n-nodes-base.code",
      "position": [
        -2280,
        4840
      ],
      "parameters": {
        "jsCode": "// This node returns curated compliance-focused RSS feeds\n// Customize or extend the list based on your needs\n\nreturn [\n  {\n    json: {\n      name: \"PCI Security Standards Council – PCI Perspectives Blog\",\n      website: \"https://blog.pcisecuritystandards.org\",\n      rss_url: \"https://blog.pcisecuritystandards.org/rss.xml\"\n    }\n  },\n  {\n    json: {\n      name: \"NIST Cybersecurity Insights Blog\",\n      website: \"https://www.nist.gov/blogs/cybersecurity-insights\",\n      rss_url: \"https://www.nist.gov/blogs/cybersecurity-insights/rss.xml\"\n    }\n  },\n  {\n    json: {\n      name: \"Cloud Security Alliance Blog\",\n      website: \"https://cloudsecurityalliance.org/blog\",\n      rss_url: \"https://cloudsecurityalliance.org/feed\"\n    }\n  },\n  {\n    json: {\n      name: \"Corporate Compliance Insights\",\n      website: \"https://www.corporatecomplianceinsights.com\",\n      rss_url: \"http://feeds.feedburner.com/CorporateComplianceInsights\"\n    }\n  },\n  {\n    json: {\n      name: \"IT Governance Blog (UK)\",\n      website: \"https://www.itgovernance.co.uk/blog\",\n      rss_url: \"https://www.itgovernance.co.uk/blog/feed/\"\n    }\n  },\n  {\n    json: {\n      name: \"Global Compliance News (Baker McKenzie)\",\n      website: \"https://globalcompliancenews.com\",\n      rss_url: \"https://globalcompliancenews.com/feed/\"\n    }\n  }\n];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "e4fa0e00-d10b-4c86-bad3-6c0d1d59750a",
      "name": "Sicherheits-Metadaten der Artikel normalisieren",
      "type": "n8n-nodes-base.set",
      "position": [
        -1600,
        3620
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "9aec0a09-4b6f-4fca-98e6-789abd5fdc51",
              "name": "title",
              "type": "string",
              "value": "={{ $json.title }}"
            },
            {
              "id": "56277e54-31a0-4804-ad23-c9ee6d244641",
              "name": "content",
              "type": "string",
              "value": "={{ $json.contentSnippet }}"
            },
            {
              "id": "a3586a80-588e-42d1-9780-370a956ddf6b",
              "name": "link",
              "type": "string",
              "value": "={{ $json.link }}"
            },
            {
              "id": "58f01618-8014-4685-9192-d15d596ffcd9",
              "name": "isoDate",
              "type": "number",
              "value": "={{ new Date($json.isoDate).getTime() }}"
            },
            {
              "id": "716bb078-8df3-4d96-8a1b-4aec4f8cf206",
              "name": "categories",
              "type": "array",
              "value": "={{ $json.categories }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "c1f6e2ac-4bf9-4fc4-85fd-c8c7649cdc9c",
      "name": "Datenschutz-Metadaten der Artikel normalisieren",
      "type": "n8n-nodes-base.set",
      "position": [
        -1620,
        4280
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "9aec0a09-4b6f-4fca-98e6-789abd5fdc51",
              "name": "title",
              "type": "string",
              "value": "={{ $json.title }}"
            },
            {
              "id": "56277e54-31a0-4804-ad23-c9ee6d244641",
              "name": "content",
              "type": "string",
              "value": "={{ $json.contentSnippet }}"
            },
            {
              "id": "a3586a80-588e-42d1-9780-370a956ddf6b",
              "name": "link",
              "type": "string",
              "value": "={{ $json.link }}"
            },
            {
              "id": "58f01618-8014-4685-9192-d15d596ffcd9",
              "name": "isoDate",
              "type": "number",
              "value": "={{ new Date($json.isoDate).getTime() }}"
            },
            {
              "id": "716bb078-8df3-4d96-8a1b-4aec4f8cf206",
              "name": "categories",
              "type": "array",
              "value": "={{ $json.categories }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "ae374184-806b-4022-80b5-94bdef48133e",
      "name": "Compliance-Metadaten der Artikel normalisieren",
      "type": "n8n-nodes-base.set",
      "position": [
        -1620,
        4840
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "9aec0a09-4b6f-4fca-98e6-789abd5fdc51",
              "name": "title",
              "type": "string",
              "value": "={{ $json.title }}"
            },
            {
              "id": "56277e54-31a0-4804-ad23-c9ee6d244641",
              "name": "content",
              "type": "string",
              "value": "={{ $json.contentSnippet }}"
            },
            {
              "id": "a3586a80-588e-42d1-9780-370a956ddf6b",
              "name": "link",
              "type": "string",
              "value": "={{ $json.link }}"
            },
            {
              "id": "58f01618-8014-4685-9192-d15d596ffcd9",
              "name": "isoDate",
              "type": "number",
              "value": "={{ new Date($json.isoDate).getTime() }}"
            },
            {
              "id": "716bb078-8df3-4d96-8a1b-4aec4f8cf206",
              "name": "categories",
              "type": "array",
              "value": "={{ $json.categories }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "e71e3c7e-a58a-49bb-9c13-827f46e4df7e",
      "name": "Aktuelle Sicherheitsartikel filtern (24h)",
      "type": "n8n-nodes-base.filter",
      "position": [
        -1380,
        3620
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "e7cf09fb-af35-495d-a840-341f8d0ddcd8",
              "operator": {
                "type": "number",
                "operation": "gt"
              },
              "leftValue": "={{ $json.isoDate }}",
              "rightValue": "={{ Date.now() - 24 * 60 * 60 * 1000 }}"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "cb34ed8e-5b67-4cfd-8731-482b22874780",
      "name": "Aktuelle Datenschutzartikel filtern (24h)",
      "type": "n8n-nodes-base.filter",
      "position": [
        -1400,
        4280
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "e7cf09fb-af35-495d-a840-341f8d0ddcd8",
              "operator": {
                "type": "number",
                "operation": "gt"
              },
              "leftValue": "={{ $json.isoDate }}",
              "rightValue": "={{ Date.now() - 24 * 60 * 60 * 1000 }}"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "07c94d37-ad0a-4f89-961c-abf1d6eeeeef",
      "name": "Aktuelle Compliance-Artikel filtern (24h)",
      "type": "n8n-nodes-base.filter",
      "position": [
        -1400,
        4840
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "e7cf09fb-af35-495d-a840-341f8d0ddcd8",
              "operator": {
                "type": "number",
                "operation": "gt"
              },
              "leftValue": "={{ $json.isoDate }}",
              "rightValue": "={{ Date.now() - 24 * 60 * 60 * 1000 }}"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "9cb809e9-4d49-452e-823e-3f54adca0529",
      "name": "Sicherheitsartikel in HTML formatieren",
      "type": "n8n-nodes-base.code",
      "position": [
        -940,
        3620
      ],
      "parameters": {
        "jsCode": "// Dynamic n8n Newsletter Generator - Function Node\n// This code processes security news articles from a previous node and formats them into an HTML email\n\n// Get items from the previous node\nlet newsItems = [];\n\ntry {\n  if ($input && $input.all().length > 0) {\n    const inputItems = $input.all();\n    if (inputItems.length === 1 && Array.isArray(inputItems[0].json)) {\n      newsItems = inputItems[0].json;\n    } else {\n      newsItems = inputItems.map(item => item.json);\n    }\n  } else if (typeof items !== 'undefined' && items.length > 0) {\n    if (items.length === 1 && Array.isArray(items[0].json)) {\n      newsItems = items[0].json;\n    } else {\n      newsItems = items.map(item => item.json);\n    }\n  }\n  console.log(`Successfully processed input, found ${newsItems.length} news items`);\n} catch (error) {\n  console.log(`Error processing input: ${error.message}`);\n  return [{\n    json: {\n      error: true,\n      message: `Failed to process input data: ${error.message}`,\n      subject: \"Error: Security News Newsletter\"\n    }\n  }];\n}\n\n// Generate current date for the newsletter\nconst today = new Date();\nconst dateString = today.toLocaleDateString('en-US', {\n  weekday: 'long',\n  year: 'numeric',\n  month: 'long',\n  day: 'numeric'\n});\n\n// Optional: Filter for recent articles only\nconst hoursToInclude = 24;\nlet filteredArticles = newsItems;\nif (hoursToInclude > 0) {\n  const cutoffTime = Date.now() - (hoursToInclude * 60 * 60 * 1000);\n  filteredArticles = newsItems.filter(article => {\n    const articleDate = article.isoDate\n      ? (typeof article.isoDate === 'number'\n         ? article.isoDate\n         : new Date(article.isoDate).getTime())\n      : 0;\n    return articleDate >= cutoffTime;\n  });\n  console.log(`Filtered to ${filteredArticles.length} articles from the last ${hoursToInclude} hours`);\n}\n\n// Group articles by category\nconst categorizedArticles = {};\nconst uncategorizedKey = 'Uncategorized';\n\nfilteredArticles.forEach(article => {\n  if (!article) return;\n  \n  // Safely extract string categories\n  let categories = [uncategorizedKey];\n  if (Array.isArray(article.categories)) {\n    categories = article.categories\n      .map(cat => {\n        if (typeof cat === 'string') return cat;\n        if (cat && typeof cat.name === 'string') return cat.name;\n        return '';\n      })\n      .map(str => str.trim())\n      .filter(str => str.length > 0);\n    if (categories.length === 0) categories = [uncategorizedKey];\n  } else if (typeof article.categories === 'string' && article.categories.trim()) {\n    categories = [article.categories.trim()];\n  }\n\n  categories.forEach(category => {\n    const name = category || uncategorizedKey;\n    if (!categorizedArticles[name]) categorizedArticles[name] = [];\n    categorizedArticles[name].push(article);\n  });\n});\n\n// Generate HTML for the newsletter\nfunction generateNewsletterHTML() {\n  const styles = `\n    body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; max-width: 800px; margin: 0 auto; padding: 20px; }\n    h1 { color: #2c3e50; border-bottom: 2px solid #e74c3c; padding-bottom: 10px; }\n    h2 { color: #c0392b; margin-top: 30px; border-left: 4px solid #e74c3c; padding-left: 10px; }\n    .article { margin-bottom: 20px; padding: 15px; background-color: #f9f9f9; border-radius: 5px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }\n    .article h3 { margin-top: 0; color: #34495e; }\n    .article-content { color: #555; margin-bottom: 10px; }\n    .article-link { color: #e74c3c; text-decoration: none; font-weight: bold; }\n    .article-link:hover { text-decoration: underline; }\n    .article-date { color: #7f8c8d; font-size: 0.9em; margin-top: 8px; }\n    .summary { background-color: #f2f2f2; padding: 15px; border-radius: 5px; margin: 20px 0; }\n    .footer { margin-top: 40px; padding-top: 20px; border-top: 1px solid #ddd; font-size: 0.9em; color: #7f8c8d; text-align: center; }\n  `;\n\n  let html = `\n    <!DOCTYPE html>\n    <html>\n    <head>\n      <meta charset=\"UTF-8\">\n      <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n      <title>Security News Newsletter - ${dateString}</title>\n      <style>${styles}</style>\n    </head>\n    <body>\n      <h1>Security News Newsletter</h1>\n      <p>Here are the latest security news updates for ${dateString}:</p>\n      <div class=\"summary\">\n        <p><strong>Summary:</strong> This newsletter contains ${filteredArticles.length} articles across ${Object.keys(categorizedArticles).length} categories.</p>\n      </div>\n  `;\n\n  Object.keys(categorizedArticles).sort().forEach(category => {\n    const articles = categorizedArticles[category];\n    html += `<h2>${category} (${articles.length})</h2>`;\n    articles.forEach(article => {\n      let formattedDate = \"Date unknown\";\n      if (article.isoDate) {\n        const dt = typeof article.isoDate === 'number'\n          ? new Date(article.isoDate)\n          : new Date(article.isoDate);\n        if (!isNaN(dt.getTime())) {\n          formattedDate = dt.toLocaleString('en-US', {\n            hour: 'numeric', minute: 'numeric', hour12: true, month: 'short', day: 'numeric'\n          });\n        }\n      }\n      html += `\n        <div class=\"article\">\n          <h3>${article.title || \"Untitled\"}</h3>\n          <div class=\"article-content\">${article.content || \"No content available\"}</div>\n          <a href=\"${article.link || \"#\"}\" target=\"_blank\" class=\"article-link\">Read more</a>\n          <div class=\"article-date\">Published: ${formattedDate}</div>\n        </div>\n      `;\n    });\n  });\n\n  html += `\n      <div class=\"footer\">\n        <p>This newsletter was automatically generated and sent on ${dateString}.</p>\n        <p>To unsubscribe, please click <a href=\"{{unsubscribe_link}}\">here</a>.</p>\n      </div>\n    </body>\n    </html>\n  `;\n  return html;\n}\n\nconst newsletterHTML = generateNewsletterHTML();\n\nreturn [{\n  json: {\n    subject: `Security News Newsletter - ${dateString}`,\n    html: newsletterHTML,\n    // to, cc, bcc can be set in the Email node\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "14fd5f01-075f-4648-a1ab-f0a87d2b676a",
      "name": "Datenschutzartikel in HTML formatieren",
      "type": "n8n-nodes-base.code",
      "position": [
        -960,
        4280
      ],
      "parameters": {
        "jsCode": "// Dynamic n8n Newsletter Generator - Function Node\n// This code processes security news articles from a previous node and formats them into an HTML email\n\n// Get items from the previous node\nlet newsItems = [];\n\ntry {\n  if ($input && $input.all().length > 0) {\n    const inputItems = $input.all();\n    if (inputItems.length === 1 && Array.isArray(inputItems[0].json)) {\n      newsItems = inputItems[0].json;\n    } else {\n      newsItems = inputItems.map(item => item.json);\n    }\n  } else if (typeof items !== 'undefined' && items.length > 0) {\n    if (items.length === 1 && Array.isArray(items[0].json)) {\n      newsItems = items[0].json;\n    } else {\n      newsItems = items.map(item => item.json);\n    }\n  }\n  console.log(`Successfully processed input, found ${newsItems.length} news items`);\n} catch (error) {\n  console.log(`Error processing input: ${error.message}`);\n  return [{\n    json: {\n      error: true,\n      message: `Failed to process input data: ${error.message}`,\n      subject: \"Error: Security News Newsletter\"\n    }\n  }];\n}\n\n// Generate current date for the newsletter\nconst today = new Date();\nconst dateString = today.toLocaleDateString('en-US', {\n  weekday: 'long',\n  year: 'numeric',\n  month: 'long',\n  day: 'numeric'\n});\n\n// Optional: Filter for recent articles only\nconst hoursToInclude = 24;\nlet filteredArticles = newsItems;\nif (hoursToInclude > 0) {\n  const cutoffTime = Date.now() - (hoursToInclude * 60 * 60 * 1000);\n  filteredArticles = newsItems.filter(article => {\n    const articleDate = article.isoDate\n      ? (typeof article.isoDate === 'number'\n         ? article.isoDate\n         : new Date(article.isoDate).getTime())\n      : 0;\n    return articleDate >= cutoffTime;\n  });\n  console.log(`Filtered to ${filteredArticles.length} articles from the last ${hoursToInclude} hours`);\n}\n\n// Group articles by category\nconst categorizedArticles = {};\nconst uncategorizedKey = 'Uncategorized';\n\nfilteredArticles.forEach(article => {\n  if (!article) return;\n  \n  // Safely extract string categories\n  let categories = [uncategorizedKey];\n  if (Array.isArray(article.categories)) {\n    categories = article.categories\n      .map(cat => {\n        if (typeof cat === 'string') return cat;\n        if (cat && typeof cat.name === 'string') return cat.name;\n        return '';\n      })\n      .map(str => str.trim())\n      .filter(str => str.length > 0);\n    if (categories.length === 0) categories = [uncategorizedKey];\n  } else if (typeof article.categories === 'string' && article.categories.trim()) {\n    categories = [article.categories.trim()];\n  }\n\n  categories.forEach(category => {\n    const name = category || uncategorizedKey;\n    if (!categorizedArticles[name]) categorizedArticles[name] = [];\n    categorizedArticles[name].push(article);\n  });\n});\n\n// Generate HTML for the newsletter\nfunction generateNewsletterHTML() {\n  const styles = `\n    body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; max-width: 800px; margin: 0 auto; padding: 20px; }\n    h1 { color: #2c3e50; border-bottom: 2px solid #e74c3c; padding-bottom: 10px; }\n    h2 { color: #c0392b; margin-top: 30px; border-left: 4px solid #e74c3c; padding-left: 10px; }\n    .article { margin-bottom: 20px; padding: 15px; background-color: #f9f9f9; border-radius: 5px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }\n    .article h3 { margin-top: 0; color: #34495e; }\n    .article-content { color: #555; margin-bottom: 10px; }\n    .article-link { color: #e74c3c; text-decoration: none; font-weight: bold; }\n    .article-link:hover { text-decoration: underline; }\n    .article-date { color: #7f8c8d; font-size: 0.9em; margin-top: 8px; }\n    .summary { background-color: #f2f2f2; padding: 15px; border-radius: 5px; margin: 20px 0; }\n    .footer { margin-top: 40px; padding-top: 20px; border-top: 1px solid #ddd; font-size: 0.9em; color: #7f8c8d; text-align: center; }\n  `;\n\n  let html = `\n    <!DOCTYPE html>\n    <html>\n    <head>\n      <meta charset=\"UTF-8\">\n      <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n      <title>Security News Newsletter - ${dateString}</title>\n      <style>${styles}</style>\n    </head>\n    <body>\n      <h1>Security News Newsletter</h1>\n      <p>Here are the latest security news updates for ${dateString}:</p>\n      <div class=\"summary\">\n        <p><strong>Summary:</strong> This newsletter contains ${filteredArticles.length} articles across ${Object.keys(categorizedArticles).length} categories.</p>\n      </div>\n  `;\n\n  Object.keys(categorizedArticles).sort().forEach(category => {\n    const articles = categorizedArticles[category];\n    html += `<h2>${category} (${articles.length})</h2>`;\n    articles.forEach(article => {\n      let formattedDate = \"Date unknown\";\n      if (article.isoDate) {\n        const dt = typeof article.isoDate === 'number'\n          ? new Date(article.isoDate)\n          : new Date(article.isoDate);\n        if (!isNaN(dt.getTime())) {\n          formattedDate = dt.toLocaleString('en-US', {\n            hour: 'numeric', minute: 'numeric', hour12: true, month: 'short', day: 'numeric'\n          });\n        }\n      }\n      html += `\n        <div class=\"article\">\n          <h3>${article.title || \"Untitled\"}</h3>\n          <div class=\"article-content\">${article.content || \"No content available\"}</div>\n          <a href=\"${article.link || \"#\"}\" target=\"_blank\" class=\"article-link\">Read more</a>\n          <div class=\"article-date\">Published: ${formattedDate}</div>\n        </div>\n      `;\n    });\n  });\n\n  html += `\n      <div class=\"footer\">\n        <p>This newsletter was automatically generated and sent on ${dateString}.</p>\n        <p>To unsubscribe, please click <a href=\"{{unsubscribe_link}}\">here</a>.</p>\n      </div>\n    </body>\n    </html>\n  `;\n  return html;\n}\n\nconst newsletterHTML = generateNewsletterHTML();\n\nreturn [{\n  json: {\n    subject: `Security News Newsletter - ${dateString}`,\n    html: newsletterHTML,\n    // to, cc, bcc can be set in the Email node\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "6eddd44f-8038-40fd-b0db-2a8d9c35000a",
      "name": "Compliance-Artikel in HTML formatieren",
      "type": "n8n-nodes-base.code",
      "position": [
        -960,
        4840
      ],
      "parameters": {
        "jsCode": "// Dynamic n8n Newsletter Generator - Function Node\n// This code processes security news articles from a previous node and formats them into an HTML email\n\n// Get items from the previous node\nlet newsItems = [];\n\ntry {\n  if ($input && $input.all().length > 0) {\n    const inputItems = $input.all();\n    if (inputItems.length === 1 && Array.isArray(inputItems[0].json)) {\n      newsItems = inputItems[0].json;\n    } else {\n      newsItems = inputItems.map(item => item.json);\n    }\n  } else if (typeof items !== 'undefined' && items.length > 0) {\n    if (items.length === 1 && Array.isArray(items[0].json)) {\n      newsItems = items[0].json;\n    } else {\n      newsItems = items.map(item => item.json);\n    }\n  }\n  console.log(`Successfully processed input, found ${newsItems.length} news items`);\n} catch (error) {\n  console.log(`Error processing input: ${error.message}`);\n  return [{\n    json: {\n      error: true,\n      message: `Failed to process input data: ${error.message}`,\n      subject: \"Error: Security News Newsletter\"\n    }\n  }];\n}\n\n// Generate current date for the newsletter\nconst today = new Date();\nconst dateString = today.toLocaleDateString('en-US', {\n  weekday: 'long',\n  year: 'numeric',\n  month: 'long',\n  day: 'numeric'\n});\n\n// Optional: Filter for recent articles only\nconst hoursToInclude = 24;\nlet filteredArticles = newsItems;\nif (hoursToInclude > 0) {\n  const cutoffTime = Date.now() - (hoursToInclude * 60 * 60 * 1000);\n  filteredArticles = newsItems.filter(article => {\n    const articleDate = article.isoDate\n      ? (typeof article.isoDate === 'number'\n         ? article.isoDate\n         : new Date(article.isoDate).getTime())\n      : 0;\n    return articleDate >= cutoffTime;\n  });\n  console.log(`Filtered to ${filteredArticles.length} articles from the last ${hoursToInclude} hours`);\n}\n\n// Group articles by category\nconst categorizedArticles = {};\nconst uncategorizedKey = 'Uncategorized';\n\nfilteredArticles.forEach(article => {\n  if (!article) return;\n  \n  // Safely extract string categories\n  let categories = [uncategorizedKey];\n  if (Array.isArray(article.categories)) {\n    categories = article.categories\n      .map(cat => {\n        if (typeof cat === 'string') return cat;\n        if (cat && typeof cat.name === 'string') return cat.name;\n        return '';\n      })\n      .map(str => str.trim())\n      .filter(str => str.length > 0);\n    if (categories.length === 0) categories = [uncategorizedKey];\n  } else if (typeof article.categories === 'string' && article.categories.trim()) {\n    categories = [article.categories.trim()];\n  }\n\n  categories.forEach(category => {\n    const name = category || uncategorizedKey;\n    if (!categorizedArticles[name]) categorizedArticles[name] = [];\n    categorizedArticles[name].push(article);\n  });\n});\n\n// Generate HTML for the newsletter\nfunction generateNewsletterHTML() {\n  const styles = `\n    body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; max-width: 800px; margin: 0 auto; padding: 20px; }\n    h1 { color: #2c3e50; border-bottom: 2px solid #e74c3c; padding-bottom: 10px; }\n    h2 { color: #c0392b; margin-top: 30px; border-left: 4px solid #e74c3c; padding-left: 10px; }\n    .article { margin-bottom: 20px; padding: 15px; background-color: #f9f9f9; border-radius: 5px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }\n    .article h3 { margin-top: 0; color: #34495e; }\n    .article-content { color: #555; margin-bottom: 10px; }\n    .article-link { color: #e74c3c; text-decoration: none; font-weight: bold; }\n    .article-link:hover { text-decoration: underline; }\n    .article-date { color: #7f8c8d; font-size: 0.9em; margin-top: 8px; }\n    .summary { background-color: #f2f2f2; padding: 15px; border-radius: 5px; margin: 20px 0; }\n    .footer { margin-top: 40px; padding-top: 20px; border-top: 1px solid #ddd; font-size: 0.9em; color: #7f8c8d; text-align: center; }\n  `;\n\n  let html = `\n    <!DOCTYPE html>\n    <html>\n    <head>\n      <meta charset=\"UTF-8\">\n      <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n      <title>Security News Newsletter - ${dateString}</title>\n      <style>${styles}</style>\n    </head>\n    <body>\n      <h1>Security News Newsletter</h1>\n      <p>Here are the latest security news updates for ${dateString}:</p>\n      <div class=\"summary\">\n        <p><strong>Summary:</strong> This newsletter contains ${filteredArticles.length} articles across ${Object.keys(categorizedArticles).length} categories.</p>\n      </div>\n  `;\n\n  Object.keys(categorizedArticles).sort().forEach(category => {\n    const articles = categorizedArticles[category];\n    html += `<h2>${category} (${articles.length})</h2>`;\n    articles.forEach(article => {\n      let formattedDate = \"Date unknown\";\n      if (article.isoDate) {\n        const dt = typeof article.isoDate === 'number'\n          ? new Date(article.isoDate)\n          : new Date(article.isoDate);\n        if (!isNaN(dt.getTime())) {\n          formattedDate = dt.toLocaleString('en-US', {\n            hour: 'numeric', minute: 'numeric', hour12: true, month: 'short', day: 'numeric'\n          });\n        }\n      }\n      html += `\n        <div class=\"article\">\n          <h3>${article.title || \"Untitled\"}</h3>\n          <div class=\"article-content\">${article.content || \"No content available\"}</div>\n          <a href=\"${article.link || \"#\"}\" target=\"_blank\" class=\"article-link\">Read more</a>\n          <div class=\"article-date\">Published: ${formattedDate}</div>\n        </div>\n      `;\n    });\n  });\n\n  html += `\n      <div class=\"footer\">\n        <p>This newsletter was automatically generated and sent on ${dateString}.</p>\n        <p>To unsubscribe, please click <a href=\"{{unsubscribe_link}}\">here</a>.</p>\n      </div>\n    </body>\n    </html>\n  `;\n  return html;\n}\n\nconst newsletterHTML = generateNewsletterHTML();\n\nreturn [{\n  json: {\n    subject: `Security News Newsletter - ${dateString}`,\n    html: newsletterHTML,\n    // to, cc, bcc can be set in the Email node\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "1e261592-348a-42af-b4ba-1b2be82b0143",
      "name": "LLM - Gemini Security Summarizer",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        -640,
        3740
      ],
      "parameters": {
        "options": {
          "temperature": 0.5
        },
        "modelName": "models/gemini-2.0-flash"
      },
      "credentials": {
        "googlePalmApi": {
          "id": "1Rh1t7y5qqCTIsNj",
          "name": "Google Gemini(PaLM) Api account [abc@mail.com"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "c4cc7264-43af-4a26-89e2-5888817b1602",
      "name": "LLM - Gemini Privacy Summarizer",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        -660,
        4400
      ],
      "parameters": {
        "options": {
          "temperature": 0.5
        },
        "modelName": "models/gemini-2.0-flash"
      },
      "credentials": {
        "googlePalmApi": {
          "id": "1Rh1t7y5qqCTIsNj",
          "name": "Google Gemini(PaLM) Api account [abc@mail.com"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "dc4e461c-dbb8-46a1-b128-6c28584c12d4",
      "name": "LLM - Gemini Compliance Summarizer",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        -640,
        5060
      ],
      "parameters": {
        "options": {
          "temperature": 0.5
        },
        "modelName": "models/gemini-2.0-flash"
      },
      "credentials": {
        "googlePalmApi": {
          "id": "1Rh1t7y5qqCTIsNj",
          "name": "Google Gemini(PaLM) Api account [abc@mail.com"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "a1e4eaac-aaea-4859-bd29-375a6b50aaa1",
      "name": "Datenschutz: Finalen Newsletter-HTML erstellen",
      "type": "n8n-nodes-base.code",
      "position": [
        -360,
        4280
      ],
      "parameters": {
        "jsCode": "return items.map(item => {\n  // 1. grab the raw AI output\n  const raw = item.json.output;\n\n  // 2. extract what's between ```json ... ``` (or fall back to full text)\n  const match = raw.match(/```json\\s*([\\s\\S]*?)```/);\n  const jsonPayload = (match ? match[1] : raw).trim();\n\n  // 3. remove any trailing commas before } or ]\n  const clean = jsonPayload.replace(/,\\s*([\\]}])/g, '$1');\n\n  // 4. parse into an object, with error reporting\n  let data;\n  try {\n    data = JSON.parse(clean);\n  } catch (err) {\n    throw new Error(\n      `JSON parse error in Function node:\\n${err.message}\\n\\nPayload was:\\n${clean}`\n    );\n  }\n\n  // 5. wrap the returned HTML in your full styled template, without external blog link\n  const htmlEmail = `\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>${data.subject}</title>\n  <style>\n    body { font-family: Arial, sans-serif; line-height:1.5; color:#333; background-color:#f7f9fa; margin:0; padding:20px; }\n    .container { max-width:700px; margin:0 auto; background:#fff; border-radius:8px; box-shadow:0 2px 8px rgba(0,0,0,0.1); overflow:hidden; }\n    .header { background:#2c3e50; color:#fff; padding:20px; text-align:center; }\n    .header h1 { margin:0; font-size:24px; }\n    .content { padding:20px; }\n    h2 { color:#e74c3c; border-bottom:2px solid #e74c3c; padding-bottom:5px; }\n    ul { padding-left:20px; }\n    li { margin-bottom:10px; }\n    a { color:#2980b9; text-decoration:none; }\n    a:hover { text-decoration:underline; }\n    .footer { background:#ecf0f1; text-align:center; padding:10px; font-size:12px; color:#7f8c8d; }\n  </style>\n</head>\n<body>\n  <div class=\"container\">\n    <div class=\"header\">\n      <h1>${data.subject}</h1>\n    </div>\n    <div class=\"content\">\n      ${data.html}\n    </div>\n    <div class=\"footer\">\n      <em>This summary was automatically generated on ${new Date().toLocaleDateString('en-US', {\n        year: 'numeric', month: 'long', day: 'numeric'\n      })}.</em>\n    </div>\n  </div>\n</body>\n</html>\n  `.trim();\n\n  // 6. emit subject + styled html\n  return {\n    json: {\n      subject: data.subject,\n      html: htmlEmail,\n    }\n  };\n});"
      },
      "typeVersion": 2
    },
    {
      "id": "7a864b0c-08f5-4e97-8430-1879f8e0e3d0",
      "name": "Sicherheit: Finalen Newsletter-HTML erstellen",
      "type": "n8n-nodes-base.code",
      "position": [
        -340,
        3620
      ],
      "parameters": {
        "jsCode": "return items.map(item => {\n  // 1. grab the raw AI output\n  const raw = item.json.output;\n\n  // 2. extract what's between ```json ... ``` (or fall back to full text)\n  const match = raw.match(/```json\\s*([\\s\\S]*?)```/);\n  const jsonPayload = (match ? match[1] : raw).trim();\n\n  // 3. remove any trailing commas before } or ]\n  const clean = jsonPayload.replace(/,\\s*([\\]}])/g, '$1');\n\n  // 4. parse into an object, with error reporting\n  let data;\n  try {\n    data = JSON.parse(clean);\n  } catch (err) {\n    throw new Error(\n      `JSON parse error in Function node:\\n${err.message}\\n\\nPayload was:\\n${clean}`\n    );\n  }\n\n  // 5. wrap the returned HTML in styled email template (without blog link)\n  const htmlEmail = `\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>${data.subject}</title>\n  <style>\n    body { font-family: Arial, sans-serif; line-height:1.5; color:#333; background-color:#f7f9fa; margin:0; padding:20px; }\n    .container { max-width:700px; margin:0 auto; background:#fff; border-radius:8px; box-shadow:0 2px 8px rgba(0,0,0,0.1); overflow:hidden; }\n    .header { background:#2c3e50; color:#fff; padding:20px; text-align:center; }\n    .header h1 { margin:0; font-size:24px; }\n    .content { padding:20px; }\n    h2 { color:#e74c3c; border-bottom:2px solid #e74c3c; padding-bottom:5px; }\n    ul { padding-left:20px; }\n    li { margin-bottom:10px; }\n    a { color:#2980b9; text-decoration:none; }\n    a:hover { text-decoration:underline; }\n    .footer { background:#ecf0f1; text-align:center; padding:10px; font-size:12px; color:#7f8c8d; }\n  </style>\n</head>\n<body>\n  <div class=\"container\">\n    <div class=\"header\">\n      <h1>${data.subject}</h1>\n    </div>\n    <div class=\"content\">\n      ${data.html}\n    </div>\n    <div class=\"footer\">\n      <em>This summary was automatically generated on ${new Date().toLocaleDateString('en-US', {\n        year: 'numeric', month: 'long', day: 'numeric'\n      })}.</em>\n    </div>\n  </div>\n</body>\n</html>\n  `.trim();\n\n  // 6. emit subject + styled html\n  return {\n    json: {\n      subject: data.subject,\n      html: htmlEmail,\n    }\n  };\n});"
      },
      "typeVersion": 2
    },
    {
      "id": "deaaeb3a-5a14-4b2a-baf8-4443e7ed9740",
      "name": "Compliance: Finalen Newsletter-HTML erstellen",
      "type": "n8n-nodes-base.code",
      "position": [
        -360,
        4840
      ],
      "parameters": {
        "jsCode": "return items.map(item => {\n  // 1. grab the raw AI output\n  const raw = item.json.output;\n\n  // 2. extract what's between ```json ... ``` (or fall back to full text)\n  const match = raw.match(/```json\\s*([\\s\\S]*?)```/);\n  const jsonPayload = (match ? match[1] : raw).trim();\n\n  // 3. remove any trailing commas before } or ]\n  const clean = jsonPayload.replace(/,\\s*([\\]}])/g, '$1');\n\n  // 4. parse into an object, with error reporting\n  let data;\n  try {\n    data = JSON.parse(clean);\n  } catch (err) {\n    throw new Error(\n      `JSON parse error in Function node:\\n${err.message}\\n\\nPayload was:\\n${clean}`\n    );\n  }\n\n  // 5. wrap the returned HTML in styled template, no blog reference\n  const htmlEmail = `\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>${data.subject}</title>\n  <style>\n    body { font-family: Arial, sans-serif; line-height:1.5; color:#333; background-color:#f7f9fa; margin:0; padding:20px; }\n    .container { max-width:700px; margin:0 auto; background:#fff; border-radius:8px; box-shadow:0 2px 8px rgba(0,0,0,0.1); overflow:hidden; }\n    .header { background:#2c3e50; color:#fff; padding:20px; text-align:center; }\n    .header h1 { margin:0; font-size:24px; }\n    .content { padding:20px; }\n    h2 { color:#e74c3c; border-bottom:2px solid #e74c3c; padding-bottom:5px; }\n    ul { padding-left:20px; }\n    li { margin-bottom:10px; }\n    a { color:#2980b9; text-decoration:none; }\n    a:hover { text-decoration:underline; }\n    .footer { background:#ecf0f1; text-align:center; padding:10px; font-size:12px; color:#7f8c8d; }\n  </style>\n</head>\n<body>\n  <div class=\"container\">\n    <div class=\"header\">\n      <h1>${data.subject}</h1>\n    </div>\n    <div class=\"content\">\n      ${data.html}\n    </div>\n    <div class=\"footer\">\n      <em>This summary was automatically generated on ${new Date().toLocaleDateString('en-US', {\n        year: 'numeric', month: 'long', day: 'numeric'\n      })}.</em>\n    </div>\n  </div>\n</body>\n</html>\n  `.trim();\n\n  // 6. emit subject + styled html\n  return {\n    json: {\n      subject: data.subject,\n      html: htmlEmail,\n    }\n  };\n});"
      },
      "typeVersion": 2
    },
    {
      "id": "fa9ac785-bc9d-43ba-8ca3-36abba10d506",
      "name": "Sicherheit: Finale E-Mail-Zusammenfassung senden",
      "type": "n8n-nodes-base.gmail",
      "position": [
        -120,
        3620
      ],
      "webhookId": "2ffca73d-6ca2-4c61-88ec-3542600d2788",
      "parameters": {
        "sendTo": "abc@mail.com",
        "message": "={{ $json.html }}",
        "options": {},
        "subject": "={{ $json.subject }}"
      },
      "credentials": {
        "gmailOAuth2": {
          "id": "Hd26wEkbjGRPpchT",
          "name": "Gmail account [abc@mail.com]"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "59c16785-571c-4403-85cf-7f7bfc14a630",
      "name": "Datenschutz: Finale E-Mail-Zusammenfassung senden",
      "type": "n8n-nodes-base.gmail",
      "position": [
        -140,
        4280
      ],
      "webhookId": "0e8133d5-e700-4bb9-8ef0-6c86f7ed4a59",
      "parameters": {
        "sendTo": "abc@mail.com",
        "message": "={{ $json.html }}",
        "options": {},
        "subject": "={{ $json.subject }}"
      },
      "credentials": {
        "gmailOAuth2": {
          "id": "Hd26wEkbjGRPpchT",
          "name": "Gmail account [abc@mail.com]"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "7526ae74-1bae-4eca-9c87-51c274565a8a",
      "name": "Compliance: Finale E-Mail-Zusammenfassung senden",
      "type": "n8n-nodes-base.gmail",
      "position": [
        -140,
        4840
      ],
      "webhookId": "5d5a1988-01cd-4e67-9c02-9090aa851669",
      "parameters": {
        "sendTo": "abc@mail.com",
        "message": "={{ $json.html }}",
        "options": {},
        "subject": "={{ $json.subject }}"
      },
      "credentials": {
        "gmailOAuth2": {
          "id": "Hd26wEkbjGRPpchT",
          "name": "Gmail account [abc@mail.com]"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "6fa939b5-12ac-47a0-ac7f-ca9957367ce2",
      "name": "Sicherheitsartikel nach Datum sortieren",
      "type": "n8n-nodes-base.sort",
      "position": [
        -1160,
        3620
      ],
      "parameters": {
        "options": {},
        "sortFieldsUi": {
          "sortField": [
            {
              "order": "descending",
              "fieldName": "isoDate"
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "7aa3a27b-72d7-4a03-83c8-361a6fbc555d",
      "name": "Datenschutzartikel nach Datum sortieren",
      "type": "n8n-nodes-base.sort",
      "position": [
        -1180,
        4280
      ],
      "parameters": {
        "options": {},
        "sortFieldsUi": {
          "sortField": [
            {
              "order": "descending",
              "fieldName": "isoDate"
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "fba86936-5208-4232-bda9-714886807b9c",
      "name": "Compliance-Artikel nach Datum sortieren",
      "type": "n8n-nodes-base.sort",
      "position": [
        -1180,
        4840
      ],
      "parameters": {
        "options": {},
        "sortFieldsUi": {
          "sortField": [
            {
              "order": "descending",
              "fieldName": "isoDate"
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "8d90a0ed-b9e1-440e-963a-e4c9f5285b32",
      "name": "Notizzettel",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2460,
        3380
      ],
      "parameters": {
        "width": 2600,
        "height": 580,
        "content": "## 📬 Daily Security Newsletter"
      },
      "typeVersion": 1
    },
    {
      "id": "946997e7-58bc-4ca0-89aa-32e39f327808",
      "name": "Notizzettel1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2460,
        4020
      ],
      "parameters": {
        "color": 4,
        "width": 2600,
        "height": 580,
        "content": "## 📬 Daily Privacy Newsletter"
      },
      "typeVersion": 1
    },
    {
      "id": "61aca795-5b6a-4301-9cea-946e0358b8c5",
      "name": "Notizzettel2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2460,
        4660
      ],
      "parameters": {
        "color": 6,
        "width": 2600,
        "height": 580,
        "content": "## 📬 Daily Compliance Newsletter"
      },
      "typeVersion": 1
    },
    {
      "id": "ca6c3e50-8ea8-436c-ab77-94501667a431",
      "name": "Sicherheits-RSS aufteilen",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        -2040,
        3620
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "rss_url"
      },
      "typeVersion": 1
    },
    {
      "id": "5784491f-071c-4159-af29-6e21305f5e78",
      "name": "Compliance-RSS aufteilen",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        -2060,
        4840
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "rss_url"
      },
      "typeVersion": 1
    },
    {
      "id": "edbd5da4-f18c-4d08-8023-df4ef7ec11fa",
      "name": "Sicherheits-RSS lesen",
      "type": "n8n-nodes-base.rssFeedRead",
      "position": [
        -1820,
        3620
      ],
      "parameters": {
        "url": "={{ $json.rss_url }}",
        "options": {}
      },
      "retryOnFail": true,
      "typeVersion": 1.1
    },
    {
      "id": "76d973a7-832e-4049-80ea-c0d28b72b345",
      "name": "Datenschutz-RSS lesen",
      "type": "n8n-nodes-base.rssFeedRead",
      "position": [
        -1840,
        4280
      ],
      "parameters": {
        "url": "={{ $json.rss_url }}",
        "options": {}
      },
      "retryOnFail": true,
      "typeVersion": 1.1
    },
    {
      "id": "5503fe77-8ae3-4d41-97d3-6520cb60067e",
      "name": "Compliance-RSS lesen",
      "type": "n8n-nodes-base.rssFeedRead",
      "position": [
        -1840,
        4840
      ],
      "parameters": {
        "url": "={{ $json.rss_url }}",
        "options": {}
      },
      "retryOnFail": true,
      "typeVersion": 1.1
    },
    {
      "id": "c2538e17-1584-45a5-8a6e-1b220ed512a5",
      "name": "Datenschutz-RSS aufteilen",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        -2060,
        4280
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "rss_url"
      },
      "typeVersion": 1
    },
    {
      "id": "d1ae80d8-8094-4f84-aa9e-d4533a99a70d",
      "name": "Sicherheits-RSS abrufen",
      "type": "n8n-nodes-base.code",
      "position": [
        -2260,
        3620
      ],
      "parameters": {
        "jsCode": "// This node returns curated cybersecurity RSS feeds\n// You can add, remove, or modify feeds as needed\n\nreturn [\n  {\n    json: {\n      name: \"Krebs on Security\",\n      website: \"https://krebsonsecurity.com\",\n      rss_url: \"https://krebsonsecurity.com/feed/\"\n    }\n  },\n  {\n    json: {\n      name: \"The Hacker News\",\n      website: \"https://thehackernews.com\",\n      rss_url: \"https://feeds.feedburner.com/TheHackersNews\"\n    }\n  },\n  {\n    json: {\n      name: \"Dark Reading\",\n      website: \"https://www.darkreading.com\",\n      rss_url: \"https://www.darkreading.com/rss.xml\"\n    }\n  },\n  {\n    json: {\n      name: \"SANS Internet Storm Center\",\n      website: \"https://isc.sans.edu\",\n      rss_url: \"https://isc.sans.edu/rssfeed_full.xml\"\n    }\n  },\n  {\n    json: {\n      name: \"Cisco Talos Intelligence Blog\",\n      website: \"https://blog.talosintelligence.com\",\n      rss_url: \"https://blog.talosintelligence.com/rss/\"\n    }\n  },\n  {\n    json: {\n      name: \"WeLiveSecurity (ESET)\",\n      website: \"https://www.welivesecurity.com\",\n      rss_url: \"https://feeds.feedburner.com/eset/blog\"\n    }\n  },\n  {\n    json: {\n      name: \"Graham Cluley Security Blog\",\n      website: \"https://grahamcluley.com\",\n      rss_url: \"https://grahamcluley.com/feed/\"\n    }\n  }\n];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "fbec32fd-2ca9-4f1f-84f9-e581bc6a37e5",
      "name": "Notizzettel3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -120,
        3480
      ],
      "parameters": {
        "color": 7,
        "height": 100,
        "content": "### Update your email address or distribution list (DL) below\n⬇️"
      },
      "typeVersion": 1
    },
    {
      "id": "4479495e-3e87-4a75-9fcc-36b230895854",
      "name": "Notizzettel4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -140,
        4160
      ],
      "parameters": {
        "color": 7,
        "height": 100,
        "content": "### Update your email address or distribution list (DL) below\n⬇️"
      },
      "typeVersion": 1
    },
    {
      "id": "18971219-b68d-4423-adbc-2f25174ae8a9",
      "name": "Notizzettel5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -140,
        4720
      ],
      "parameters": {
        "color": 7,
        "height": 100,
        "content": "### Update your email address or distribution list (DL) below\n⬇️"
      },
      "typeVersion": 1
    },
    {
      "id": "349ec0eb-9b5f-4bea-9b83-35d6cb63c1fa",
      "name": "Notizzettel6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2320,
        3520
      ],
      "parameters": {
        "color": 7,
        "height": 80,
        "content": "### Update the RSS feed URL as needed to fetch content from your preferred source."
      },
      "typeVersion": 1
    },
    {
      "id": "4f3b0da6-4db7-41e9-aa0a-9bd084fce819",
      "name": "Notizzettel7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2340,
        4180
      ],
      "parameters": {
        "color": 7,
        "height": 80,
        "content": "### Update the RSS feed URL as needed to fetch content from your preferred source."
      },
      "typeVersion": 1
    },
    {
      "id": "9c48eaa6-c602-44a3-871c-33ffd9dfa476",
      "name": "Notizzettel8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2340,
        4740
      ],
      "parameters": {
        "color": 7,
        "height": 80,
        "content": "### Update the RSS feed URL as needed to fetch content from your preferred source."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "0dc52173-7378-4951-8ebc-e44443c39540",
  "connections": {
    "76d973a7-832e-4049-80ea-c0d28b72b345": {
      "main": [
        [
          {
            "node": "c1f6e2ac-4bf9-4fc4-85fd-c8c7649cdc9c",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "edbd5da4-f18c-4d08-8023-df4ef7ec11fa": {
      "main": [
        [
          {
            "node": "e4fa0e00-d10b-4c86-bad3-6c0d1d59750a",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "d1ae80d8-8094-4f84-aa9e-d4533a99a70d": {
      "main": [
        [
          {
            "node": "ca6c3e50-8ea8-436c-ab77-94501667a431",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "5503fe77-8ae3-4d41-97d3-6520cb60067e": {
      "main": [
        [
          {
            "node": "ae374184-806b-4022-80b5-94bdef48133e",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "351774d8-7adc-4041-8639-bc35f9c37183": {
      "main": [
        [
          {
            "node": "c2538e17-1584-45a5-8a6e-1b220ed512a5",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "328bb06a-edfd-4a14-9011-68cdd00bcd8e": {
      "main": [
        [
          {
            "node": "d1ae80d8-8094-4f84-aa9e-d4533a99a70d",
            "type": "main",
            "index": 0
          },
          {
            "node": "d0a93584-a1bc-4da8-9aaf-129adf7e4cae",
            "type": "main",
            "index": 0
          },
          {
            "node": "351774d8-7adc-4041-8639-bc35f9c37183",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "c2538e17-1584-45a5-8a6e-1b220ed512a5": {
      "main": [
        [
          {
            "node": "76d973a7-832e-4049-80ea-c0d28b72b345",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "d0a93584-a1bc-4da8-9aaf-129adf7e4cae": {
      "main": [
        [
          {
            "node": "5784491f-071c-4159-af29-6e21305f5e78",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "ca6c3e50-8ea8-436c-ab77-94501667a431": {
      "main": [
        [
          {
            "node": "edbd5da4-f18c-4d08-8023-df4ef7ec11fa",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "5784491f-071c-4159-af29-6e21305f5e78": {
      "main": [
        [
          {
            "node": "5503fe77-8ae3-4d41-97d3-6520cb60067e",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "828bdcf3-09a4-4235-8dbb-2153f0928037": {
      "main": [
        [
          {
            "node": "a1e4eaac-aaea-4859-bd29-375a6b50aaa1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "c4cc7264-43af-4a26-89e2-5888817b1602": {
      "ai_languageModel": [
        [
          {
            "node": "828bdcf3-09a4-4235-8dbb-2153f0928037",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "7aa3a27b-72d7-4a03-83c8-361a6fbc555d": {
      "main": [
        [
          {
            "node": "14fd5f01-075f-4648-a1ab-f0a87d2b676a",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "7be7a9fe-e8f5-4a56-a77d-7ca098d52479": {
      "main": [
        [
          {
            "node": "7a864b0c-08f5-4e97-8430-1879f8e0e3d0",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "1e261592-348a-42af-b4ba-1b2be82b0143": {
      "ai_languageModel": [
        [
          {
            "node": "7be7a9fe-e8f5-4a56-a77d-7ca098d52479",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "6fa939b5-12ac-47a0-ac7f-ca9957367ce2": {
      "main": [
        [
          {
            "node": "9cb809e9-4d49-452e-823e-3f54adca0529",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "14fd5f01-075f-4648-a1ab-f0a87d2b676a": {
      "main": [
        [
          {
            "node": "828bdcf3-09a4-4235-8dbb-2153f0928037",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "bb59ecfa-b197-47c4-a32e-0834c187100e": {
      "main": [
        [
          {
            "node": "deaaeb3a-5a14-4b2a-baf8-4443e7ed9740",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "9cb809e9-4d49-452e-823e-3f54adca0529": {
      "main": [
        [
          {
            "node": "7be7a9fe-e8f5-4a56-a77d-7ca098d52479",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "dc4e461c-dbb8-46a1-b128-6c28584c12d4": {
      "ai_languageModel": [
        [
          {
            "node": "bb59ecfa-b197-47c4-a32e-0834c187100e",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "c1f6e2ac-4bf9-4fc4-85fd-c8c7649cdc9c": {
      "main": [
        [
          {
            "node": "cb34ed8e-5b67-4cfd-8731-482b22874780",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "fba86936-5208-4232-bda9-714886807b9c": {
      "main": [
        [
          {
            "node": "6eddd44f-8038-40fd-b0db-2a8d9c35000a",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "e4fa0e00-d10b-4c86-bad3-6c0d1d59750a": {
      "main": [
        [
          {
            "node": "e71e3c7e-a58a-49bb-9c13-827f46e4df7e",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "a1e4eaac-aaea-4859-bd29-375a6b50aaa1": {
      "main": [
        [
          {
            "node": "59c16785-571c-4403-85cf-7f7bfc14a630",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "cb34ed8e-5b67-4cfd-8731-482b22874780": {
      "main": [
        [
          {
            "node": "7aa3a27b-72d7-4a03-83c8-361a6fbc555d",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "6eddd44f-8038-40fd-b0db-2a8d9c35000a": {
      "main": [
        [
          {
            "node": "bb59ecfa-b197-47c4-a32e-0834c187100e",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "7a864b0c-08f5-4e97-8430-1879f8e0e3d0": {
      "main": [
        [
          {
            "node": "fa9ac785-bc9d-43ba-8ca3-36abba10d506",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "e71e3c7e-a58a-49bb-9c13-827f46e4df7e": {
      "main": [
        [
          {
            "node": "6fa939b5-12ac-47a0-ac7f-ca9957367ce2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "ae374184-806b-4022-80b5-94bdef48133e": {
      "main": [
        [
          {
            "node": "07c94d37-ad0a-4f89-961c-abf1d6eeeeef",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "deaaeb3a-5a14-4b2a-baf8-4443e7ed9740": {
      "main": [
        [
          {
            "node": "7526ae74-1bae-4eca-9c87-51c274565a8a",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "07c94d37-ad0a-4f89-961c-abf1d6eeeeef": {
      "main": [
        [
          {
            "node": "fba86936-5208-4232-bda9-714886807b9c",
            "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 - Künstliche Intelligenz, Sicherheitsbetrieb

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 Nodes43
Kategorie2
Node-Typen11
Schwierigkeitsbeschreibung

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

Autor
Niranjan G

Niranjan G

@niranjan

Cybersecurity leader turning complex workflows into seamless, AI-driven automations.

Externe Links
Auf n8n.io ansehen

Diesen Workflow teilen

Kategorien

Kategorien: 34