Something went wrong. Try again.
🪺 PoP Zero is my homelab
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778package main
import ( "bytes" "context" "crypto/hmac" "crypto/rand" "crypto/sha256" "encoding/hex" "encoding/json/v2" "fmt" "log/slog" "net/http" "os" "time")
type notifier struct { url string secret string token string}
func newNotifier() (*notifier, error) { n := notifier{ url: os.Getenv("NEXTCLOUD_URL"), secret: os.Getenv("NEXTCLOUD_TALK_SECRET"), token: os.Getenv("NEXTCLOUD_TALK_TOKEN"), } if n.url == "" || n.secret == "" || n.token == "" { return nil, fmt.Errorf("NEXTCLOUD_URL, NEXTCLOUD_TALK_SECRET, and NEXTCLOUD_TALK_TOKEN are required for failure alerts") } return &n, nil}
func (n *notifier) alert(msg string) error { msg = fmt.Sprintf("backup failed: %s", msg) b, err := json.Marshal(map[string]string{"message": msg}) if err != nil { return fmt.Errorf("marshal message: %w", err) } r := make([]byte, 32) if _, err := rand.Read(r); err != nil { return fmt.Errorf("generate random: %w", err) } rand := hex.EncodeToString(r) mac := hmac.New(sha256.New, []byte(n.secret)) mac.Write([]byte(rand)) mac.Write([]byte(msg)) sig := hex.EncodeToString(mac.Sum(nil)) u := fmt.Sprintf("%s/ocs/v2.php/apps/spreed/api/v1/bot/%s/message", n.url, n.token) req, err := http.NewRequest(http.MethodPost, u, bytes.NewReader(b)) if err != nil { return fmt.Errorf("create request: %w", err) } req.Header.Set("Content-Type", "application/json") req.Header.Set("Accept", "application/json") req.Header.Set("OCS-APIRequest", "true") req.Header.Set("X-Nextcloud-Talk-Bot-Random", rand) req.Header.Set("X-Nextcloud-Talk-Bot-Signature", sig) ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() req = req.WithContext(ctx) resp, err := http.DefaultClient.Do(req) if err != nil { return fmt.Errorf("send request: %w", err) } defer func() { if err := resp.Body.Close(); err != nil { slog.Error("closing alert response body", "err", err) } }() if resp.StatusCode != http.StatusCreated { return fmt.Errorf("nextcloud returned %s", resp.Status) } return nil}