{
  "name": "Telegram webhook health check (unboxth.xyz)",
  "nodes": [
    {
      "id": "42dc1872-9502-5083-9628-c3d688c34345",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -460,
        -460
      ],
      "parameters": {
        "content": "## Telegram webhook health check (unboxth.xyz)\n\n**What it does:** asks Telegram which webhook URL your bot is registered to (getWebhookInfo) and flags the usual n8n failures in plain English.\n\n**Setup (2 minutes):**\n1. Open **Config** and paste your bot token and your n8n public URL (the value of N8N_WEBHOOK_URL / WEBHOOK_URL, e.g. https://n8n.example.com/).\n2. Click **Execute workflow**. Read the **Diagnose** output: `healthy`, `problems`, `fixes`.\n3. Optional: publish it so the hourly **Schedule Trigger** runs, and connect an alert node (Telegram, Slack, email) to the **false** output of **Healthy?**.\n\n**Reset (only if Diagnose tells you to):** unpublish the workflow that holds your Telegram Trigger, enable **OPTIONAL deleteWebhook**, execute it once, disable it again, then publish your Telegram workflow so n8n re-registers the webhook with its secret token. Do not setWebhook to an n8n URL by hand: n8n's Telegram Trigger (v1.1+) rejects updates without the secret it set, with a 403.\n\nThe token sits in plain text in Config: keep this workflow private, and use a test bot if you share it.\nChecked against core.telegram.org/bots/api and docs.n8n.io on 4 Nov 2026.",
        "height": 420,
        "width": 700,
        "color": 5
      }
    },
    {
      "id": "b0c5be68-620e-5388-871e-13fc8b4f5685",
      "name": "Run check",
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [
        -440,
        60
      ],
      "parameters": {}
    },
    {
      "id": "fe7edf14-6173-5755-b54f-349d82632599",
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        -440,
        240
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "hours",
              "hoursInterval": 1
            }
          ]
        }
      }
    },
    {
      "id": "57cbe40e-a3fe-5bc8-ae8d-781490bb9fc5",
      "name": "Config",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        -200,
        140
      ],
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "95e9c1e2-2d45-57b0-9b96-d72f4ab2530c",
              "name": "bot_token",
              "value": "PASTE_YOUR_BOT_TOKEN",
              "type": "string"
            },
            {
              "id": "42e91aa8-fd44-56dd-86ac-9c73ff408b2e",
              "name": "n8n_public_url",
              "value": "https://n8n.example.com/",
              "type": "string"
            }
          ]
        },
        "options": {}
      }
    },
    {
      "id": "d596261e-3143-5ca9-8acf-cc9505cf5174",
      "name": "getWebhookInfo",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        40,
        60
      ],
      "parameters": {
        "url": "=https://api.telegram.org/bot{{ $json.bot_token }}/getWebhookInfo",
        "options": {
          "response": {
            "response": {
              "neverError": true
            }
          }
        }
      }
    },
    {
      "id": "34032216-550b-5222-b6d3-0a7a93dc3253",
      "name": "Diagnose",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        280,
        60
      ],
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "// unboxth.xyz: interpret Telegram getWebhookInfo for an n8n Telegram Trigger.\nconst cfg = $('Config').first().json;\nconst res = $input.first().json;\nconst problems = [];\nconst fixes = [];\nconst base = String(cfg.n8n_public_url || '').trim().replace(/\\/+$/, '');\n\nif (!res || res.ok !== true) {\n  problems.push('Telegram did not return ok:true (' + (res && (res.description || res.error_code) || 'no response') + ').');\n  fixes.push('Check the bot token in Config: paste the token only, without the word \"bot\" in front.');\n  return [{ json: { healthy: false, problems, fixes, raw: res } }];\n}\n\nconst info = res.result || {};\nconst url = info.url || '';\nconst allowedPorts = ['443', '80', '88', '8443'];\n\nif (!url) {\n  problems.push('No webhook is registered for this bot (url is empty).');\n  fixes.push('Publish the workflow that contains your Telegram Trigger. n8n calls setWebhook when it activates the trigger.');\n  fixes.push('If publishing fails, read the error: \"An HTTPS URL must be provided\" means N8N_WEBHOOK_URL / WEBHOOK_URL is missing or http.');\n} else {\n  let u = null;\n  try { u = new URL(url); } catch (e) {}\n  if (!u) {\n    problems.push('Registered URL cannot be parsed: ' + url);\n  } else {\n    if (u.protocol !== 'https:') {\n      problems.push('Registered URL is not HTTPS.');\n      fixes.push('Terminate TLS at a reverse proxy (Caddy, Traefik, nginx) or use a tunnel, set N8N_WEBHOOK_URL / WEBHOOK_URL to the https address, restart, republish.');\n    }\n    if (['localhost', '127.0.0.1', '0.0.0.0'].includes(u.hostname)) {\n      problems.push('Registered URL points at ' + u.hostname + ', which Telegram cannot reach.');\n      fixes.push('Set N8N_WEBHOOK_URL / WEBHOOK_URL to your public domain and restart n8n.');\n    }\n    const port = u.port || (u.protocol === 'https:' ? '443' : '80');\n    if (!allowedPorts.includes(port)) {\n      problems.push('Port ' + port + ' is not one Telegram supports for webhooks (443, 80, 88, 8443).');\n      fixes.push('Expose n8n through a proxy on 443 and drop the port from N8N_WEBHOOK_URL / WEBHOOK_URL.');\n    }\n    if (u.pathname.includes('/webhook-test/')) {\n      problems.push('Bot is registered to the TEST URL (/webhook-test/). Production executions will not start.');\n      fixes.push('Stop listening on the canvas, then unpublish and publish the workflow so n8n registers the /webhook/ URL again.');\n    }\n    if (base && !url.startsWith(base + '/')) {\n      problems.push('Registered URL does not start with your n8n public URL (' + base + '/).');\n      fixes.push('Another instance, an old domain or a script set this webhook. Unpublish, reset with deleteWebhook, then publish again.');\n    }\n  }\n}\n\nconst notes = [];\nconst errAgeMin = info.last_error_date ? Math.round((Date.now() / 1000 - info.last_error_date) / 60) : null;\nif (info.last_error_message && errAgeMin !== null && errAgeMin > 1440) {\n  notes.push('Old delivery error (' + Math.round(errAgeMin / 60) + ' h ago, ignored): ' + info.last_error_message);\n} else if (info.last_error_message) {\n  const ageMin = errAgeMin;\n  problems.push('Last delivery error' + (ageMin !== null ? ' (' + ageMin + ' min ago)' : '') + ': ' + info.last_error_message);\n  const m = info.last_error_message;\n  if (/403/.test(m)) fixes.push('403: the secret token does not match. Often a webhook set by hand. Unpublish, deleteWebhook, publish again.');\n  if (/404/.test(m)) fixes.push('404: nothing is listening at that path. Usually a stale test URL or an unpublished workflow.');\n  if (/certificate|SSL|TLS/i.test(m)) fixes.push('TLS problem: serve a full certificate chain (TLS 1.2+) whose name matches the domain.');\n  if (/timeout|timed out/i.test(m)) fixes.push('Timeout: Telegram cannot reach your server. Check DNS, firewall and that the proxy forwards to n8n.');\n  if (/resolve host/i.test(m)) fixes.push('DNS: the hostname in the webhook URL does not resolve publicly.');\n}\nif ((info.pending_update_count || 0) > 0 && problems.length) {\n  problems.push(info.pending_update_count + ' updates are waiting for delivery.');\n}\n\nreturn [{ json: {\n  healthy: problems.length === 0,\n  registered_url: url,\n  pending_update_count: info.pending_update_count || 0,\n  allowed_updates: info.allowed_updates || [],\n  problems,\n  fixes,\n  notes,\n  checked_at: new Date().toISOString(),\n} }];"
      }
    },
    {
      "id": "ac6bc4d4-ebea-509f-8f07-8d7f4aac46b4",
      "name": "Healthy?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        520,
        60
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "5010508a-f8f6-512f-849b-be1fd0529650",
              "leftValue": "={{ $json.healthy }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      }
    },
    {
      "id": "77ab249d-c8c5-52e2-a4ee-4a192aa37941",
      "name": "Webhook OK",
      "type": "n8n-nodes-base.noOp",
      "typeVersion": 1,
      "position": [
        760,
        -40
      ],
      "parameters": {}
    },
    {
      "id": "6b545dee-b34a-53ee-bce1-e006d9d3e367",
      "name": "Needs attention (add an alert here)",
      "type": "n8n-nodes-base.noOp",
      "typeVersion": 1,
      "position": [
        760,
        160
      ],
      "parameters": {}
    },
    {
      "id": "0525d1c9-fa99-5a83-b924-deeca394d3ec",
      "name": "OPTIONAL deleteWebhook",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        40,
        300
      ],
      "disabled": true,
      "parameters": {
        "url": "=https://api.telegram.org/bot{{ $json.bot_token }}/deleteWebhook?drop_pending_updates=false",
        "options": {
          "response": {
            "response": {
              "neverError": true
            }
          }
        }
      }
    }
  ],
  "connections": {
    "Run check": {
      "main": [
        [
          {
            "node": "Config",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "Config",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Config": {
      "main": [
        [
          {
            "node": "getWebhookInfo",
            "type": "main",
            "index": 0
          },
          {
            "node": "OPTIONAL deleteWebhook",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "getWebhookInfo": {
      "main": [
        [
          {
            "node": "Diagnose",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Diagnose": {
      "main": [
        [
          {
            "node": "Healthy?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Healthy?": {
      "main": [
        [
          {
            "node": "Webhook OK",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Needs attention (add an alert here)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "active": false,
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "tags": []
}