/
main.go
152 lines (120 loc) · 3.71 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"os"
"github.com/matrix-org/gomatrix"
"github.com/prometheus/alertmanager/template"
htmpl "html/template"
)
var messageTempl *htmpl.Template
func getMatrixMessageFor(alert template.Alert) gomatrix.HTMLMessage {
var tpl bytes.Buffer
if err := messageTempl.Execute(&tpl, alert); err != nil {
log.Fatal(err)
}
rendered := tpl.String()
return gomatrix.GetHTMLMessage("m.text", rendered)
}
func getMatrixClient(homeserver string, user string, token string, targetRoomID string) *gomatrix.Client {
log.Printf("Connecting to Matrix Homserver %v as %v.", homeserver, user)
matrixClient, err := gomatrix.NewClient(homeserver, user, token)
if err != nil {
log.Fatalf("Could not log in to Matrix Homeserver (%v): %v", homeserver, err)
}
joinedRooms, err := matrixClient.JoinedRooms()
if err != nil {
log.Fatalf("Could not fetch Matrix rooms: %v", err)
}
alreadyJoinedTarget := false
for _, roomID := range joinedRooms.JoinedRooms {
if targetRoomID == roomID {
alreadyJoinedTarget = true
}
}
if alreadyJoinedTarget {
log.Printf("%v is already part of %v.", user, targetRoomID)
} else {
log.Printf("Joining %v.", targetRoomID)
_, err := matrixClient.JoinRoom(targetRoomID, "", nil)
if err != nil {
log.Fatalf("Failed to join %v: %v", targetRoomID, err)
}
}
return matrixClient
}
func handleIncomingHooksPlain(w http.ResponseWriter, r *http.Request,
matrixClient *gomatrix.Client, targetRoomID string) {
if r.Method != http.MethodPost {
w.WriteHeader(http.StatusMethodNotAllowed)
return
}
bodyBytes, err := io.ReadAll(r.Body)
if err != nil {
log.Fatal(err)
}
log.Printf("Received valid plain hook from %v", r.RemoteAddr)
bodyString := string(bodyBytes)
log.Println(bodyString)
msg := gomatrix.GetHTMLMessage("m.text", bodyString)
_, err = matrixClient.SendMessageEvent(targetRoomID, "m.room.message", msg)
if err != nil {
log.Printf(">> Could not forward to Matrix: %v", err)
}
w.WriteHeader(http.StatusOK)
}
func handleIncomingHooks(w http.ResponseWriter, r *http.Request,
matrixClient *gomatrix.Client, targetRoomID string) {
if r.Method != http.MethodPost {
w.WriteHeader(http.StatusMethodNotAllowed)
return
}
// b, err := httputil.DumpRequest(r, true)
// if err != nil {
// log.Fatalln(err)
// }
// log.Println(string(b))
payload := template.Data{}
if err := json.NewDecoder(r.Body).Decode(&payload); err != nil {
w.WriteHeader(http.StatusBadRequest)
}
log.Printf("Received valid hook from %v", r.RemoteAddr)
for _, alert := range payload.Alerts {
msg := getMatrixMessageFor(alert)
// To also log to systlog TODO add debug variable
// log.Printf("> %v", msg.Body)
_, err := matrixClient.SendMessageEvent(targetRoomID, "m.room.message", msg)
if err != nil {
log.Printf(">> Could not forward to Matrix: %v", err)
}
}
w.WriteHeader(http.StatusOK)
}
func main() {
var err error
messageTempl, err = htmpl.ParseFiles(os.Getenv("MX_MSG_TEMPLATE"))
if err != nil {
log.Fatal(err)
}
// Initialize Matrix client.
matrixClient := getMatrixClient(
os.Getenv("MX_HOMESERVER"),
os.Getenv("MX_ID"),
os.Getenv("MX_TOKEN"),
os.Getenv("MX_ROOMID"),
)
// Initialize HTTP server.
http.HandleFunc("/alert", func(w http.ResponseWriter, r *http.Request) {
handleIncomingHooks(w, r, matrixClient, os.Getenv("MX_ROOMID"))
})
http.HandleFunc("/plain", func(w http.ResponseWriter, r *http.Request) {
handleIncomingHooksPlain(w, r, matrixClient, os.Getenv("MX_ROOMID"))
})
var listenAddr = fmt.Sprintf("%v:%v", os.Getenv("HTTP_ADDRESS"), os.Getenv("HTTP_PORT"))
log.Printf("Listening for HTTP requests (webhooks) on %v", listenAddr)
log.Fatal(http.ListenAndServe(listenAddr, nil))
}