AutomationFlowsSlack & Telegram › SSL Certificate Monitoring with Discord Alerts

SSL Certificate Monitoring with Discord Alerts

Original n8n title: Comprehensive Ssl Certificate Monitoring with Discord Alerts and Notion Integration

ByTom Cao @tomcao on n8n.io

Daily Trigger runs the workflow every morning for proactive monitoring. URL Collection fetches the list of website URLs to monitor from your data source. Dual SSL Analysis: Free SSL Assessment Script — Get from sysadmin-toolkit on Github SSL-Checker.io API — External…

Cron / scheduled trigger★★★★☆ complexity16 nodesHTTP RequestSshDiscordNotion
Slack & Telegram Trigger: Cron / scheduled Nodes: 16 Complexity: ★★★★☆ Added:

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

This workflow follows the Discord → HTTP Request 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": "REwp6JdhNjvbGQ1J",
  "name": "My workflow",
  "tags": [],
  "nodes": [
    {
      "id": "106c2b40-43f5-432d-9fdd-446e7309abc7",
      "name": "Check SSL",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2300,
        580
      ],
      "parameters": {
        "url": "=https://ssl-checker.io/api/v1/check/{{ $json[\"property_domains\"].replace(/^https?:\\/\\//, \"\").replace(/\\/$/, \"\") }}",
        "options": {}
      },
      "typeVersion": 4.2
    },
    {
      "id": "92e421ce-6f88-44d4-9018-8b39e9fad396",
      "name": "Expiry Alert",
      "type": "n8n-nodes-base.if",
      "position": [
        2660,
        580
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "ee6e2ce8-569a-4f1f-91b5-2c55f605a16b",
              "operator": {
                "type": "number",
                "operation": "lte"
              },
              "leftValue": "={{ $json.result.days_left }}",
              "rightValue": 7
            },
            {
              "id": "d82f8203-0908-4a48-9eb7-48e11555c1c2",
              "operator": {
                "name": "filter.operator.equals",
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "bafe935b-b283-428f-934a-49d03de5d38f",
      "name": "Daily Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        1620,
        960
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "triggerAtHour": 10
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "873fc171-6b69-4e80-b81a-f14d68c885f4",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        540,
        140
      ],
      "parameters": {
        "width": 920,
        "height": 1760,
        "content": "## \ud83d\udd10 Advanced SSL Health Monitor\n### \ud83d\udc64 Who is this for?\n#### This workflow is designed for **DevOps engineers, IT administrators, and security professionals** who need comprehensive **SSL certificate monitoring and health assessment** across multiple domains \u2014 featuring **dual verification** and **professional reporting** without relying on expensive monitoring services.\n\n---\n\n### \ud83e\udde9 What It Does\n1. **Daily Trigger** runs the workflow every morning for proactive monitoring.\n2. **URL Collection** fetches the list of website URLs to monitor from your data source.\n3. **Dual SSL Analysis**:\n   - **Bubobot SSL Scanner** \u2014 Our custom SSL health assessment tool (SSL Labs-style analysis)\n   - **SSL-Checker.io API** \u2014 External verification for cross-validation\n4. **Comprehensive Health Check**:\n   - Certificate expiration monitoring (customizable threshold)\n   - SSL configuration security assessment\n   - Protocol support analysis (TLS 1.3, 1.2, deprecated protocols)\n   - Cipher suite strength evaluation\n   - Vulnerability scanning (POODLE, BEAST, etc.)\n   - Compliance checking (PCI DSS, NIST, FIPS)\n5. **Smart Alert System** sends Discord notifications when:\n   - Certificates expire within threshold (default: 30 days)\n   - SSL configuration issues detected (weak ciphers, deprecated protocols)\n   - Security vulnerabilities found\n   - Compliance standards not met\n   - Grade drops below acceptable level (configurable)\n\n---\n\n### \ud83c\udfaf Key Features\n- **\ud83d\udd04 Dual Verification**: Cross-checks results between internal scanner and external API\n- **\ud83d\udcca SSL Labs-Style Grading**: A+ to F rating system with detailed analysis\n- **\ud83d\udee1\ufe0f Security Assessment**: Vulnerability detection and compliance checking\n- **\ud83d\udcf1 Discord Integration**: Rich embed notifications with color-coded alerts\n- **\ud83d\udcc8 Historical Tracking**: Maintain SSL health trends over time\n- **\ud83d\udea8 Smart Alerting**: Only alerts on actual issues, reducing noise\n- **\ud83d\udcc4 Professional Reports**: HTML reports for stakeholder sharing\n\n---\n\n### \u2699\ufe0f Setup Instructions\n1. **Data Source**:  \n   - Configure your URL source from Notion\n   - Ensure it contains a `URL` column with domains to monitor\n2. **Credentials**:  \n   - Set up **Discord webhook** for alert notifications\n   - Configure any required **API credentials** for data sources\n3. **Customize Thresholds**:  \n   - **Expiration Alert**: Days before expiry (default: 30 days)\n   - **Grade Threshold**: Minimum acceptable SSL grade (default: B)\n   - **Alert Severity**: Choose which issues trigger notifications\n4. **Advanced Configuration**:\n   - Modify **vulnerability checks** based on your security requirements\n   - Adjust **compliance standards** for your industry needs\n   - Customize **Discord message formatting** and alert channels\n\n---\n\n### \ud83e\udde0 Technical Notes\n- **Dual-Check Reliability**: Combines custom Bubobot scanner with ssl-checker.io for maximum accuracy\n- **No Vendor Lock-in**: Uses free public APIs and open-source tools\n- **Scalable Architecture**: Easily handles monitoring of hundreds of domains\n- **Professional Reporting**: Generates SSL Labs-quality assessments\n- **Security-First Approach**: Comprehensive vulnerability and compliance checking\n- **Flexible Alerting**: Discord integration with rich formatting and conditional logic\n\n\nThis workflow transforms basic SSL expiry checking into a **comprehensive SSL security monitoring solution** that rivals enterprise-grade tools while remaining completely open-source and cost-effective."
      },
      "typeVersion": 1
    },
    {
      "id": "b3cf7e3e-3d7b-484c-bd26-2d1aa996d020",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1560,
        780
      ],
      "parameters": {
        "height": 380,
        "content": "### \ud83d\udd52 Daily Trigger\nRuns the workflow every day at 10:00 AM.  \nAdjust the time or frequency as needed using cron or interval settings.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "d55ad3b8-6cf1-479c-9646-973ff2946964",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1860,
        780
      ],
      "parameters": {
        "height": 380,
        "content": "### \ud83d\udcc4 Fetch URLs\nReads website URLs from Notion.  \nMake sure the sheet has a column named `URL` containing the domains you want to monitor.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "fbb9752a-9231-4a3e-93ed-149770335f64",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2260,
        420
      ],
      "parameters": {
        "height": 320,
        "content": "### \ud83d\udd0d Check SSL\nQueries `ssl-checker.io` (free API) for SSL certificate data of each domain.  \nReturns valid_from, valid_till, days_left, and host info.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "b5018cec-3c2e-4824-9d57-87157fc28616",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "disabled": true,
      "position": [
        2600,
        420
      ],
      "parameters": {
        "height": 320,
        "content": "### \u26a0\ufe0f Expiry Alert\nChecks if `days_left` is less than or equal to 7.  \nOnly domains that meet this condition will trigger an email alert.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "a9913ede-0f83-4352-bf31-3634b856c35e",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "disabled": true,
      "position": [
        2940,
        420
      ],
      "parameters": {
        "width": 260,
        "height": 320,
        "content": "### \ud83d\udce7 Send Discord alerts\nSends alerts whether there are problems"
      },
      "typeVersion": 1
    },
    {
      "id": "819e2cb7-d1a4-4fdd-b62a-d2378161373a",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2280,
        1180
      ],
      "parameters": {
        "width": 520,
        "height": 320,
        "content": "### \ud83d\udd0d Check SSL health score\nUse sysadmin-toolkit/scripts/ssl/ssl-health-assessment.js\n  \nReturns SSL overall grade, vulnerabilities and actions to take"
      },
      "typeVersion": 1
    },
    {
      "id": "e5ef4591-f45c-4712-97b4-0d7a520c238d",
      "name": "SSH - Analyze system",
      "type": "n8n-nodes-base.ssh",
      "position": [
        2380,
        1340
      ],
      "parameters": {
        "command": "=node /opt/sysadmin-toolkit/scripts/ssl/ssl-health-assessment.js {{ $json.property_domains }} --json",
        "authentication": "privateKey"
      },
      "typeVersion": 1,
      "alwaysOutputData": true
    },
    {
      "id": "240f78ee-96ab-4f53-bb9c-c40e0f8d0961",
      "name": "Discord",
      "type": "n8n-nodes-base.discord",
      "position": [
        2980,
        1340
      ],
      "parameters": {
        "content": "={{ $json.discord.title }}\n\n{{ $json.discord.fullDescription }}",
        "guildId": {
          "__rl": true,
          "mode": "list",
          "value": "1254730427805990942",
          "cachedResultUrl": "https://discord.com/channels/1254730427805990942",
          "cachedResultName": "b0ld8"
        },
        "options": {},
        "resource": "message",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "1254730427805990945",
          "cachedResultUrl": "https://discord.com/channels/1254730427805990942/1254730427805990945",
          "cachedResultName": "general"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "edc63e4c-8a87-4fbb-ba61-195b3e587965",
      "name": "Discord1",
      "type": "n8n-nodes-base.discord",
      "position": [
        3000,
        560
      ],
      "parameters": {
        "content": "=SSL Expiry - {{ $json.result.days_left }} days Left - {{ $json.result.host }}",
        "guildId": {
          "__rl": true,
          "mode": "list",
          "value": "1254730427805990942",
          "cachedResultUrl": "https://discord.com/channels/1254730427805990942",
          "cachedResultName": "b0ld8"
        },
        "options": {},
        "resource": "message",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "1254730427805990945",
          "cachedResultUrl": "https://discord.com/channels/1254730427805990942/1254730427805990945",
          "cachedResultName": "general"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "c58aad29-de35-46e1-b43a-dfcfac0cffc2",
      "name": "Fetch domains to check SSL",
      "type": "n8n-nodes-base.notion",
      "position": [
        1920,
        960
      ],
      "parameters": {
        "options": {},
        "resource": "databasePage",
        "operation": "getAll",
        "returnAll": true,
        "databaseId": {
          "__rl": true,
          "mode": "list",
          "value": "22612359-20f8-80f4-897f-eae0ad313057",
          "cachedResultUrl": "https://www.notion.so/2261235920f880f4897feae0ad313057",
          "cachedResultName": "n8n flow - SSL Certificate Expiry Monitoring"
        },
        "filterType": "manual"
      },
      "typeVersion": 2.2
    },
    {
      "id": "b544b226-ceb6-439d-b350-4e77b39e2fde",
      "name": "Code - Format output",
      "type": "n8n-nodes-base.code",
      "position": [
        2620,
        1340
      ],
      "parameters": {
        "jsCode": "// n8n Code Node - Parse SSL Scanner Output\n// This code processes the SSH node output and formats it for Discord notifications\n\nconst results = [];\n\nfor (const item of $input.all()) {\n  try {\n    // Extract the stdout from SSH response\n    const sshOutput = item.json;\n    \n    // Check if SSH command was successful\n    if (sshOutput.code !== 0) {\n      results.push({\n        json: {\n          hostname: 'unknown',\n          status: 'error',\n          error: sshOutput.stderr || 'SSH command failed',\n          alert: true,\n          alertLevel: 'critical'\n        }\n      });\n      continue;\n    }\n    \n    // Parse the JSON output from stdout\n    let sslData;\n    try {\n      sslData = JSON.parse(sshOutput.stdout);\n    } catch (parseError) {\n      results.push({\n        json: {\n          hostname: 'unknown',\n          status: 'error',\n          error: 'Failed to parse SSL scanner output',\n          alert: true,\n          alertLevel: 'critical'\n        }\n      });\n      continue;\n    }\n    \n    // Extract key information for Discord notification\n    const parsedResult = {\n      // Basic info\n      hostname: sslData.hostname,\n      port: sslData.port || 443,\n      scanTime: sslData.scanTime,\n      scanDuration: sslData.scanDuration,\n      \n      // Overall status\n      overallGrade: sslData.overallGrade,\n      connectionStatus: sslData.connectionStatus || 'unknown',\n      success: sslData.success || false,\n      \n      // Certificate info\n      certificate: {\n        subject: sslData.certificate?.subject || 'unknown',\n        issuer: sslData.certificate?.issuer || 'unknown',\n        validUntil: sslData.certificate?.validUntil,\n        daysUntilExpiry: sslData.certificate?.daysUntilExpiry,\n        isValid: sslData.certificate?.isValid || false,\n        issues: sslData.certificate?.issues || [],\n        hostnameMatch: sslData.certificate?.hostnameMatch || false\n      },\n      \n      // Protocol support\n      protocols: {\n        tls13: sslData.protocols?.tls13 || false,\n        tls12: sslData.protocols?.tls12 || false,\n        tls11: sslData.protocols?.tls11 || false,\n        tls10: sslData.protocols?.tls10 || false,\n        ssl3: sslData.protocols?.ssl3 || false\n      },\n      \n      // Security info\n      vulnerabilities: {\n        hasVulnerabilities: sslData.vulnerabilities?.hasVulnerabilities || false,\n        poodle: sslData.vulnerabilities?.poodle || false,\n        freak: sslData.vulnerabilities?.freak || false,\n        details: sslData.vulnerabilities || {}\n      },\n      \n      // Grades breakdown\n      grades: sslData.grades || {},\n      \n      // Recommendations\n      recommendations: sslData.recommendations || [],\n      \n      // Error handling\n      error: sslData.error,\n      \n      // Alert logic\n      alert: false,\n      alertLevel: 'info',\n      alertReasons: []\n    };\n    \n    // Determine if this needs an alert\n    const alertReasons = [];\n    let alertLevel = 'info';\n    \n    // Critical alerts\n    if (sslData.error) {\n      alertReasons.push(`Scan failed: ${sslData.error}`);\n      alertLevel = 'critical';\n    }\n    \n    if (!parsedResult.certificate.isValid) {\n      alertReasons.push('Certificate is invalid');\n      alertLevel = 'critical';\n    }\n    \n    if (parsedResult.certificate.daysUntilExpiry <= 0) {\n      alertReasons.push('Certificate has expired');\n      alertLevel = 'critical';\n    }\n    \n    // High priority alerts\n    if (parsedResult.certificate.daysUntilExpiry <= 7 && parsedResult.certificate.daysUntilExpiry > 0) {\n      alertReasons.push(`Certificate expires in ${parsedResult.certificate.daysUntilExpiry} days`);\n      if (alertLevel === 'info') alertLevel = 'high';\n    }\n    \n    if (parsedResult.vulnerabilities.hasVulnerabilities) {\n      alertReasons.push('Security vulnerabilities detected');\n      if (alertLevel === 'info') alertLevel = 'high';\n    }\n    \n    if (!parsedResult.certificate.hostnameMatch) {\n      alertReasons.push('Hostname mismatch detected');\n      if (alertLevel === 'info') alertLevel = 'high';\n    }\n    \n    // Medium priority alerts\n    if (parsedResult.certificate.daysUntilExpiry <= 30 && parsedResult.certificate.daysUntilExpiry > 7) {\n      alertReasons.push(`Certificate expires in ${parsedResult.certificate.daysUntilExpiry} days`);\n      if (alertLevel === 'info') alertLevel = 'medium';\n    }\n    \n    if (['C', 'D', 'F'].includes(parsedResult.overallGrade)) {\n      alertReasons.push(`Poor SSL grade: ${parsedResult.overallGrade}`);\n      if (alertLevel === 'info') alertLevel = 'medium';\n    }\n    \n    if (parsedResult.protocols.ssl3 || parsedResult.protocols.tls10) {\n      alertReasons.push('Deprecated protocols enabled');\n      if (alertLevel === 'info') alertLevel = 'medium';\n    }\n    \n    // Low priority alerts\n    if (parsedResult.recommendations && parsedResult.recommendations.length > 0) {\n      alertReasons.push(`${parsedResult.recommendations.length} recommendations available`);\n      if (alertLevel === 'info') alertLevel = 'low';\n    }\n    \n    // Set alert status\n    parsedResult.alert = alertReasons.length > 0;\n    parsedResult.alertLevel = alertLevel;\n    parsedResult.alertReasons = alertReasons;\n    \n    // Add Discord formatting helpers\n    parsedResult.discord = {\n      color: getDiscordColor(alertLevel, parsedResult.overallGrade),\n      title: `SSL Health Check: ${parsedResult.hostname}`,\n      description: getDiscordDescription(parsedResult),\n      fields: getDiscordFields(parsedResult),\n      timestamp: new Date().toISOString(),\n      \n      // Pre-formatted content for easy Discord input\n      content: alertLevel === 'critical' ? '@here \ud83d\udea8 SSL Health Monitor Alert' : '\ud83d\udd10 SSL Health Monitor Alert',\n      \n      // Simple descriptions without complex logic\n      simpleDescription: parsedResult.alert \n        ? `\u26a0\ufe0f SSL issues detected for ${parsedResult.hostname}`\n        : `\u2705 SSL looks healthy for ${parsedResult.hostname}`,\n        \n      // Detailed info as simple strings\n      certificateInfo: `Grade: ${parsedResult.overallGrade} | Expires in ${parsedResult.certificate.daysUntilExpiry} days`,\n      \n      // Alert details as simple string\n      alertSummary: parsedResult.alert \n        ? `Issues: ${parsedResult.alertReasons.join(', ')}`\n        : `Certificate expires ${parsedResult.certificate.validUntil}`,\n        \n      // Complete formatted description\n      fullDescription: getFullDiscordDescription(parsedResult)\n    };\n    \n    results.push({ json: parsedResult });\n    \n  } catch (error) {\n    // Handle any unexpected errors\n    results.push({\n      json: {\n        hostname: 'unknown',\n        status: 'error',\n        error: `Processing error: ${error.message}`,\n        alert: true,\n        alertLevel: 'critical'\n      }\n    });\n  }\n}\n\n// Helper functions for Discord formatting\nfunction getDiscordColor(alertLevel, grade) {\n  // Color mapping for Discord embeds\n  const colors = {\n    critical: 15158332, // Red\n    high: 15105570,     // Orange\n    medium: 15844367,   // Yellow\n    low: 5763719,       // Blue\n    info: 5763719       // Blue\n  };\n  \n  // Grade-based colors for non-alerts\n  const gradeColors = {\n    'A+': 5763719,  // Green\n    'A': 3066993,   // Green\n    'B': 15844367,  // Yellow\n    'C': 15105570,  // Orange\n    'D': 15158332,  // Red\n    'F': 10038562   // Dark Red\n  };\n  \n  if (alertLevel !== 'info') {\n    return colors[alertLevel] || colors.info;\n  }\n  \n  return gradeColors[grade] || colors.info;\n}\n\nfunction getFullDiscordDescription(result) {\n  if (result.error) {\n    return `\u274c SSL scan failed: ${result.error}`;\n  }\n  \n  if (result.alert) {\n    let description = `\u26a0\ufe0f SSL issues detected for ${result.hostname}\\n`;\n    description += `Grade: ${result.overallGrade} | Expires in ${result.certificate.daysUntilExpiry} days\\n\\n`;\n    description += `Issues found:\\n`;\n    result.alertReasons.forEach(reason => {\n      description += `\u2022 ${reason}\\n`;\n    });\n    return description.trim();\n  }\n  \n  return `\u2705 SSL configuration looks good for ${result.hostname}\\nGrade: ${result.overallGrade} | Certificate expires in ${result.certificate.daysUntilExpiry} days`;\n}\n\nfunction getDiscordDescription(result) {\n  if (result.error) {\n    return `\u274c SSL scan failed: ${result.error}`;\n  }\n  \n  if (result.alert) {\n    // Create simple alert description\n    let description = \"\u26a0\ufe0f SSL issues detected:\\n\";\n    result.alertReasons.forEach(reason => {\n      description += `\u2022 ${reason}\\n`;\n    });\n    return description.trim();\n  }\n  \n  return `\u2705 SSL configuration looks good\\nGrade: ${result.overallGrade} | Expires in ${result.certificate.daysUntilExpiry} days`;\n}\n\nfunction getDiscordFields(result) {\n  const fields = [];\n  \n  // Certificate info\n  fields.push({\n    name: \"\ud83d\udcdc Certificate\",\n    value: [\n      `**Subject:** ${result.certificate.subject}`,\n      `**Issuer:** ${result.certificate.issuer}`,\n      `**Expires:** ${new Date(result.certificate.validUntil).toLocaleDateString()}`,\n      `**Days Left:** ${result.certificate.daysUntilExpiry}`\n    ].join('\\n'),\n    inline: true\n  });\n  \n  // Security info\n  fields.push({\n    name: \"\ud83d\udd10 Security\",\n    value: [\n      `**Overall Grade:** ${result.overallGrade}`,\n      `**TLS 1.2:** ${result.protocols.tls12 ? '\u2705' : '\u274c'}`,\n      `**TLS 1.3:** ${result.protocols.tls13 ? '\u2705' : '\u274c'}`,\n      `**Vulnerabilities:** ${result.vulnerabilities.hasVulnerabilities ? '\u26a0\ufe0f Found' : '\u2705 None'}`\n    ].join('\\n'),\n    inline: true\n  });\n  \n  // Add recommendations if any\n  if (result.recommendations.length > 0) {\n    fields.push({\n      name: \"\ud83d\udca1 Recommendations\",\n      value: result.recommendations.slice(0, 3).map(rec => `\u2022 ${rec.message || rec}`).join('\\n') + \n             (result.recommendations.length > 3 ? `\\n... and ${result.recommendations.length - 3} more` : ''),\n      inline: false\n    });\n  }\n  \n  return fields;\n}\n\nreturn results;"
      },
      "typeVersion": 2
    },
    {
      "id": "8e86994c-5ebc-4600-80b1-ad187b17d125",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "disabled": true,
      "position": [
        2900,
        1180
      ],
      "parameters": {
        "width": 260,
        "height": 320,
        "content": "### \ud83d\udce7 Send Discord alerts\nSends alerts whether there are problems"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "746cb098-9c5f-4b65-9bd2-c7f20d40df61",
  "connections": {
    "Check SSL": {
      "main": [
        [
          {
            "node": "Expiry Alert",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Expiry Alert": {
      "main": [
        [
          {
            "node": "Discord1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Daily Trigger": {
      "main": [
        [
          {
            "node": "Fetch domains to check SSL",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code - Format output": {
      "main": [
        [
          {
            "node": "Discord",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "SSH - Analyze system": {
      "main": [
        [
          {
            "node": "Code - Format output",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch domains to check SSL": {
      "main": [
        [
          {
            "node": "SSH - Analyze system",
            "type": "main",
            "index": 0
          },
          {
            "node": "Check SSL",
            "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

Daily Trigger runs the workflow every morning for proactive monitoring. URL Collection fetches the list of website URLs to monitor from your data source. Dual SSL Analysis: Free SSL Assessment Script — Get from sysadmin-toolkit on Github SSL-Checker.io API — External…

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

More Slack & Telegram workflows → · Browse all categories →

Related workflows

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

Slack & Telegram

This n8n workflow template is designed to provide real-time alerts on new cryptocurrency exchange listings and delistings. It caters especially to crypto traders, investors, and enthusiasts who want t

Supabase, HTTP Request, Telegram +2
Slack & Telegram

Stay ahead of commodity market movements with automated news collection, translation, and sector impact analysis. This workflow monitors Oil, Gold, and Grain markets from global English sources, trans

HTTP Request, Discord, Telegram +1
Slack & Telegram

This automated n8n workflow monitors real-time cryptocurrency prices using CoinGecko API and sends smart alerts when price conditions are met. It supports multi-coin tracking, dynamic conditions, and

Google Sheets, HTTP Request, Email Send +2
Slack & Telegram

This template is essential for Remote Operations Managers, HR Teams, and Project Leads managing distributed teams across different countries. It prevents scheduling conflicts by automatically flagging

Slack, Notion, HTTP Request
Slack & Telegram

This workflow is designed for engineering teams, project managers, and IT operations who need consistent visibility into team availability across multiple projects. It’s perfect for organizations that

HTTP Request, Execute Workflow Trigger, Slack