91 lines
2.3 KiB
Go
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
|
|
}
|