diff --git a/common/notify/channel/channel_test.go b/common/notify/channel/channel_test.go index 79a9bdc6..bd800c59 100644 --- a/common/notify/channel/channel_test.go +++ b/common/notify/channel/channel_test.go @@ -109,7 +109,8 @@ func TestTelegramSend(t *testing.T) { InitConfig() secret := viper.GetString("notify.telegram.bot_api_key") chatID := viper.GetString("notify.telegram.chat_id") - dingTalk := channel.NewTelegram(secret, chatID) + httpProxy := viper.GetString("notify.telegram.http_proxy") + dingTalk := channel.NewTelegram(secret, chatID, httpProxy) err := dingTalk.Send(context.Background(), "Test Title", "*Test Message*") fmt.Println(err) @@ -120,7 +121,7 @@ func TestTelegramSendError(t *testing.T) { InitConfig() secret := "test" chatID := viper.GetString("notify.telegram.chat_id") - dingTalk := channel.NewTelegram(secret, chatID) + dingTalk := channel.NewTelegram(secret, chatID, "") err := dingTalk.Send(context.Background(), "Test Title", "*Test Message*") fmt.Println(err) diff --git a/common/notify/channel/telegram.go b/common/notify/channel/telegram.go index fe95e57d..9176685f 100644 --- a/common/notify/channel/telegram.go +++ b/common/notify/channel/telegram.go @@ -12,8 +12,9 @@ import ( const telegramURL = "https://api.telegram.org/bot" type Telegram struct { - secret string - chatID string + secret string + chatID string + httpProxy string } type telegramMessage struct { @@ -27,10 +28,11 @@ type telegramResponse struct { Description string `json:"description"` } -func NewTelegram(secret string, chatID string) *Telegram { +func NewTelegram(secret, chatID, httpProxy string) *Telegram { return &Telegram{ - secret: secret, - chatID: chatID, + secret: secret, + chatID: chatID, + httpProxy: httpProxy, } } @@ -43,7 +45,7 @@ func (t *Telegram) Send(ctx context.Context, title, message string) error { message = fmt.Sprintf("*%s*\n%s", title, message) messages := splitTelegramMessageIntoParts(message, maxMessageLength) - client := requester.NewHTTPRequester("", telegramErrFunc) + client := requester.NewHTTPRequester(t.httpProxy, telegramErrFunc) client.Context = ctx client.IsOpenAI = false diff --git a/common/notify/notifier.go b/common/notify/notifier.go index c70c4eb3..944d0c62 100644 --- a/common/notify/notifier.go +++ b/common/notify/notifier.go @@ -87,11 +87,12 @@ func InitPushdeerNotifier() { func InitTelegramNotifier() { bot_token := viper.GetString("notify.telegram.bot_api_key") chat_id := viper.GetString("notify.telegram.chat_id") + httpProxy := viper.GetString("notify.telegram.http_proxy") if bot_token == "" || chat_id == "" { return } - telegramNotifier := channel.NewTelegram(bot_token, chat_id) + telegramNotifier := channel.NewTelegram(bot_token, chat_id, httpProxy) AddNotifiers(telegramNotifier) common.SysLog("telegram notifier enable") diff --git a/common/telegram/common.go b/common/telegram/common.go index f49c7069..6e22c687 100644 --- a/common/telegram/common.go +++ b/common/telegram/common.go @@ -3,6 +3,8 @@ package telegram import ( "errors" "fmt" + "net/http" + "net/url" "one-api/common" "one-api/model" "strings" @@ -14,6 +16,7 @@ import ( "github.com/PaulSonOfLars/gotgbot/v2/ext/handlers/filters/callbackquery" "github.com/PaulSonOfLars/gotgbot/v2/ext/handlers/filters/message" "github.com/spf13/viper" + "golang.org/x/net/proxy" ) var TGupdater *ext.Updater @@ -35,7 +38,7 @@ func InitTelegramBot() { } var err error - TGBot, err = gotgbot.NewBot(botKey, nil) + TGBot, err = gotgbot.NewBot(botKey, getBotOpts()) if err != nil { common.SysLog("failed to create new telegram bot: " + err.Error()) return @@ -220,3 +223,53 @@ func getBindUser(b *gotgbot.Bot, ctx *ext.Context) *model.User { return user } + +func getHttpClient() (httpClient *http.Client) { + proxyAddr := viper.GetString("tg.http_proxy") // http/socks5 + if proxyAddr == "" { + return + } + + proxyURL, err := url.Parse(proxyAddr) + if err != nil { + common.SysLog("failed to parse TG proxy URL: " + err.Error()) + return + } + + switch proxyURL.Scheme { + case "http", "https": + httpClient = &http.Client{ + Transport: &http.Transport{ + Proxy: http.ProxyURL(proxyURL), + }, + } + case "socks5": + dialer, err := proxy.SOCKS5("tcp", proxyURL.Host, nil, proxy.Direct) + if err != nil { + common.SysLog("failed to create TG SOCKS5 dialer: " + err.Error()) + return + } + httpClient = &http.Client{ + Transport: &http.Transport{ + Dial: dialer.Dial, + }, + } + default: + common.SysLog("unknown TG proxy type: " + proxyAddr) + } + + return +} + +func getBotOpts() *gotgbot.BotOpts { + httpClient := getHttpClient() + if httpClient == nil { + return nil + } + + return &gotgbot.BotOpts{ + BotClient: &gotgbot.BaseBotClient{ + Client: *httpClient, + }, + } +} diff --git a/config.example.yaml b/config.example.yaml index efaebd86..1f205223 100644 --- a/config.example.yaml +++ b/config.example.yaml @@ -43,6 +43,7 @@ data_gym_cache_dir: "" tg: bot_api_key: "" # 你的 Telegram bot 的 API 密钥 webhook_secret: "" # 你的 webhook 密钥。你可以自定义这个密钥。如果设置了这个密钥,将使用webhook的方式接收消息,否则使用轮询(Polling)的方式。 + http_proxy: "" # 代理设置,格式为 "http://127.0.0.1:1080" 或 "socks5://",未设置则不使用代理。 notify: # 通知设置, 配置了几个通知方式,就会同时发送几次通知 如果不需要通知,可以删除这个配置 email: # 邮件通知 (具体stmp配置在后台设置) disable: false # 是否禁用邮件通知 @@ -61,6 +62,7 @@ notify: # 通知设置, 配置了几个通知方式,就会同时发送几次 telegram: # Telegram 通知 bot_api_key: "" # 你的 Telegram bot 的 API 密钥 chat_id: "" # 你的 Telegram chat_id + http_proxy: "" # 代理设置,格式为 "http://127.0.0.1:1080" 或 "socks5://",未设置则不使用代理。 storage: # 存储设置 (可选,主要用于图片生成,有些供应商不提供url,只能返回base64图片,设置后可以正常返回url格式的图片生成) smms: # sm.ms 图床设置 secret: "" # 你的 sm.ms API 密钥