Skip to content

Commit

Permalink
add prometheus metrics for room joining back
Browse files Browse the repository at this point in the history
fix room mapping
use format.HTMLToContent instead of our own HTMLMessage
  • Loading branch information
metskem committed Aug 31, 2024
1 parent 843405c commit e8302bc
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 26 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ require (
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.1 // indirect
github.com/tidwall/sjson v1.2.5 // indirect
github.com/yuin/goldmark v1.7.4 // indirect
go.mau.fi/util v0.7.0 // indirect
golang.org/x/crypto v0.26.0 // indirect
golang.org/x/exp v0.0.0-20240823005443-9b4947da3948 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=
github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=
github.com/yuin/goldmark v1.7.4 h1:BDXOHExt+A7gwPCJgPIIq7ENvceR7we7rOS9TNoLZeg=
github.com/yuin/goldmark v1.7.4/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E=
go.mau.fi/util v0.7.0 h1:l31z+ivrSQw+cv/9eFebEqtQW2zhxivGypn+JT0h/ws=
go.mau.fi/util v0.7.0/go.mod h1:bWYreIoTULL/UiRbZdfddPh7uWDFW5yX4YCv5FB0eE0=
golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
Expand Down
66 changes: 40 additions & 26 deletions internal/matrix/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,24 @@ import (
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"github.com/sebhoss/matrix-alertmanager-receiver/internal/config"
"html"
"log/slog"
"maunium.net/go/mautrix"
"maunium.net/go/mautrix/event"
"maunium.net/go/mautrix/format"
"maunium.net/go/mautrix/id"
"os"
"regexp"
"slices"
)

var (
joinRoomSuccessTotal = promauto.NewCounterVec(prometheus.CounterOpts{
Name: "matrix_alertmanager_receiver_join_room_success_total",
Help: "The total number of successful join room operations",
}, []string{"room"})
joinRoomFailureTotal = promauto.NewCounterVec(prometheus.CounterOpts{
Name: "matrix_alertmanager_receiver_join_room_failure_total",
Help: "The total number of failed join room operations",
}, []string{"room"})
sendSuccessTotal = promauto.NewCounter(prometheus.CounterOpts{
Name: "matrix_alertmanager_receiver_send_success_total",
Help: "The total number of successful send operations",
Expand All @@ -33,38 +41,22 @@ var (

type SendingFunc func(htmlText string, roomID string)

// An HTMLMessage is the contents of a Matrix HTML formated message event.
type HTMLMessage struct {
Body string `json:"body"`
MsgType string `json:"msgtype"`
Format string `json:"format"`
FormattedBody string `json:"formatted_body"`
}

var htmlRegex = regexp.MustCompile("<[^<]+?>")

// GetHTMLMessage returns an HTMLMessage with the body set to a stripped version of the provided HTML, in addition
// to the provided HTML.
func GetHTMLMessage(msgtype, htmlText string) HTMLMessage {
return HTMLMessage{
Body: html.UnescapeString(htmlRegex.ReplaceAllLiteralString(htmlText, "")),
MsgType: msgtype,
Format: "org.matrix.custom.html",
FormattedBody: htmlText,
}
}
var joinedRoomIDs []string

func CreatingSendingFunc(ctx context.Context, configuration config.Matrix) SendingFunc {
matrixClient := createMatrixClient(ctx, configuration)
fetchJoinedRooms(ctx, matrixClient)
return func(htmlText string, room string) {
mappedRoom := room
if mapped, ok := configuration.RoomMapping[room]; ok {
mappedRoom = mapped
}
if _, err := matrixClient.JoinRoom(ctx, mappedRoom, "", nil); err != nil {
if err := joinRoom(ctx, matrixClient, mappedRoom); err != nil {
joinRoomFailureTotal.WithLabelValues(mappedRoom).Inc()
slog.ErrorContext(ctx, fmt.Sprintf("Could not join room %s", room), slog.Any("error", err))
} else {
if respSendEvent, err := matrixClient.SendMessageEvent(ctx, id.RoomID(room), event.NewEventType("m.room.message"), GetHTMLMessage("m.text", htmlText)); err != nil {
joinRoomSuccessTotal.WithLabelValues(mappedRoom).Inc()
if respSendEvent, err := matrixClient.SendMessageEvent(ctx, id.RoomID(mappedRoom), event.NewEventType("m.room.message"), format.HTMLToContent(htmlText)); err != nil {
sendFailureTotal.Inc()
slog.ErrorContext(ctx, "Could not send message to Matrix homeserver", slog.Any("error", err))
} else {
Expand All @@ -82,8 +74,30 @@ func createMatrixClient(ctx context.Context, configuration config.Matrix) *mautr
if matrixClient, err = mautrix.NewClient(configuration.HomeServerURL, id.UserID(configuration.UserID), configuration.AccessToken); err != nil {
slog.ErrorContext(ctx, "Failed to create matrix client", slog.Any("error", err))
os.Exit(1)
} else {
slog.DebugContext(ctx, "Created Matrix client")
}
slog.DebugContext(ctx, "Created Matrix client")
return matrixClient
}

func fetchJoinedRooms(ctx context.Context, client *mautrix.Client) {
joinedRooms, err := client.JoinedRooms(ctx)
if err != nil {
slog.ErrorContext(ctx, "Could not fetch Matrix rooms", slog.Any("error", err))
os.Exit(1)
}
for _, roomID := range joinedRooms.JoinedRooms {
joinedRoomIDs = append(joinedRoomIDs, roomID.String())
}
}

func joinRoom(ctx context.Context, client *mautrix.Client, roomToJoin string) error {
if !slices.Contains(joinedRoomIDs, roomToJoin) {
slog.DebugContext(ctx, "Joining room", slog.String("room", roomToJoin))
_, err := client.JoinRoom(ctx, roomToJoin, "", nil)
if err != nil {
return err
}
joinedRoomIDs = append(joinedRoomIDs, roomToJoin)
}
return nil
}

0 comments on commit e8302bc

Please sign in to comment.