b9335462eb
For now the format is similar to the email receiver. Maybe switch to template usage in the future.
98 lines
2.3 KiB
Go
98 lines
2.3 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
"strings"
|
|
"time"
|
|
|
|
"git.xenrox.net/~xenrox/go-log"
|
|
"golang.org/x/text/cases"
|
|
"golang.org/x/text/language"
|
|
)
|
|
|
|
type receiver struct {
|
|
logger *log.Logger
|
|
}
|
|
|
|
type payload struct {
|
|
Status string `json:"status"`
|
|
Alerts []alert `json:"alerts"`
|
|
GroupLabels map[string]interface{} `json:"groupLabels"`
|
|
CommonLabels map[string]interface{} `json:"commonLabels"`
|
|
CommonAnnotations map[string]interface{} `json:"commonAnnotations"`
|
|
}
|
|
|
|
type alert struct {
|
|
Status string `json:"status"`
|
|
Labels map[string]interface{} `json:"labels"`
|
|
Annotations map[string]interface{} `json:"annotations"`
|
|
}
|
|
|
|
func (rcv *receiver) handleWebhooks(w http.ResponseWriter, r *http.Request) {
|
|
defer r.Body.Close()
|
|
|
|
var event payload
|
|
if err := json.NewDecoder(r.Body).Decode(&event); err != nil {
|
|
rcv.logger.Error(err)
|
|
return
|
|
}
|
|
|
|
count := len(event.Alerts)
|
|
title := fmt.Sprintf("[%s", strings.ToUpper(event.Status))
|
|
if event.Status == "firing" {
|
|
title = fmt.Sprintf("%s:%d", title, count)
|
|
}
|
|
|
|
title += "]"
|
|
for _, value := range event.GroupLabels {
|
|
title = fmt.Sprintf("%s %s", title, value)
|
|
}
|
|
|
|
var body string
|
|
c := cases.Title(language.English)
|
|
|
|
for _, alert := range event.Alerts {
|
|
alertBody := fmt.Sprintf("%s\nLabels:\n", c.String(alert.Status))
|
|
for key, value := range alert.Labels {
|
|
alertBody = fmt.Sprintf("%s%s = %s\n", alertBody, key, value)
|
|
}
|
|
|
|
alertBody += "Annotations:\n"
|
|
for key, value := range alert.Annotations {
|
|
alertBody = fmt.Sprintf("%s%s = %s\n", alertBody, key, value)
|
|
}
|
|
|
|
alertBody += "\n"
|
|
|
|
body += alertBody
|
|
}
|
|
|
|
client := &http.Client{Timeout: time.Second * 3}
|
|
url := "https://ntfy.sh/alertmanager_test"
|
|
req, err := http.NewRequest(http.MethodPost, url, strings.NewReader(body))
|
|
if err != nil {
|
|
rcv.logger.Error(err)
|
|
}
|
|
|
|
req.Header.Set("X-Title", title)
|
|
resp, err := client.Do(req)
|
|
if err != nil {
|
|
rcv.logger.Error(err)
|
|
}
|
|
|
|
defer resp.Body.Close()
|
|
if resp.StatusCode != http.StatusOK {
|
|
rcv.logger.Error("ntfy: received status code %d", resp.StatusCode)
|
|
}
|
|
}
|
|
|
|
func main() {
|
|
logger := log.NewDefaultLogger()
|
|
|
|
receiver := &receiver{logger: logger}
|
|
|
|
http.HandleFunc("/", receiver.handleWebhooks)
|
|
logger.Fatal(http.ListenAndServe("127.0.0.1:8080", nil))
|
|
}
|