fix issue 1936
This commit is contained in:
parent
c36b06a901
commit
3896b73b74
2 changed files with 78 additions and 12 deletions
|
|
@ -3,12 +3,15 @@ package telegram
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
|
"crypto/tls"
|
||||||
|
"crypto/x509"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
@ -59,23 +62,20 @@ func NewTelegramChannel(cfg *config.Config, bus *bus.MessageBus) (*TelegramChann
|
||||||
var opts []telego.BotOption
|
var opts []telego.BotOption
|
||||||
telegramCfg := cfg.Channels.Telegram
|
telegramCfg := cfg.Channels.Telegram
|
||||||
|
|
||||||
|
transport, err := telegramHTTPTransport(telegramCfg)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
opts = append(opts, telego.WithHTTPClient(&http.Client{Transport: transport}))
|
||||||
|
|
||||||
if telegramCfg.Proxy != "" {
|
if telegramCfg.Proxy != "" {
|
||||||
proxyURL, parseErr := url.Parse(telegramCfg.Proxy)
|
proxyURL, parseErr := url.Parse(telegramCfg.Proxy)
|
||||||
if parseErr != nil {
|
if parseErr != nil {
|
||||||
return nil, fmt.Errorf("invalid proxy URL %q: %w", telegramCfg.Proxy, parseErr)
|
return nil, fmt.Errorf("invalid proxy URL %q: %w", telegramCfg.Proxy, parseErr)
|
||||||
}
|
}
|
||||||
opts = append(opts, telego.WithHTTPClient(&http.Client{
|
transport.Proxy = http.ProxyURL(proxyURL)
|
||||||
Transport: &http.Transport{
|
} else {
|
||||||
Proxy: http.ProxyURL(proxyURL),
|
transport.Proxy = http.ProxyFromEnvironment
|
||||||
},
|
|
||||||
}))
|
|
||||||
} 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,
|
|
||||||
},
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if baseURL := strings.TrimRight(strings.TrimSpace(telegramCfg.BaseURL), "/"); baseURL != "" {
|
if baseURL := strings.TrimRight(strings.TrimSpace(telegramCfg.BaseURL), "/"); baseURL != "" {
|
||||||
|
|
@ -106,6 +106,69 @@ func NewTelegramChannel(cfg *config.Config, bus *bus.MessageBus) (*TelegramChann
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func telegramHTTPTransport(cfg config.TelegramConfig) (*http.Transport, error) {
|
||||||
|
// Start with Go defaults, then inject proxy + TLS tweaks.
|
||||||
|
// We keep timeouts conservative; telego itself also applies request-level timeouts.
|
||||||
|
t := &http.Transport{
|
||||||
|
Proxy: http.ProxyFromEnvironment,
|
||||||
|
}
|
||||||
|
|
||||||
|
tlsCfg, err := telegramTLSConfig(cfg)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if tlsCfg != nil {
|
||||||
|
t.TLSClientConfig = tlsCfg
|
||||||
|
}
|
||||||
|
return t, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func telegramTLSConfig(cfg config.TelegramConfig) (*tls.Config, error) {
|
||||||
|
if !cfg.TLSInsecure && strings.TrimSpace(cfg.TLSCAFile) == "" && strings.TrimSpace(cfg.TLSCADir) == "" {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
base, err := x509.SystemCertPool()
|
||||||
|
if err != nil || base == nil {
|
||||||
|
base = x509.NewCertPool()
|
||||||
|
}
|
||||||
|
|
||||||
|
if caFile := strings.TrimSpace(cfg.TLSCAFile); caFile != "" {
|
||||||
|
pemBytes, readErr := os.ReadFile(caFile)
|
||||||
|
if readErr != nil {
|
||||||
|
return nil, fmt.Errorf("telegram tls_ca_file read %q: %w", caFile, readErr)
|
||||||
|
}
|
||||||
|
if ok := base.AppendCertsFromPEM(pemBytes); !ok {
|
||||||
|
return nil, fmt.Errorf("telegram tls_ca_file %q: no certificates found", caFile)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if caDir := strings.TrimSpace(cfg.TLSCADir); caDir != "" {
|
||||||
|
entries, readErr := os.ReadDir(caDir)
|
||||||
|
if readErr != nil {
|
||||||
|
return nil, fmt.Errorf("telegram tls_ca_dir read %q: %w", caDir, readErr)
|
||||||
|
}
|
||||||
|
for _, ent := range entries {
|
||||||
|
if ent.IsDir() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// Common practice: read every file; ignore parse failures quietly to handle
|
||||||
|
// hashed symlinks / non-PEM files.
|
||||||
|
p := filepath.Join(caDir, ent.Name())
|
||||||
|
b, e := os.ReadFile(p)
|
||||||
|
if e != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
_ = base.AppendCertsFromPEM(b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &tls.Config{
|
||||||
|
RootCAs: base,
|
||||||
|
InsecureSkipVerify: cfg.TLSInsecure,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (c *TelegramChannel) Start(ctx context.Context) error {
|
func (c *TelegramChannel) Start(ctx context.Context) error {
|
||||||
logger.InfoC("telegram", "Starting Telegram bot (polling mode)...")
|
logger.InfoC("telegram", "Starting Telegram bot (polling mode)...")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -344,6 +344,9 @@ type TelegramConfig struct {
|
||||||
Token SecureString `json:"token,omitzero" yaml:"token,omitempty" env:"PICOCLAW_CHANNELS_TELEGRAM_TOKEN"`
|
Token SecureString `json:"token,omitzero" yaml:"token,omitempty" env:"PICOCLAW_CHANNELS_TELEGRAM_TOKEN"`
|
||||||
BaseURL string `json:"base_url" yaml:"-" env:"PICOCLAW_CHANNELS_TELEGRAM_BASE_URL"`
|
BaseURL string `json:"base_url" yaml:"-" env:"PICOCLAW_CHANNELS_TELEGRAM_BASE_URL"`
|
||||||
Proxy string `json:"proxy" yaml:"-" env:"PICOCLAW_CHANNELS_TELEGRAM_PROXY"`
|
Proxy string `json:"proxy" yaml:"-" env:"PICOCLAW_CHANNELS_TELEGRAM_PROXY"`
|
||||||
|
TLSCAFile string `json:"tls_ca_file,omitempty" yaml:"-" env:"PICOCLAW_CHANNELS_TELEGRAM_TLS_CA_FILE"`
|
||||||
|
TLSCADir string `json:"tls_ca_dir,omitempty" yaml:"-" env:"PICOCLAW_CHANNELS_TELEGRAM_TLS_CA_DIR"`
|
||||||
|
TLSInsecure bool `json:"tls_insecure,omitempty" yaml:"-" env:"PICOCLAW_CHANNELS_TELEGRAM_TLS_INSECURE"`
|
||||||
AllowFrom FlexibleStringSlice `json:"allow_from" yaml:"-" env:"PICOCLAW_CHANNELS_TELEGRAM_ALLOW_FROM"`
|
AllowFrom FlexibleStringSlice `json:"allow_from" yaml:"-" env:"PICOCLAW_CHANNELS_TELEGRAM_ALLOW_FROM"`
|
||||||
GroupTrigger GroupTriggerConfig `json:"group_trigger,omitempty" yaml:"-"`
|
GroupTrigger GroupTriggerConfig `json:"group_trigger,omitempty" yaml:"-"`
|
||||||
Typing TypingConfig `json:"typing,omitempty" yaml:"-"`
|
Typing TypingConfig `json:"typing,omitempty" yaml:"-"`
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue