package alerts import ( "bytes" "encoding/json" "fmt" "net/http" "net/smtp" "strings" "time" ) type NotifyConfig struct { TelegramBotToken string TelegramChatID string EmailEnabled bool SMTPHost string SMTPPort int SMTPUser string SMTPPassword string EmailTo string EmailFrom string } func SendTelegram(cfg NotifyConfig, text string) error { if cfg.TelegramBotToken == "" || cfg.TelegramChatID == "" { return nil } url := fmt.Sprintf("https://api.telegram.org/bot%s/sendMessage", cfg.TelegramBotToken) body, _ := json.Marshal(map[string]string{ "chat_id": cfg.TelegramChatID, "text": text, }) req, err := http.NewRequest(http.MethodPost, url, bytes.NewReader(body)) if err != nil { return err } req.Header.Set("Content-Type", "application/json") client := &http.Client{Timeout: 15 * time.Second} resp, err := client.Do(req) if err != nil { return err } defer resp.Body.Close() if resp.StatusCode >= 300 { return fmt.Errorf("telegram API status %d", resp.StatusCode) } return nil } func SendEmail(cfg NotifyConfig, subject, body string) error { if !cfg.EmailEnabled || cfg.SMTPHost == "" || cfg.EmailTo == "" { return nil } from := cfg.EmailFrom if from == "" { from = cfg.SMTPUser } port := cfg.SMTPPort if port <= 0 { port = 587 } addr := fmt.Sprintf("%s:%d", cfg.SMTPHost, port) msg := strings.Join([]string{ fmt.Sprintf("From: %s", from), fmt.Sprintf("To: %s", cfg.EmailTo), fmt.Sprintf("Subject: %s", subject), "MIME-Version: 1.0", "Content-Type: text/plain; charset=UTF-8", "", body, }, "\r\n") var auth smtp.Auth if cfg.SMTPUser != "" { auth = smtp.PlainAuth("", cfg.SMTPUser, cfg.SMTPPassword, cfg.SMTPHost) } return smtp.SendMail(addr, auth, from, []string{cfg.EmailTo}, []byte(msg)) } func NotifyAll(cfg NotifyConfig, subject, text string) { _ = SendTelegram(cfg, subject+": "+text) _ = SendEmail(cfg, subject, text) }