From 225508b0dc6cc350764c4eef74a65cef81edee30 Mon Sep 17 00:00:00 2001 From: shenghui kevin Date: Tue, 3 Mar 2026 07:00:38 -0800 Subject: [PATCH] feat(telegram): add proxy support Support HTTP/SOCKS5 proxy for Telegram API requests via config options: proxy = "http://proxy.example.com:8080" proxy_username = "user" # optional proxy_password = "pass" # optional Covers both bot API calls and file downloads. Follows the same pattern as the existing wecom proxy implementation. Closes #6 --- platform/telegram/telegram.go | 37 +++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/platform/telegram/telegram.go b/platform/telegram/telegram.go index 6fbe839..b5465d9 100644 --- a/platform/telegram/telegram.go +++ b/platform/telegram/telegram.go @@ -6,8 +6,10 @@ import ( "io" "log/slog" "net/http" + "net/url" "strconv" "strings" + "time" "github.com/chenhg5/cc-connect/core" @@ -24,11 +26,12 @@ type replyContext struct { } type Platform struct { - token string - allowFrom string - bot *tgbotapi.BotAPI - handler core.MessageHandler - cancel context.CancelFunc + token string + allowFrom string + bot *tgbotapi.BotAPI + httpClient *http.Client + handler core.MessageHandler + cancel context.CancelFunc } func New(opts map[string]any) (core.Platform, error) { @@ -37,7 +40,25 @@ func New(opts map[string]any) (core.Platform, error) { return nil, fmt.Errorf("telegram: token is required") } allowFrom, _ := opts["allow_from"].(string) - return &Platform{token: token, allowFrom: allowFrom}, nil + + // Build HTTP client with optional proxy support + transport := &http.Transport{} + if proxyURL, _ := opts["proxy"].(string); proxyURL != "" { + u, err := url.Parse(proxyURL) + if err != nil { + return nil, fmt.Errorf("telegram: invalid proxy URL %q: %w", proxyURL, err) + } + proxyUser, _ := opts["proxy_username"].(string) + proxyPass, _ := opts["proxy_password"].(string) + if proxyUser != "" { + u.User = url.UserPassword(proxyUser, proxyPass) + } + transport.Proxy = http.ProxyURL(u) + slog.Info("telegram: using proxy", "proxy", u.Host, "auth", proxyUser != "") + } + httpClient := &http.Client{Timeout: 60 * time.Second, Transport: transport} + + return &Platform{token: token, allowFrom: allowFrom, httpClient: httpClient}, nil } func (p *Platform) Name() string { return "telegram" } @@ -45,7 +66,7 @@ func (p *Platform) Name() string { return "telegram" } func (p *Platform) Start(handler core.MessageHandler) error { p.handler = handler - bot, err := tgbotapi.NewBotAPI(p.token) + bot, err := tgbotapi.NewBotAPIWithClient(p.token, tgbotapi.APIEndpoint, p.httpClient) if err != nil { return fmt.Errorf("telegram: auth failed: %w", err) } @@ -344,7 +365,7 @@ func (p *Platform) downloadFile(fileID string) ([]byte, error) { } link := file.Link(p.bot.Token) - resp, err := http.Get(link) + resp, err := p.httpClient.Get(link) if err != nil { return nil, fmt.Errorf("download: %w", err) }