Некоторые проверки не удались
CI / test (push) Successful in 2m5s
Docker / Build and publish worker image (push) Failing after 31s
67 строки
2.1 KiB
Go
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"
|
|
}
|