notification-controller/internal/notifier/matrix.go

83 lines
1.8 KiB
Go

package notifier
import (
"crypto/sha1"
"encoding/json"
"fmt"
"net/http"
"net/url"
"strings"
"github.com/fluxcd/pkg/runtime/events"
"github.com/hashicorp/go-retryablehttp"
)
type Matrix struct {
Token string
URL string
RoomId string
}
type MatrixPayload struct {
Body string `json:"body"`
MsgType string `json:"msgtype"`
}
func NewMatrix(serverURL, token, roomId string) (*Matrix, error) {
_, err := url.ParseRequestURI(serverURL)
if err != nil {
return nil, fmt.Errorf("invalid Matrix homeserver URL %s", serverURL)
}
return &Matrix{
URL: serverURL,
RoomId: roomId,
Token: token,
}, nil
}
func (m *Matrix) Post(event events.Event) error {
txId, err := sha1sum(event)
if err != nil {
return fmt.Errorf("unable to generate unique tx id: %s", err)
}
fullURL := fmt.Sprintf("%s/_matrix/client/r0/rooms/%s/send/m.room.message/%s",
m.URL, m.RoomId, txId)
emoji := "💫"
if event.Severity == events.EventSeverityError {
emoji = "🚨"
}
var metadata string
for k, v := range event.Metadata {
metadata = metadata + fmt.Sprintf("- %s: %s\n", k, v)
}
heading := fmt.Sprintf("%s %s/%s.%s", emoji, strings.ToLower(event.InvolvedObject.Kind),
event.InvolvedObject.Name, event.InvolvedObject.Namespace)
msg := fmt.Sprintf("%s\n%s\n%s", heading, event.Message, metadata)
payload := MatrixPayload{
Body: msg,
MsgType: "m.text",
}
err = postMessage(fullURL, "", nil, payload, func(request *retryablehttp.Request) {
request.Method = http.MethodPut
request.Header.Add("Authorization", "Bearer "+m.Token)
})
if err != nil {
return fmt.Errorf("postMessage failed: %w", err)
}
return nil
}
func sha1sum(event events.Event) (string, error) {
val, err := json.Marshal(event)
if err != nil {
return "", err
}
digest := sha1.Sum(val)
return fmt.Sprintf("%x", digest), nil
}