﻿{
    "name":  "Automated SSL/Certificate Checker",
    "nodes":  [
                  {
                      "parameters":  {
                                         "rule":  {
                                                      "interval":  [
                                                                       {
                                                                           "field":  "weeks",
                                                                           "triggerAtDay":  [
                                                                                                1
                                                                                            ],
                                                                           "triggerAtHour":  9
                                                                       }
                                                                   ]
                                                  }
                                     },
                      "id":  "schedule-trigger",
                      "name":  "Schedule Trigger",
                      "type":  "n8n-nodes-base.scheduleTrigger",
                      "typeVersion":  1.2,
                      "position":  [
                                       240,
                                       304
                                   ]
                  },
                  {
                      "parameters":  {
                                         "assignments":  {
                                                             "assignments":  [
                                                                                 {
                                                                                     "id":  "domains",
                                                                                     "name":  "domains",
                                                                                     "type":  "array",
                                                                                     "value":  "=[\"proxmox\", \"homeassistant\", \"n8n\", \"uptimekuma\", \"pihole\", \"grafana\", \"vaultwarden\"]"
                                                                                 }
                                                                             ]
                                                         },
                                         "options":  {

                                                     }
                                     },
                      "id":  "set-domains",
                      "name":  "Set Domains",
                      "type":  "n8n-nodes-base.set",
                      "typeVersion":  3.4,
                      "position":  [
                                       464,
                                       304
                                   ]
                  },
                  {
                      "parameters":  {
                                         "fieldToSplitOut":  "domains",
                                         "options":  {

                                                     }
                                     },
                      "id":  "split-domains",
                      "name":  "Split Domains",
                      "type":  "n8n-nodes-base.splitOut",
                      "typeVersion":  1,
                      "position":  [
                                       688,
                                       304
                                   ]
                  },
                  {
                      "parameters":  {
                                         "method":  "POST",
                                         "url":  "http://nmap-api:3001/ssl-check",
                                         "sendBody":  true,
                                         "specifyBody":  "json",
                                         "jsonBody":  "={{ { \"host\": $json.domains, \"port\": 443, \"timeoutMs\": 5000 } }}",
                                         "options":  {
                                                         "response":  {
                                                                          "response":  {
                                                                                           "neverError":  true,
                                                                                           "responseFormat":  "json"
                                                                                       }
                                                                      },
                                                         "timeout":  20000
                                                     }
                                     },
                      "id":  "check-certificate",
                      "name":  "Check Certificate",
                      "type":  "n8n-nodes-base.httpRequest",
                      "typeVersion":  4.3,
                      "position":  [
                                       912,
                                       304
                                   ],
                      "continueOnFail":  true
                  },
                  {
                      "parameters":  {
                                         "jsCode":  "const payload = $input.first().json || {};\n\nconst data = payload \u0026\u0026 typeof payload.body === \u0027object\u0027 ? payload.body : payload;\nconst domain = String(data.host || payload.domains || payload.domain || \u0027unknown\u0027);\n\nif (!data.success || !data.certificate) {\n  return [{\n    json: {\n      domain,\n      error: String(data.error || payload.error || \u0027Certificate check failed\u0027).substring(0, 260),\n      daysRemaining: 999,\n      status: \u0027ERROR\u0027\n    }\n  }];\n}\n\nconst cert = data.certificate;\nconst expiryDate = cert.validToISO ? new Date(cert.validToISO) : new Date(cert.validTo || \u0027\u0027);\nconst daysRemaining = Number.isFinite(Number(cert.daysRemaining))\n  ? Number(cert.daysRemaining)\n  : Math.floor((expiryDate - new Date()) / (1000 * 60 * 60 * 24));\n\nreturn [{\n  json: {\n    domain,\n    expiryDate: expiryDate.toISOString(),\n    daysRemaining,\n    status: cert.status || (daysRemaining \u003c 0 ? \u0027EXPIRED\u0027 : daysRemaining \u003c 7 ? \u0027EXPIRING_SOON\u0027 : \u0027OK\u0027),\n    issuer: cert.issuer || {},\n    subject: cert.subject || {}\n  }\n}];"
                                     },
                      "id":  "parse-certificate",
                      "name":  "Parse Certificate",
                      "type":  "n8n-nodes-base.code",
                      "typeVersion":  2,
                      "position":  [
                                       1120,
                                       304
                                   ]
                  },
                  {
                      "parameters":  {
                                         "conditions":  {
                                                            "options":  {
                                                                            "leftValue":  "",
                                                                            "caseSensitive":  true,
                                                                            "typeValidation":  "strict",
                                                                            "version":  2
                                                                        },
                                                            "combinator":  "or",
                                                            "conditions":  [
                                                                               {
                                                                                   "id":  "expiring-soon",
                                                                                   "operator":  {
                                                                                                    "type":  "number",
                                                                                                    "operation":  "lt"
                                                                                                },
                                                                                   "leftValue":  "={{ $json.daysRemaining }}",
                                                                                   "rightValue":  7
                                                                               },
                                                                               {
                                                                                   "id":  "expired",
                                                                                   "operator":  {
                                                                                                    "type":  "string",
                                                                                                    "operation":  "equals"
                                                                                                },
                                                                                   "leftValue":  "={{ $json.status }}",
                                                                                   "rightValue":  "EXPIRED"
                                                                               }
                                                                           ]
                                                        },
                                         "options":  {

                                                     }
                                     },
                      "id":  "filter-expiring",
                      "name":  "Filter Expiring",
                      "type":  "n8n-nodes-base.filter",
                      "typeVersion":  2.2,
                      "position":  [
                                       1344,
                                       304
                                   ]
                  },
                  {
                      "parameters":  {
                                         "conditions":  {
                                                            "options":  {
                                                                            "leftValue":  "",
                                                                            "caseSensitive":  true,
                                                                            "typeValidation":  "strict",
                                                                            "version":  2
                                                                        },
                                                            "combinator":  "and",
                                                            "conditions":  [
                                                                               {
                                                                                   "id":  "has-items",
                                                                                   "operator":  {
                                                                                                    "type":  "number",
                                                                                                    "operation":  "gt"
                                                                                                },
                                                                                   "leftValue":  "={{ $input.all().length }}",
                                                                                   "rightValue":  0
                                                                               }
                                                                           ]
                                                        },
                                         "options":  {

                                                     }
                                     },
                      "id":  "if-has-expiring",
                      "name":  "Has Expiring Certs?",
                      "type":  "n8n-nodes-base.if",
                      "typeVersion":  2.2,
                      "position":  [
                                       1568,
                                       304
                                   ]
                  },
                  {
                      "parameters":  {
                                         "jsCode":  "const items = $input.all();\n\nlet message = \u0027SSL Certificate Alert\\n\\n\u0027;\nmessage += `Found ${items.length} certificate(s) expiring soon:\\n\\n`;\n\nfor (const item of items) {\n  const data = item.json;\n  const statusIcon = data.status === \u0027EXPIRED\u0027 ? \u0027[EXPIRED]\u0027 : \u0027[WARN]\u0027;\n  message += `${statusIcon} ${data.domain}\\n`;\n  message += `  Days remaining: ${data.daysRemaining}\\n`;\n  message += `  Expires: ${new Date(data.expiryDate).toLocaleDateString()}\\n\\n`;\n}\n\nmessage += \u0027Check and renew certificates ASAP.\u0027;\n\nreturn [{ json: { message, count: items.length } }];"
                                     },
                      "id":  "format-alert",
                      "name":  "Format Alert",
                      "type":  "n8n-nodes-base.code",
                      "typeVersion":  2,
                      "position":  [
                                       1792,
                                       208
                                   ]
                  },
                  {
                      "parameters":  {
                                         "method":  "POST",
                                         "url":  "[REDACTED]",
                                         "sendBody":  true,
                                         "specifyBody":  "json",
                                         "jsonBody":  "={\"content\": \"{{ $json.message }}\"}",
                                         "options":  {

                                                     }
                                     },
                      "id":  "send-discord",
                      "name":  "Send Discord Alert",
                      "type":  "n8n-nodes-base.httpRequest",
                      "typeVersion":  4.3,
                      "position":  [
                                       2000,
                                       112
                                   ]
                  },
                  {
                      "parameters":  {
                                         "method":  "POST",
                                         "url":  "[REDACTED]",
                                         "sendBody":  true,
                                         "specifyBody":  "json",
                                         "jsonBody":  "={\"chat_id\": \"YOUR_CHAT_ID\", \"text\": \"{{ $json.message }}\", \"parse_mode\": \"Markdown\"}",
                                         "options":  {

                                                     }
                                     },
                      "id":  "send-telegram",
                      "name":  "Send Telegram Alert",
                      "type":  "n8n-nodes-base.httpRequest",
                      "typeVersion":  4.3,
                      "position":  [
                                       2000,
                                       304
                                   ]
                  },
                  {
                      "parameters":  {

                                     },
                      "id":  "no-alert",
                      "name":  "No Alert Needed",
                      "type":  "n8n-nodes-base.noOp",
                      "typeVersion":  1,
                      "position":  [
                                       1792,
                                       400
                                   ]
                  },
                  {
                      "parameters":  {
                                         "content":  "Weekly schedule â†’ Checks SSL expiry for your services â†’ Calculates days remaining â†’ Alerts via Discord/Telegram if \u003c 7 days",
                                         "height":  80,
                                         "width":  704
                                     },
                      "type":  "n8n-nodes-base.stickyNote",
                      "position":  [
                                       704,
                                       -128
                                   ],
                      "typeVersion":  1,
                      "id":  "db405699-6e9d-433c-9327-05324a9cf553",
                      "name":  "Sticky Note"
                  }
              ],
    "pinData":  {

                },
    "connections":  {
                        "Set Domains":  {
                                            "main":  [
                                                         [
                                                             {
                                                                 "node":  "Split Domains",
                                                                 "type":  "main",
                                                                 "index":  0
                                                             }
                                                         ]
                                                     ]
                                        },
                        "Split Domains":  {
                                              "main":  [
                                                           [
                                                               {
                                                                   "node":  "Check Certificate",
                                                                   "type":  "main",
                                                                   "index":  0
                                                               }
                                                           ]
                                                       ]
                                          },
                        "Format Alert":  {
                                             "main":  [
                                                          [
                                                              {
                                                                  "node":  "Send Discord Alert",
                                                                  "type":  "main",
                                                                  "index":  0
                                                              },
                                                              {
                                                                  "node":  "Send Telegram Alert",
                                                                  "type":  "main",
                                                                  "index":  0
                                                              }
                                                          ]
                                                      ]
                                         },
                        "Filter Expiring":  {
                                                "main":  [
                                                             [
                                                                 {
                                                                     "node":  "Has Expiring Certs?",
                                                                     "type":  "main",
                                                                     "index":  0
                                                                 }
                                                             ]
                                                         ]
                                            },
                        "Schedule Trigger":  {
                                                 "main":  [
                                                              [
                                                                  {
                                                                      "node":  "Set Domains",
                                                                      "type":  "main",
                                                                      "index":  0
                                                                  }
                                                              ]
                                                          ]
                                             },
                        "Check Certificate":  {
                                                  "main":  [
                                                               [
                                                                   {
                                                                       "node":  "Parse Certificate",
                                                                       "type":  "main",
                                                                       "index":  0
                                                                   }
                                                               ]
                                                           ]
                                              },
                        "Parse Certificate":  {
                                                  "main":  [
                                                               [
                                                                   {
                                                                       "node":  "Filter Expiring",
                                                                       "type":  "main",
                                                                       "index":  0
                                                                   }
                                                               ]
                                                           ]
                                              },
                        "Has Expiring Certs?":  {
                                                    "main":  [
                                                                 [
                                                                     {
                                                                         "node":  "Format Alert",
                                                                         "type":  "main",
                                                                         "index":  0
                                                                     }
                                                                 ],
                                                                 [
                                                                     {
                                                                         "node":  "No Alert Needed",
                                                                         "type":  "main",
                                                                         "index":  0
                                                                     }
                                                                 ]
                                                             ]
                                                }
                    },
    "active":  false,
    "settings":  {
                     "executionOrder":  "v1",
                     "saveDataErrorExecution":  "all",
                     "saveDataSuccessExecution":  "all",
                     "saveManualExecutions":  true,
                     "saveExecutionProgress":  true,
                     "callerPolicy":  "workflowsFromSameOwner",
                     "availableInMCP":  false
                 },
    "versionId":  "0fa5ee10-b735-4d8a-9f29-ac1149e26fd8",
    "meta":  {
                 "instanceId":  "e09d1f0f8b9f78e80ac70b6dc8726dd263b0b6ffc4300b0eee3b58f6da316f29"
             },
    "id":  "dJplEhdzWGQU8LC7",
    "tags":  [

             ]
}
