Files
worker/internal/notify/telegram.go
Gleb Tv 2c884c5612
Некоторые проверки не удались
CI / test (push) Successful in 2m5s
Docker / Build and publish worker image (push) Failing after 31s
refactor: adopt worker module path
2026-07-13 17:56:12 +03:00

67 строки
2.1 KiB
Go

package notify
import (
"fmt"
"strings"
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
"rocketgit.ru/rsmon/worker/app/models"
)
// Telegram sends a text message to the given chat ID using the given Telegram
// bot credential. chatID is the numeric Telegram chat id assigned by Telegram
// to a private chat, group or channel.
func Telegram(cred *models.NotificationCredential, chatID int64, text string) error {
if cred == nil {
return fmt.Errorf("credential is nil")
}
if cred.Kind != models.CredentialKindTelegram {
return fmt.Errorf("credential %d is not telegram (kind=%s)", cred.ID, cred.Kind)
}
token, err := cred.GetSecret()
if err != nil {
return fmt.Errorf("decrypt telegram token: %w", err)
}
if token == "" {
return fmt.Errorf("credential %d has empty token", cred.ID)
}
apiURL := ""
if cred.APIURL != nil && *cred.APIURL != "" {
apiURL = *cred.APIURL
}
bot, err := tgbotapi.NewBotAPIWithAPIEndpoint(token, telegramEndpoint(apiURL))
if err != nil {
return fmt.Errorf("init telegram bot: %w", err)
}
msg := tgbotapi.NewMessage(chatID, text)
if _, err := bot.Send(msg); err != nil {
return fmt.Errorf("send telegram via credential %d: %w", cred.ID, err)
}
return nil
}
// telegramEndpoint returns the Bot API endpoint pattern that tgbotapi expects
// (".../bot%s/%s"). If rawURL is empty, returns the default Telegram endpoint.
//
// rawURL may be a base URL with optional basic-auth credentials in the
// userinfo (https://user:pass@host/) — net/http applies the userinfo as the
// Authorization header automatically, so reverse proxies with basic auth
// work transparently.
//
// We deliberately avoid url.Parse here: it percent-encodes the literal "%"
// in "/bot%s/%s" to "/bot%25s/%25s", which makes tgbotapi's fmt.Sprintf
// produce a malformed URL (verified against the deploy.rscz.ru proxy).
// Stripping the path and appending the bot-method pattern as a string is
// both simpler and safe.
func telegramEndpoint(rawURL string) string {
if rawURL == "" {
return tgbotapi.APIEndpoint
}
return strings.TrimRight(rawURL, "/") + "/bot%s/%s"
}