{
  "id": "UZyaBkQntPxoQbrA",
  "name": "SSL Monitoring",
  "tags": [],
  "nodes": [
    {
      "id": "6393b349-fc19-4625-8e53-d536d2cd5a68",
      "name": "Get SSL",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        80,
        820
      ],
      "parameters": {
        "url": "=https://ssl-checker.io/api/v1/check/{{ $json.Link.replace(/^https?:\\/\\//, \"\").replace(/\\/$/, \"\") }}",
        "options": {},
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {}
          ]
        }
      },
      "typeVersion": 4.2,
      "alwaysOutputData": true
    },
    {
      "id": "9e14ff05-74c9-4cc7-b548-f59bc4b48cad",
      "name": "Loop",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        -280,
        480
      ],
      "parameters": {
        "options": {
          "reset": false
        }
      },
      "typeVersion": 3
    },
    {
      "id": "dcc452e3-e90b-4e83-90c2-f93547d8eade",
      "name": "Update SSL in Spreadsheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        740,
        1040
      ],
      "parameters": {
        "columns": {
          "value": {
            "Name": "={{ $('Get Website List').item.json.Name }}",
            "SSL Issued On": "={{ $json.result.valid_from }}",
            "SSL Expired On": "={{ $json.result.valid_till }}"
          },
          "schema": [
            {
              "id": "No",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "No",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Name",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Link",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Link",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "SSL Issued On",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "SSL Issued On",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "SSL Expired On",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "SSL Expired On",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "SSL Status",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "SSL Status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "version",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "version",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "app",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "app",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "host",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "host",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "status",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "result",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "result",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "response_time_sec",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "response_time_sec",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "row_number",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "row_number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "Name"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "update",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1FWZ8vT5bMQXxDToguBW30LjQV_8sU9UN1wXk-2vCFTE/edit#gid=0",
          "cachedResultName": "List"
        },
        "documentId": {
          "__rl": true,
          "mode": "url",
          "value": "https://docs.google.com/spreadsheets/d/1FWZ8vT5bMQXxDToguBW30LjQV_8sU9UN1wXk-2vCFTE/edit?usp=sharing"
        },
        "authentication": "serviceAccount"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.6
    },
    {
      "id": "169a5730-d686-43ed-90bb-d590becaa145",
      "name": "Trigger Every Monday",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -1140,
        620
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "weeks",
              "triggerAtDay": [
                1
              ],
              "triggerAtHour": 7
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "92a63f90-51c8-4627-a445-9ab986dae932",
      "name": "SSL Not Good?",
      "type": "n8n-nodes-base.if",
      "position": [
        480,
        360
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "3dfd4edd-6a4d-4a41-b2f3-647bc7308aaa",
              "operator": {
                "type": "string",
                "operation": "notEquals"
              },
              "leftValue": "={{ $json.message }}",
              "rightValue": "All Good"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "fb348ae3-27ba-41d3-9566-b0c4faa07cbf",
      "name": "Get Website List",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -760,
        620
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1FWZ8vT5bMQXxDToguBW30LjQV_8sU9UN1wXk-2vCFTE/edit#gid=0",
          "cachedResultName": "List"
        },
        "documentId": {
          "__rl": true,
          "mode": "url",
          "value": "https://docs.google.com/spreadsheets/d/1FWZ8vT5bMQXxDToguBW30LjQV_8sU9UN1wXk-2vCFTE/edit?usp=sharing"
        },
        "authentication": "serviceAccount"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.6
    },
    {
      "id": "88e6b31e-702a-460a-a5ec-7b7e05ea3852",
      "name": "Code",
      "type": "n8n-nodes-base.code",
      "position": [
        80,
        380
      ],
      "parameters": {
        "jsCode": "// Get the current date and time\nconst now = new Date();\n\n// Set the threshold (in days) for SSL expiration warning\nconst thresholdDays = 14;\n\n// Filter the input data to only include entries where the SSL certificate\n// expires within the threshold (i.e., 14 days or fewer from today)\nconst filtered = $input.all().filter(item => {\n  const expiry = new Date(item.json[\"SSL Expired On\"]);\n  const daysLeft = (expiry - now) / (1000 * 60 * 60 * 24); // Convert milliseconds to days\n  return daysLeft <= thresholdDays;\n});\n\n// If no certificates are expiring soon, return a simple \"All Good\" message\nif (filtered.length === 0) {\n  return [\n    {\n      json: {\n        message: \"All Good\"\n      }\n    }\n  ];\n} else {\n  // If some certificates are expiring soon, build a message listing them\n  const websiteNames = filtered.map(entry => {\n    const daysLeft = Math.ceil((new Date(entry.json[\"SSL Expired On\"]) - now) / (1000 * 60 * 60 * 24));\n    return `- ${entry.json.Name} (expires in ${daysLeft} days)`;\n  }).join('\\n');\n\n  // Create the final message to return\n  const message = `SSL certificates expiring soon:\\n${websiteNames}`;\n\n  return [\n    {\n      json: {\n        message: message\n      }\n    }\n  ];\n}\n"
      },
      "typeVersion": 2
    },
    {
      "id": "e24a0b93-3812-4f35-a758-9daecaa200d3",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1220,
        420
      ],
      "parameters": {
        "width": 260,
        "height": 360,
        "content": "## Weekly Trigger\n\nThis workflow trigger is scheduled to run every Monday at 7:00 AM.\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "57ca5b4a-9dd3-4a07-b473-cabb223d594f",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -840,
        420
      ],
      "parameters": {
        "width": 260,
        "height": 360,
        "content": "## Fetch URL Website\n\nThis step reads a list of website URLs from a connected spreadsheet.\nEach row should contain a valid URL in the designated column.\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "0f641fd9-3841-4509-9921-2f9959cd40c7",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        0,
        600
      ],
      "parameters": {
        "width": 260,
        "height": 360,
        "content": "## Get SSL Status\n\nThis step checks the SSL certificate status for each URL using the ssl-checker.io API.\nIt retrieves information such as certificate validity, expiration date, and overall SSL health, helping monitor website security.\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "a8cd1179-e8b4-4b9c-94e0-fef811e29807",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        580,
        660
      ],
      "parameters": {
        "width": 400,
        "height": 560,
        "content": "## Update Spreadsheet\n\nThis step updates the spreadsheet with the latest SSL information for each website.\nEnsure your spreadsheet includes the following columns:\n\n* No\n* Name\n* Link\n* SSL Issued On\n* SSL Expired On\n* SSL Status\n\nThe node will automatically fill in or update the Issued On, Expired On, and SSL Status fields based on the SSL data retrieved.\n\n\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "64324b4e-cf9c-46a6-83e3-6e6d73e737ae",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        0,
        0
      ],
      "parameters": {
        "width": 260,
        "height": 520,
        "content": "\n## Check SSL Expiry Threshold Code\n\nThis step checks if any SSL certificates will expire within 14 days.\n\n- If none are expiring soon, it returns \"All Good\".\n\n- If some are expiring, it lists the website names and how many days are left.\n\nUse this to stay ahead of SSL renewals."
      },
      "typeVersion": 1
    },
    {
      "id": "2e68579e-168a-4ce3-af98-9a732477c245",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        400,
        60
      ],
      "parameters": {
        "width": 260,
        "height": 440,
        "content": "\n## Check Condition\nThis step checks if any SSL certificates are expiring soon (within 14 days).\nIf any are found, it will trigger an email alert with the details.\n\nUse this to notify you when SSL action is needed."
      },
      "typeVersion": 1
    },
    {
      "id": "ff5db72e-6031-41cb-bc6f-f10ab5976acd",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        760,
        60
      ],
      "parameters": {
        "width": 260,
        "height": 440,
        "content": "\n## Send Email Alert\nThis step sends an email notification when SSL certificates are close to expiring.\nIt includes the list of affected websites and how many days are left until expiration.\n\nMake sure your email settings are properly configured to receive alerts.\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "31a10b9b-bdc0-46a2-9402-b8f16ad0c35a",
      "name": "Send Email Alert",
      "type": "n8n-nodes-base.emailSend",
      "position": [
        840,
        340
      ],
      "parameters": {
        "text": "={{ $json.message }}",
        "options": {},
        "subject": "\u26a0\ufe0f ALERT!! SSL EXPIRED",
        "toEmail": "user@example.com, user@example.com",
        "fromEmail": "user@example.com",
        "emailFormat": "text"
      },
      "credentials": {
        "smtp": {
          "name": "<your credential>"
        }
      },
      "retryOnFail": true,
      "typeVersion": 2.1
    },
    {
      "id": "d87308c9-90b4-4aef-8420-47bfa3270255",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1840,
        260
      ],
      "parameters": {
        "width": 560,
        "height": 640,
        "content": "# \ud83d\udd12 SSL Monitoring Workflow\n\u2705 What It Does:\nThis workflow automatically checks the SSL certificates of websites and alerts you if any are expiring soon (within 14 days). It helps you stay ahead of SSL issues before they cause downtime or security warnings.\n\n\u2699\ufe0f Flow:\n1. Trigger (Weekly):\nRuns every Monday at 7:00 AM to start the SSL check.\n\n2. Fetch URLs from Spreadsheet:\nReads website URLs from a spreadsheet with the following columns:\nNo, Name, Link, SSL Issued On, SSL Expired On, SSL Status\n\n3. Get SSL Status:\nUses ssl-checker.io API to fetch the SSL details (issued date, expiry date, status).\n\n4. Update Spreadsheet:\nAutomatically updates the spreadsheet with the latest SSL data.\n\n5. Check SSL Expiry:\nFilters websites with certificates expiring in 14 days or less.\n\n6. SSL Not Good?:\nIf expiring certificates are found, it triggers an alert.\n\n7. Send Email Alert:\nSends an email listing the websites that need attention.\n\n"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "9853d436-b2d3-49b5-a444-91e7c48e127d",
  "connections": {
    "Code": {
      "main": [
        [
          {
            "node": "SSL Not Good?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop": {
      "main": [
        [
          {
            "node": "Code",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Get SSL",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get SSL": {
      "main": [
        [
          {
            "node": "Update SSL in Spreadsheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "SSL Not Good?": {
      "main": [
        [
          {
            "node": "Send Email Alert",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Website List": {
      "main": [
        [
          {
            "node": "Loop",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Trigger Every Monday": {
      "main": [
        [
          {
            "node": "Get Website List",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update SSL in Spreadsheet": {
      "main": [
        [
          {
            "node": "Loop",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}