From 4237149180579ba66a9ff5e619505e70ceeea9ca Mon Sep 17 00:00:00 2001 From: mantrahq502 Date: Wed, 25 Feb 2026 08:49:51 +0800 Subject: [PATCH] fix(telegram): implement custom HTTP transport with TCP keepalive to prevent connection drops --- pkg/channels/telegram.go | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/pkg/channels/telegram.go b/pkg/channels/telegram.go index a0a1c8d0a..adf81f238 100644 --- a/pkg/channels/telegram.go +++ b/pkg/channels/telegram.go @@ -3,6 +3,7 @@ package channels import ( "context" "fmt" + "net" "net/http" "net/url" "os" @@ -48,25 +49,31 @@ func NewTelegramChannel(cfg *config.Config, bus *bus.MessageBus) (*TelegramChann var opts []telego.BotOption telegramCfg := cfg.Channels.Telegram + // Always use a custom transport with TCP keepalive to prevent "unexpected EOF" + // errors caused by NAT/firewall silently dropping idle long-poll connections. + transport := &http.Transport{ + DialContext: (&net.Dialer{ + Timeout: 30 * time.Second, + KeepAlive: 30 * time.Second, + }).DialContext, + IdleConnTimeout: 90 * time.Second, + TLSHandshakeTimeout: 10 * time.Second, + } + if telegramCfg.Proxy != "" { proxyURL, parseErr := url.Parse(telegramCfg.Proxy) if parseErr != nil { return nil, fmt.Errorf("invalid proxy URL %q: %w", telegramCfg.Proxy, parseErr) } - opts = append(opts, telego.WithHTTPClient(&http.Client{ - Transport: &http.Transport{ - Proxy: http.ProxyURL(proxyURL), - }, - })) + transport.Proxy = http.ProxyURL(proxyURL) } else if os.Getenv("HTTP_PROXY") != "" || os.Getenv("HTTPS_PROXY") != "" { - // Use environment proxy if configured - opts = append(opts, telego.WithHTTPClient(&http.Client{ - Transport: &http.Transport{ - Proxy: http.ProxyFromEnvironment, - }, - })) + transport.Proxy = http.ProxyFromEnvironment } + opts = append(opts, telego.WithHTTPClient(&http.Client{ + Transport: transport, + })) + bot, err := telego.NewBot(telegramCfg.Token, opts...) if err != nil { return nil, fmt.Errorf("failed to create telegram bot: %w", err)