Files
omnex/control-plane/api/internal/alerts/notifier.go
T
Xor290 c5ee5636ef
ci-api / test (push) Successful in 22m17s
ci-web / test (push) Successful in 13m44s
chore: update
2026-08-02 18:34:59 +02:00

91 lines
2.3 KiB
Go

// Package alerts : surveillance des pods des démos + notification (Discord,
// Telegram) quand une plateforme tombe en erreur ou se rétablit.
package alerts
import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"net/http"
"time"
)
// Notifier envoie un message d'alerte vers un canal externe.
type Notifier interface {
Notify(ctx context.Context, message string) error
}
// MultiNotifier diffuse vers plusieurs canaux ; une erreur sur l'un
// n'empêche pas la notification des autres.
type MultiNotifier []Notifier
func (m MultiNotifier) Notify(ctx context.Context, message string) error {
var errs []error
for _, n := range m {
if err := n.Notify(ctx, message); err != nil {
errs = append(errs, err)
}
}
return errors.Join(errs...)
}
var httpClient = &http.Client{Timeout: 10 * time.Second}
// DiscordNotifier envoie le message sur un webhook Discord.
type DiscordNotifier struct {
WebhookURL string
}
func (d *DiscordNotifier) Notify(ctx context.Context, message string) error {
body, err := json.Marshal(map[string]string{"content": message})
if err != nil {
return err
}
req, err := http.NewRequestWithContext(ctx, http.MethodPost, d.WebhookURL, bytes.NewReader(body))
if err != nil {
return err
}
req.Header.Set("Content-Type", "application/json")
resp, err := httpClient.Do(req)
if err != nil {
return fmt.Errorf("discord: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode >= 300 {
return fmt.Errorf("discord: statut %d", resp.StatusCode)
}
return nil
}
// TelegramNotifier envoie le message via un bot Telegram (sendMessage).
type TelegramNotifier struct {
BotToken string
ChatID string
}
func (t *TelegramNotifier) Notify(ctx context.Context, message string) error {
endpoint := fmt.Sprintf("https://api.telegram.org/bot%s/sendMessage", t.BotToken)
body, err := json.Marshal(map[string]string{"chat_id": t.ChatID, "text": message})
if err != nil {
return err
}
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint, bytes.NewReader(body))
if err != nil {
return err
}
req.Header.Set("Content-Type", "application/json")
resp, err := httpClient.Do(req)
if err != nil {
return fmt.Errorf("telegram: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode >= 300 {
return fmt.Errorf("telegram: statut %d", resp.StatusCode)
}
return nil
}