← Back to PRs

#20420: Telegram webhook listener to use the gateway's HTTP server instead of a (broken?) own server

by kesor open 2026-02-18 22:13 View on GitHub →
docs channel: telegram gateway size: M
> implemented w/kiro-cli/auto-model(some claude or other) ## Summary Describe the problem and fix in 2–5 bullets: - Problem: Telegram webhook was running on a separate HTTP server (port `8787`), causing "`405 Method Not Allowed`" errors when reverse proxies forwarded to the gateway port (`18789`) instead. - Why it matters: Webhook mode was unusable without complex port forwarding configuration, and users naturally expected webhooks to work on the same port as the gateway. - What changed: Telegram webhooks now use the gateway's HTTP server (same port as gateway) via an HTTP registry pattern, matching how Slack webhooks work. - What did NOT change (scope boundary): Polling mode, bot API interactions, webhook secret validation, or any other channel implementations. ## Change Type (select all) - [x] Bug fix - [x] Feature - [ ] Refactor - [x] Docs - [ ] Security hardening - [ ] Chore/infra ## Scope (select all touched areas) - [x] Gateway / orchestration - [ ] Skills / tool execution - [ ] Auth / tokens - [ ] Memory / storage - [x] Integrations - [ ] API / contracts - [ ] UI / DX - [ ] CI/CD / infra ## Linked Issue/PR - Closes https://github.com/openclaw/openclaw/issues/4417 ## User-visible / Behavior Changes - Telegram webhooks now listen on the gateway port (default `18789`) instead of a separate port (`8787`) - `webhookHost` config option is now ignored (webhooks use the gateway's bind address) - Reverse proxy configuration is simpler: forward to gateway port instead of separate webhook port - Existing configurations continue to work, just need to update reverse proxy to point to gateway port ## Security Impact (required) - New permissions/capabilities? No - Secrets/tokens handling changed? No - New/changed network calls? No - Command/tool execution surface changed? No - Data access scope changed? No ## Repro + Verification ### Environment - OS: Linux NixOS 25.11 - Runtime/container: systemd - Model/provider: not relevant - Integration/channel (if any): Telegram - Relevant config (redacted): ```json { "channels": { "telegram": { "webhookUrl": "https://oc.kesor.net/telegram/webhook", "webhookSecret": "xxx", "webhookPath": "/telegram/webhook" } } } ``` ### Steps 1. Configure Telegram webhook with external URL 2. Set up reverse proxy to forward webhook requests to gateway 3. Send test message to Telegram bot 4. Check Telegram webhook info: `curl https://api.telegram.org/bot${TOKEN}/getWebhookInfo` for errors ### Expected - Telegram successfully delivers webhook POSTs to the gateway - Bot receives and processes messages - No "405 Method Not Allowed" errors ### Actual **Before fix:** - Telegram reports "`Wrong response from the webhook: 405 Method Not Allowed`" - Webhook requests fail because they're sent to gateway port (18789) but webhook server listens on separate port (`8787`) **After fix:** - Telegram successfully delivers webhooks - Bot processes messages correctly - Webhook works on gateway port as expected ## Evidence Attach at least one: - [x] Trace/log snippets **Before (Telegram webhook info):** ```json { "last_error_date": 1771445185, "last_error_message": "Wrong response from the webhook: 405 Method Not Allowed" } ``` **After:** - Telegram webhook delivers successfully - Messages processed correctly - No errors in webhook info ## Human Verification (required) What you personally verified (not just CI), and how: - Verified scenarios: - Configured Telegram webhook with external reverse proxy - Sent test messages and confirmed bot receives them - Verified webhook registration with Telegram API - Confirmed gateway logs show webhook requests being handled - Edge cases checked: - Gateway shutdown properly unregisters webhook handler - Multiple Telegram accounts (not tested, single account only) - What you did **not** verify: - Behavior with multiple Telegram accounts using different webhook paths - High-volume webhook traffic - Webhook behavior with gateway auth enabled ## Compatibility / Migration - Backward compatible? Yes - Config/env changes? No (`webhookHost` is now ignored but doesn't break) - Migration needed? Yes (reverse proxy configuration) - If yes, exact upgrade steps: 1. Update reverse proxy to forward webhook requests to gateway port (18789) instead of 8787 2. Restart gateway 3. Verify webhook works with test message ## Failure Recovery (if this breaks) - How to disable/revert this change quickly: Switch to polling mode by removing `webhookUrl` from config, or revert the commits - Files/config to restore: `src/telegram/monitor.ts`, `src/telegram/http/registry.ts`, `src/gateway/server-http.ts` - Known bad symptoms reviewers should watch for: - Webhook requests returning 404 (handler not registered) - Multiple webhook handlers conflicting on same path - Memory leak from handlers not being unregistered on shutdown ## Risks and Mitigations - Risk: Webhook handler not unregistered on channel restart, causing duplicate handlers - Mitigation: Handler unregister function is called before bot.stop() in monitor cleanup - Risk: Path conflicts if multiple Telegram accounts use same webhookPath - Mitigation: Registry checks for existing path and logs warning; first registration wins - Risk: Gateway auth might block webhook requests if not properly configured - Mitigation: Webhook routes are handled before auth checks in gateway HTTP server (same as Slack) <!-- greptile_comment --> <h3>Greptile Summary</h3> This PR moves Telegram webhook handling from a standalone HTTP server (port 8787) to the gateway's existing HTTP server, following the same HTTP registry pattern used by Slack webhooks. The new `src/telegram/http/registry.ts` mirrors `src/slack/http/registry.ts` and integrates cleanly into `server-http.ts`. - **Gateway integration**: Telegram webhooks now register on the gateway HTTP server via `registerTelegramHttpHandler`, eliminating the need for a separate port and simplifying reverse proxy configuration. - **Missing error handling in webhook handler**: The new `webhookHandler` in `monitor.ts` uses `void handled.finally(...)` but lacks a `.catch()` block — unlike the old `webhook.ts` which logged errors and sent 500 responses. Handler rejections are silently discarded, potentially leaving HTTP responses incomplete. - **Handler leak on `setWebhook` failure**: If the Telegram API `setWebhook` call fails, the HTTP handler registered via `registerTelegramHttpHandler` is never unregistered, leaving a stale route in the global map and blocking future re-registration on the same path. - **Docs inconsistency**: `webhookHost` references remain in `docs/channels/grammy.md` (line 23) and `docs/channels/telegram.md` (lines 731, 750) despite being effectively deprecated by this change. - **Test coverage gap**: The removed tests (`webhookHost` passthrough, `webhookSecret` fallback) are not replaced with equivalent tests for the new gateway-integrated webhook path. No unit test exists for `src/telegram/http/registry.ts` (the Slack equivalent has `registry.test.ts`). <h3>Confidence Score: 2/5</h3> - The handler leak and missing error handling are functional issues that should be addressed before merging. - Score of 2 reflects two logic-level issues: (1) silent error swallowing in the webhook handler can leave HTTP responses hanging, and (2) a failed setWebhook call leaks a stale handler in the global route map and prevents re-registration. Both are non-trivial in production webhook scenarios. The overall architectural approach is sound and well-aligned with existing patterns. - `src/telegram/monitor.ts` needs error handling fixes in the webhook handler and cleanup-on-failure logic for `setWebhook`. <sub>Last reviewed commit: 7080b3a</sub> <!-- greptile_other_comments_section --> <sub>(3/5) Reply to the agent's comments like "Can you suggest a fix for this @greptileai?" or ask follow-up questions!</sub> <!-- /greptile_comment -->

Most Similar PRs