Added tg proxy, mail, mattermost
This commit is contained in:
parent
9ee043ab15
commit
454aed05fa
10 changed files with 183 additions and 60 deletions
|
|
@ -198,4 +198,9 @@ func ccCheckAndAlert(cert ccCertInfo, hostname string) {
|
||||||
} else {
|
} else {
|
||||||
log.Println("✅ Алерт успешно отправлен на Email")
|
log.Println("✅ Алерт успешно отправлен на Email")
|
||||||
}
|
}
|
||||||
|
if err := mattermostSend(message); err != nil {
|
||||||
|
log.Printf("❌ Ошибка отправки в Mattermost: %v", err)
|
||||||
|
} else {
|
||||||
|
log.Println("✅ Алерт успешно отправлен в Mattermost")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
37
config.go
37
config.go
|
|
@ -28,11 +28,14 @@ var (
|
||||||
cfgTelegramSocks5Proxy = "" // Опционально: host:port
|
cfgTelegramSocks5Proxy = "" // Опционально: host:port
|
||||||
cfgTelegramSocks5User = "" // Логин прокси (опционально)
|
cfgTelegramSocks5User = "" // Логин прокси (опционально)
|
||||||
cfgTelegramSocks5Password = "" // Пароль прокси (опционально)
|
cfgTelegramSocks5Password = "" // Пароль прокси (опционально)
|
||||||
|
cfgTelegramHTTPProxy = "" // Опционально: http://user:pass@host:port
|
||||||
)
|
)
|
||||||
|
|
||||||
// --- Mattermost ---
|
// --- Mattermost ---
|
||||||
var (
|
var (
|
||||||
cfgMattermostWebhookURL = "" // Incoming Webhook URL
|
cfgMattermostURL = "" // https://mattermost.example.com
|
||||||
|
cfgMattermostBotToken = "" // Токен бота
|
||||||
|
cfgMattermostChannelID = "" // ID канала для отправки
|
||||||
)
|
)
|
||||||
|
|
||||||
// --- Email / SMTP ---
|
// --- Email / SMTP ---
|
||||||
|
|
@ -169,6 +172,9 @@ func applyConfig(env map[string]string) {
|
||||||
if v, ok := env["TELEGRAM_SOCKS5_PASSWORD"]; ok && v != "" {
|
if v, ok := env["TELEGRAM_SOCKS5_PASSWORD"]; ok && v != "" {
|
||||||
cfgTelegramSocks5Password = v
|
cfgTelegramSocks5Password = v
|
||||||
}
|
}
|
||||||
|
if v, ok := env["TELEGRAM_HTTP_PROXY"]; ok && v != "" {
|
||||||
|
cfgTelegramHTTPProxy = v
|
||||||
|
}
|
||||||
|
|
||||||
// Database
|
// Database
|
||||||
if v, ok := env["DB_USER"]; ok && v != "" {
|
if v, ok := env["DB_USER"]; ok && v != "" {
|
||||||
|
|
@ -294,8 +300,14 @@ func applyConfig(env map[string]string) {
|
||||||
cfgEmailFrom = v
|
cfgEmailFrom = v
|
||||||
}
|
}
|
||||||
// Mattermost
|
// Mattermost
|
||||||
if v, ok := env["MATTERMOST_WEBHOOK_URL"]; ok && v != "" {
|
if v, ok := env["MATTERMOST_URL"]; ok && v != "" {
|
||||||
cfgMattermostWebhookURL = v
|
cfgMattermostURL = v
|
||||||
|
}
|
||||||
|
if v, ok := env["MATTERMOST_BOT_TOKEN"]; ok && v != "" {
|
||||||
|
cfgMattermostBotToken = v
|
||||||
|
}
|
||||||
|
if v, ok := env["MATTERMOST_CHANNEL_ID"]; ok && v != "" {
|
||||||
|
cfgMattermostChannelID = v
|
||||||
}
|
}
|
||||||
|
|
||||||
// Email / SMTP
|
// Email / SMTP
|
||||||
|
|
@ -324,7 +336,9 @@ func isTelegramConfigured() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func isMattermostConfigured() bool {
|
func isMattermostConfigured() bool {
|
||||||
return cfgMattermostWebhookURL != ""
|
return cfgMattermostURL != "" &&
|
||||||
|
cfgMattermostBotToken != "" &&
|
||||||
|
cfgMattermostChannelID != ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func isEmailConfigured() bool {
|
func isEmailConfigured() bool {
|
||||||
|
|
@ -339,13 +353,16 @@ func printConfigStatus() {
|
||||||
|
|
||||||
// Telegram
|
// Telegram
|
||||||
if isTelegramConfigured() {
|
if isTelegramConfigured() {
|
||||||
if cfgTelegramSocks5Proxy != "" {
|
switch {
|
||||||
|
case cfgTelegramSocks5Proxy != "":
|
||||||
if cfgTelegramSocks5User != "" {
|
if cfgTelegramSocks5User != "" {
|
||||||
fmt.Printf(" ✅ Telegram: настроен (прокси: %s, пользователь: %s)\n", cfgTelegramSocks5Proxy, cfgTelegramSocks5User)
|
fmt.Printf(" ✅ Telegram: настроен (SOCKS5: %s, пользователь: %s)\n", cfgTelegramSocks5Proxy, cfgTelegramSocks5User)
|
||||||
} else {
|
} else {
|
||||||
fmt.Printf(" ✅ Telegram: настроен (прокси: %s, без авторизации)\n", cfgTelegramSocks5Proxy)
|
fmt.Printf(" ✅ Telegram: настроен (SOCKS5: %s, без авторизации)\n", cfgTelegramSocks5Proxy)
|
||||||
}
|
}
|
||||||
} else {
|
case cfgTelegramHTTPProxy != "":
|
||||||
|
fmt.Printf(" ✅ Telegram: настроен (HTTP прокси: %s)\n", cfgTelegramHTTPProxy)
|
||||||
|
default:
|
||||||
fmt.Println(" ✅ Telegram: настроен (прямое соединение)")
|
fmt.Println(" ✅ Telegram: настроен (прямое соединение)")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -361,9 +378,9 @@ func printConfigStatus() {
|
||||||
|
|
||||||
// Mattermost
|
// Mattermost
|
||||||
if isMattermostConfigured() {
|
if isMattermostConfigured() {
|
||||||
fmt.Printf(" ✅ Mattermost: настроен (webhook: %s)\n", cfgMattermostWebhookURL)
|
fmt.Printf(" ✅ Mattermost: настроен (%s, channel: %s)\n", cfgMattermostURL, cfgMattermostChannelID)
|
||||||
} else {
|
} else {
|
||||||
fmt.Println(" ⚠️ Mattermost: не настроен (MATTERMOST_WEBHOOK_URL)")
|
fmt.Println(" ⚠️ Mattermost: не настроен (MATTERMOST_URL, MATTERMOST_BOT_TOKEN, MATTERMOST_CHANNEL_ID)")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Email
|
// Email
|
||||||
|
|
|
||||||
|
|
@ -507,6 +507,11 @@ func dcSendAlert(hostname string, changes []dcStateChange) {
|
||||||
} else {
|
} else {
|
||||||
log.Println("✅ Алерт успешно отправлен на Email")
|
log.Println("✅ Алерт успешно отправлен на Email")
|
||||||
}
|
}
|
||||||
|
if err := mattermostSend(message); err != nil {
|
||||||
|
log.Printf("❌ Ошибка отправки в Mattermost: %v", err)
|
||||||
|
} else {
|
||||||
|
log.Println("✅ Алерт успешно отправлен в Mattermost")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Вспомогательные функции ──────────────────────────────────────────────────
|
// ── Вспомогательные функции ──────────────────────────────────────────────────
|
||||||
|
|
|
||||||
|
|
@ -482,4 +482,9 @@ func lcSendAlerts(hostname string, staleFiles []lcLogFileStatus) {
|
||||||
} else {
|
} else {
|
||||||
log.Println("✅ Алерт успешно отправлен на Email")
|
log.Println("✅ Алерт успешно отправлен на Email")
|
||||||
}
|
}
|
||||||
|
if err := mattermostSend(message); err != nil {
|
||||||
|
log.Printf("❌ Ошибка отправки в Mattermost: %v", err)
|
||||||
|
} else {
|
||||||
|
log.Println("✅ Алерт успешно отправлен в Mattermost")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
2
main.go
2
main.go
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
const appVersion = "1.3.1"
|
const appVersion = "1.3.5"
|
||||||
|
|
||||||
// Цвета терминала (общие для всех модулей)
|
// Цвета терминала (общие для всех модулей)
|
||||||
const (
|
const (
|
||||||
|
|
|
||||||
|
|
@ -513,4 +513,9 @@ func mcSendAlerts(hostname string, stats *mcStatistics, alertList []mcAlert) {
|
||||||
} else {
|
} else {
|
||||||
fmt.Printf("%s[Email] ✓ Алерт отправлен (%d проблем)%s\n", cGreen, len(alertList), cReset)
|
fmt.Printf("%s[Email] ✓ Алерт отправлен (%d проблем)%s\n", cGreen, len(alertList), cReset)
|
||||||
}
|
}
|
||||||
|
if err := mattermostSend(sb.String()); err != nil {
|
||||||
|
fmt.Printf("%s[Mattermost] ✗ Ошибка отправки: %v%s\n", cRed, err, cReset)
|
||||||
|
} else {
|
||||||
|
fmt.Printf("%s[Mattermost] ✓ Алерт отправлен (%d проблем)%s\n", cGreen, len(alertList), cReset)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,19 +12,25 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// mattermostSend отправляет сообщение в Mattermost через Incoming Webhook.
|
// mattermostSend отправляет сообщение в Mattermost через Bot API.
|
||||||
// HTML-теги из Telegram автоматически конвертируются в Markdown.
|
// HTML-теги из Telegram автоматически конвертируются в Markdown.
|
||||||
// Если вебхук не настроен — пишет в лог и не паникует.
|
// Если бот не настроен — пишет в лог и не паникует.
|
||||||
func mattermostSend(message string) error {
|
func mattermostSend(message string) error {
|
||||||
if !isMattermostConfigured() {
|
if !isMattermostConfigured() {
|
||||||
log.Printf("[Mattermost] Не настроен (нужен MATTERMOST_WEBHOOK_URL) — пропускаем")
|
log.Printf("[Mattermost] Не настроен (нужны MATTERMOST_URL, MATTERMOST_BOT_TOKEN, MATTERMOST_CHANNEL_ID) — пропускаем")
|
||||||
return fmt.Errorf("mattermost не настроен")
|
return fmt.Errorf("mattermost не настроен")
|
||||||
}
|
}
|
||||||
|
|
||||||
mdMessage := mmHTMLToMarkdown(message)
|
mdMessage := mmHTMLToMarkdown(message)
|
||||||
|
|
||||||
payload := map[string]string{
|
type mmPost struct {
|
||||||
"text": mdMessage,
|
ChannelID string `json:"channel_id"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
}
|
||||||
|
|
||||||
|
payload := mmPost{
|
||||||
|
ChannelID: cfgMattermostChannelID,
|
||||||
|
Message: mdMessage,
|
||||||
}
|
}
|
||||||
|
|
||||||
jsonData, err := json.Marshal(payload)
|
jsonData, err := json.Marshal(payload)
|
||||||
|
|
@ -32,18 +38,27 @@ func mattermostSend(message string) error {
|
||||||
return fmt.Errorf("marshal error: %w", err)
|
return fmt.Errorf("marshal error: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("[Mattermost] Отправка вебхук: %s", cfgMattermostWebhookURL)
|
apiURL := fmt.Sprintf("%s/api/v4/posts", strings.TrimRight(cfgMattermostURL, "/"))
|
||||||
|
|
||||||
|
log.Printf("[Mattermost] Отправка: %s (channel: %s)", apiURL, cfgMattermostChannelID)
|
||||||
|
|
||||||
|
req, err := http.NewRequest("POST", apiURL, bytes.NewBuffer(jsonData))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("ошибка создания запроса: %w", err)
|
||||||
|
}
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
req.Header.Set("Authorization", "Bearer "+cfgMattermostBotToken)
|
||||||
|
|
||||||
client := &http.Client{Timeout: 15 * time.Second}
|
client := &http.Client{Timeout: 15 * time.Second}
|
||||||
resp, err := client.Post(cfgMattermostWebhookURL, "application/json", bytes.NewBuffer(jsonData))
|
resp, err := client.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("ошибка отправки в Mattermost (webhook: %s): %w", cfgMattermostWebhookURL, err)
|
return fmt.Errorf("ошибка отправки в Mattermost (%s): %w", apiURL, err)
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusCreated {
|
||||||
body, _ := io.ReadAll(resp.Body)
|
body, _ := io.ReadAll(resp.Body)
|
||||||
return fmt.Errorf("mattermost webhook error: status %d, body: %s", resp.StatusCode, string(body))
|
return fmt.Errorf("mattermost api error: status %d, body: %s", resp.StatusCode, string(body))
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
||||||
|
|
@ -531,4 +531,9 @@ func pcSendNotification(changes []string) {
|
||||||
} else {
|
} else {
|
||||||
fmt.Println("✓ Уведомление отправлено на Email")
|
fmt.Println("✓ Уведомление отправлено на Email")
|
||||||
}
|
}
|
||||||
|
if err := mattermostSend(message); err != nil {
|
||||||
|
fmt.Printf("❌ Mattermost: Ошибка отправки: %v\n", err)
|
||||||
|
} else {
|
||||||
|
fmt.Println("✓ Уведомление отправлено в Mattermost")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -318,6 +318,11 @@ func scSendAlert(hostname string, changes []scStateChange) {
|
||||||
} else {
|
} else {
|
||||||
log.Println("✅ Алерт успешно отправлен на Email")
|
log.Println("✅ Алерт успешно отправлен на Email")
|
||||||
}
|
}
|
||||||
|
if err := mattermostSend(message); err != nil {
|
||||||
|
log.Printf("❌ Ошибка отправки в Mattermost: %v", err)
|
||||||
|
} else {
|
||||||
|
log.Println("✅ Алерт успешно отправлен в Mattermost")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Вспомогательные функции ──────────────────────────────────────────────────
|
// ── Вспомогательные функции ──────────────────────────────────────────────────
|
||||||
|
|
|
||||||
139
telegram.go
139
telegram.go
|
|
@ -15,43 +15,114 @@ import (
|
||||||
"golang.org/x/net/proxy"
|
"golang.org/x/net/proxy"
|
||||||
)
|
)
|
||||||
|
|
||||||
// telegramHTTPClient возвращает http.Client — обычный или через SOCKS5 прокси.
|
// telegramHTTPClient возвращает цепочку http.Client для отправки запросов к Telegram API.
|
||||||
// Если TELEGRAM_SOCKS5_PROXY не задан — прямое соединение.
|
// Порядок попыток: HTTP прокси → SOCKS5 → прямое соединение.
|
||||||
// Логин и пароль задаются отдельными параметрами TELEGRAM_SOCKS5_USER / TELEGRAM_SOCKS5_PASSWORD
|
// Если предыдущий вариант недоступен — автоматически пробуется следующий.
|
||||||
// чтобы избежать проблем со спецсимволами при парсинге URL.
|
func telegramHTTPClients() []*http.Client {
|
||||||
func telegramHTTPClient() (*http.Client, error) {
|
|
||||||
timeout := 15 * time.Second
|
timeout := 15 * time.Second
|
||||||
|
var clients []*http.Client
|
||||||
|
|
||||||
if cfgTelegramSocks5Proxy == "" {
|
// 1. HTTP прокси
|
||||||
// Прямое соединение
|
if cfgTelegramHTTPProxy != "" {
|
||||||
return &http.Client{Timeout: timeout}, nil
|
proxyURL, err := url.Parse(cfgTelegramHTTPProxy)
|
||||||
}
|
if err != nil {
|
||||||
|
log.Printf("[Telegram] ⚠️ Некорректный адрес HTTP прокси %q: %v", cfgTelegramHTTPProxy, err)
|
||||||
var auth *proxy.Auth
|
} else {
|
||||||
if cfgTelegramSocks5User != "" {
|
clients = append(clients, &http.Client{
|
||||||
auth = &proxy.Auth{
|
Transport: &http.Transport{Proxy: http.ProxyURL(proxyURL)},
|
||||||
User: cfgTelegramSocks5User,
|
Timeout: timeout,
|
||||||
Password: cfgTelegramSocks5Password,
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dialer, err := proxy.SOCKS5("tcp", cfgTelegramSocks5Proxy, auth, proxy.Direct)
|
// 2. SOCKS5 прокси
|
||||||
if err != nil {
|
if cfgTelegramSocks5Proxy != "" {
|
||||||
return nil, fmt.Errorf("ошибка создания SOCKS5 диалера: %w", err)
|
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 {
|
||||||
|
log.Printf("[Telegram] ⚠️ Ошибка создания SOCKS5 диалера: %v", err)
|
||||||
|
} else {
|
||||||
|
clients = append(clients, &http.Client{
|
||||||
|
Transport: &http.Transport{
|
||||||
|
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
|
||||||
|
return dialer.Dial(network, addr)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Timeout: timeout,
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
transport := &http.Transport{
|
// 3. Прямое соединение — всегда последний fallback
|
||||||
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
|
clients = append(clients, &http.Client{Timeout: timeout})
|
||||||
return dialer.Dial(network, addr)
|
|
||||||
},
|
return clients
|
||||||
|
}
|
||||||
|
|
||||||
|
// telegramDoPost выполняет POST запрос перебирая доступные клиенты по порядку.
|
||||||
|
// Возвращает первый успешный ответ или последнюю ошибку если все варианты исчерпаны.
|
||||||
|
func telegramDoPost(apiURL, contentType string, body []byte) (*http.Response, error) {
|
||||||
|
clients := telegramHTTPClients()
|
||||||
|
labels := telegramClientLabels()
|
||||||
|
|
||||||
|
var lastErr error
|
||||||
|
for i, client := range clients {
|
||||||
|
resp, err := client.Post(apiURL, contentType, bytes.NewBuffer(body))
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("[Telegram] ⚠️ %s недоступен: %v", labels[i], err)
|
||||||
|
lastErr = err
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if i > 0 {
|
||||||
|
log.Printf("[Telegram] ✓ Использован fallback: %s", labels[i])
|
||||||
|
} else {
|
||||||
|
log.Printf("[Telegram] Отправка через: %s", labels[i])
|
||||||
|
}
|
||||||
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
return nil, lastErr
|
||||||
|
}
|
||||||
|
|
||||||
log.Printf("[Telegram] Используется SOCKS5 прокси: %s", cfgTelegramSocks5Proxy)
|
// telegramDoPostForm выполняет POST form запрос с перебором клиентов.
|
||||||
|
func telegramDoPostForm(apiURL string, data url.Values) (*http.Response, error) {
|
||||||
|
clients := telegramHTTPClients()
|
||||||
|
labels := telegramClientLabels()
|
||||||
|
|
||||||
return &http.Client{
|
var lastErr error
|
||||||
Transport: transport,
|
for i, client := range clients {
|
||||||
Timeout: timeout,
|
resp, err := client.PostForm(apiURL, data)
|
||||||
}, nil
|
if err != nil {
|
||||||
|
log.Printf("[Telegram] ⚠️ %s недоступен: %v", labels[i], err)
|
||||||
|
lastErr = err
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if i > 0 {
|
||||||
|
log.Printf("[Telegram] ✓ Использован fallback: %s", labels[i])
|
||||||
|
} else {
|
||||||
|
log.Printf("[Telegram] Отправка через: %s", labels[i])
|
||||||
|
}
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
|
return nil, lastErr
|
||||||
|
}
|
||||||
|
|
||||||
|
// telegramClientLabels возвращает человекочитаемые названия клиентов в том же порядке.
|
||||||
|
func telegramClientLabels() []string {
|
||||||
|
var labels []string
|
||||||
|
if cfgTelegramHTTPProxy != "" {
|
||||||
|
labels = append(labels, fmt.Sprintf("HTTP прокси (%s)", cfgTelegramHTTPProxy))
|
||||||
|
}
|
||||||
|
if cfgTelegramSocks5Proxy != "" {
|
||||||
|
labels = append(labels, fmt.Sprintf("SOCKS5 (%s)", cfgTelegramSocks5Proxy))
|
||||||
|
}
|
||||||
|
labels = append(labels, "прямое соединение")
|
||||||
|
return labels
|
||||||
}
|
}
|
||||||
|
|
||||||
// telegramSendHTML отправляет HTML-сообщение в Telegram
|
// telegramSendHTML отправляет HTML-сообщение в Telegram
|
||||||
|
|
@ -61,11 +132,6 @@ func telegramSendHTML(message string) error {
|
||||||
return fmt.Errorf("telegram не настроен")
|
return fmt.Errorf("telegram не настроен")
|
||||||
}
|
}
|
||||||
|
|
||||||
client, err := telegramHTTPClient()
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("ошибка создания HTTP клиента: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
type tgMessage struct {
|
type tgMessage struct {
|
||||||
ChatID string `json:"chat_id"`
|
ChatID string `json:"chat_id"`
|
||||||
Text string `json:"text"`
|
Text string `json:"text"`
|
||||||
|
|
@ -85,7 +151,7 @@ func telegramSendHTML(message string) error {
|
||||||
|
|
||||||
apiURL := fmt.Sprintf("https://api.telegram.org/bot%s/sendMessage", cfgTelegramBotToken)
|
apiURL := fmt.Sprintf("https://api.telegram.org/bot%s/sendMessage", cfgTelegramBotToken)
|
||||||
|
|
||||||
resp, err := client.Post(apiURL, "application/json", bytes.NewBuffer(jsonData))
|
resp, err := telegramDoPost(apiURL, "application/json", jsonData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("http error: %w", err)
|
return fmt.Errorf("http error: %w", err)
|
||||||
}
|
}
|
||||||
|
|
@ -106,18 +172,13 @@ func telegramSendPlainText(message string) error {
|
||||||
return fmt.Errorf("telegram не настроен")
|
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)
|
apiURL := fmt.Sprintf("https://api.telegram.org/bot%s/sendMessage", cfgTelegramBotToken)
|
||||||
|
|
||||||
data := url.Values{}
|
data := url.Values{}
|
||||||
data.Set("chat_id", cfgTelegramChatID)
|
data.Set("chat_id", cfgTelegramChatID)
|
||||||
data.Set("text", message)
|
data.Set("text", message)
|
||||||
|
|
||||||
resp, err := client.PostForm(apiURL, data)
|
resp, err := telegramDoPostForm(apiURL, data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("http error: %w", err)
|
return fmt.Errorf("http error: %w", err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue