auspex/telegram.go

132 lines
3.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package main
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"log"
"net"
"net/http"
"net/url"
"time"
"golang.org/x/net/proxy"
)
// telegramHTTPClient возвращает http.Client — обычный или через SOCKS5 прокси.
// Если TELEGRAM_SOCKS5_PROXY не задан — прямое соединение.
// Логин и пароль задаются отдельными параметрами TELEGRAM_SOCKS5_USER / TELEGRAM_SOCKS5_PASSWORD
// чтобы избежать проблем со спецсимволами при парсинге URL.
func telegramHTTPClient() (*http.Client, error) {
timeout := 15 * time.Second
if cfgTelegramSocks5Proxy == "" {
// Прямое соединение
return &http.Client{Timeout: timeout}, nil
}
var auth *proxy.Auth
if cfgTelegramSocks5User != "" {
auth = &proxy.Auth{
User: cfgTelegramSocks5User,
Password: cfgTelegramSocks5Password,
}
}
dialer, err := proxy.SOCKS5("tcp", cfgTelegramSocks5Proxy, auth, proxy.Direct)
if err != nil {
return nil, fmt.Errorf("ошибка создания SOCKS5 диалера: %w", err)
}
transport := &http.Transport{
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
return dialer.Dial(network, addr)
},
}
log.Printf("[Telegram] Используется SOCKS5 прокси: %s", cfgTelegramSocks5Proxy)
return &http.Client{
Transport: transport,
Timeout: timeout,
}, nil
}
// telegramSendHTML отправляет HTML-сообщение в Telegram
func telegramSendHTML(message string) error {
if !isTelegramConfigured() {
log.Printf("[Telegram] Не настроен. Сообщение:\n%s\n", message)
return fmt.Errorf("telegram не настроен")
}
client, err := telegramHTTPClient()
if err != nil {
return fmt.Errorf("ошибка создания HTTP клиента: %w", err)
}
type tgMessage struct {
ChatID string `json:"chat_id"`
Text string `json:"text"`
ParseMode string `json:"parse_mode"`
}
msg := tgMessage{
ChatID: cfgTelegramChatID,
Text: message,
ParseMode: "HTML",
}
jsonData, err := json.Marshal(msg)
if err != nil {
return fmt.Errorf("marshal error: %w", err)
}
apiURL := fmt.Sprintf("https://api.telegram.org/bot%s/sendMessage", cfgTelegramBotToken)
resp, err := client.Post(apiURL, "application/json", bytes.NewBuffer(jsonData))
if err != nil {
return fmt.Errorf("http error: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
body, _ := io.ReadAll(resp.Body)
return fmt.Errorf("telegram api error: status %d, body: %s", resp.StatusCode, string(body))
}
return nil
}
// telegramSendPlainText отправляет текстовое сообщение без форматирования
func telegramSendPlainText(message string) error {
if !isTelegramConfigured() {
log.Printf("[Telegram] Не настроен. Сообщение:\n%s\n", message)
return fmt.Errorf("telegram не настроен")
}
client, err := telegramHTTPClient()
if err != nil {
return fmt.Errorf("ошибка создания HTTP клиента: %w", err)
}
apiURL := fmt.Sprintf("https://api.telegram.org/bot%s/sendMessage", cfgTelegramBotToken)
data := url.Values{}
data.Set("chat_id", cfgTelegramChatID)
data.Set("text", message)
resp, err := client.PostForm(apiURL, data)
if err != nil {
return fmt.Errorf("http error: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
body, _ := io.ReadAll(resp.Body)
return fmt.Errorf("telegram api error: status %d, body: %s", resp.StatusCode, string(body))
}
return nil
}