diff --git a/bridge/bridge.go b/bridge/bridge.go index 3ee95fb..dbd7d9f 100644 --- a/bridge/bridge.go +++ b/bridge/bridge.go @@ -4,7 +4,6 @@ import ( "encoding/base64" "encoding/json" "errors" - "io" "log/slog" "net/http" "strconv" @@ -16,7 +15,7 @@ var ( ) type Handler interface { - FormatNotification(r io.Reader) (Notification, error) + ProduceNotifications(r *http.Request) ([]Notification, error) } type NotificationError struct { @@ -132,8 +131,7 @@ func (b Bridge) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } - not, err := b.h.FormatNotification(r.Body) - defer r.Body.Close() + nots, err := b.h.ProduceNotifications(r) if errors.Is(err, errSkipNotification) { w.WriteHeader(http.StatusNoContent) @@ -146,15 +144,17 @@ func (b Bridge) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } - not.topic = b.topic - not.auth = b.auth - if err = not.Send(b.baseURL); err != nil { - slog.Error("unable to send notification", "error", err) - w.WriteHeader(http.StatusInternalServerError) - return + for _, not := range nots { + not.topic = b.topic + not.auth = b.auth + if err = not.Send(b.baseURL); err != nil { + slog.Error("unable to send notification", "error", err) + w.WriteHeader(http.StatusInternalServerError) + return + } } - slog.Debug("notification sent with success") + slog.Debug("notifications sent with success", "sent", len(nots)) w.WriteHeader(http.StatusNoContent) } diff --git a/bridge/flux.go b/bridge/flux.go index 357d447..0088240 100644 --- a/bridge/flux.go +++ b/bridge/flux.go @@ -3,8 +3,8 @@ package bridge import ( "encoding/json" "fmt" - "io" "log/slog" + "net/http" "strings" "time" ) @@ -48,21 +48,22 @@ func NewFluxHandler() FluxHandler { } } -func (f FluxHandler) FormatNotification(r io.Reader) (Notification, error) { +func (f FluxHandler) ProduceNotifications(r *http.Request) ([]Notification, error) { l := slog.With(slog.String("handler", "flux")) - dec := json.NewDecoder(r) + dec := json.NewDecoder(r.Body) + defer r.Body.Close() var not FluxNotification if err := dec.Decode(¬); err != nil { - l.Error("invalid message format in flux", "error", err) - return Notification{}, err + l.Error("invalid message format", "error", err) + return nil, err } obj := not.InvolvedObject.String() if not.Reason == "ReconciliationSucceeded" { if ok := f.reconciliations[obj]; !ok { // Filter out spammy ReconciliationSucceeded notification - return Notification{}, errSkipNotification + return nil, errSkipNotification } // we will print the object so skip it next time it spam @@ -78,9 +79,9 @@ func (f FluxHandler) FormatNotification(r io.Reader) (Notification, error) { l.Debug("flux notification", slog.Group("notification", slog.String("title", title), slog.String("body", body))) - return Notification{ + return []Notification{{ Title: title, Body: body, IsMarkdown: true, - }, nil + }}, nil }