Add fleet ops dashboard, Calibrate enforcement, and dead-code cleanup.
Ship live alerts, pool status, AI monitor, remote agent commands, build manager, and uninstall flow; wire Calibrate settings (WS ping, pool traffic log, retention limits) at runtime and exclude server/data from git.
This commit is contained in:
83
server/internal/alerts/notify.go
Normal file
83
server/internal/alerts/notify.go
Normal file
@@ -0,0 +1,83 @@
|
||||
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)
|
||||
}
|
||||
Reference in New Issue
Block a user