xmpp-webhook

webhook to xmpp gateway (clone of https://github.com/opthomas-prime/xmpp-webhook/ with my own mods)
git clone https://git.e1e0.net/xmpp-webhook.git
Log | Files | Refs | README | LICENSE

commit edced6e71a9ca83fd275e2b6dd0af64cf146cd5f
parent b3d1e9fdf8bf8bd2d4dc3650a41a4e8c7c53f962
Author: Thomas Maier <thomas.maier@leomedia.eu>
Date:   Mon, 25 Sep 2017 17:58:44 +0200

WiP

Diffstat:
Agrafana.go | 50++++++++++++++++++++++++++++++++++++++++++++++++++
Mmain.go | 50++++++++++++++++++++++++++++++++++++++++----------
2 files changed, 90 insertions(+), 10 deletions(-)

diff --git a/grafana.go b/grafana.go @@ -0,0 +1,50 @@ +package main + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "net/http" +) + +/* +{ + "title": "My alert", + "ruleId": 1, + "ruleName": "Load peaking!", + "ruleUrl": "http://url.to.grafana/db/dashboard/my_dashboard?panelId=2", + "state": "alerting", + "imageUrl": "http://s3.image.url", + "message": "Load is peaking. Make sure the traffic is real and spin up more webfronts", + "evalMatches": [ + { + "metric": "requests", + "tags": {}, + "value": 122 + } + ] +} +*/ + +type GrafanaAlert struct { + Title string `json:"title"` + RuleName string `json:"ruleName"` + RuleUrl string `json:"ruleUrl"` + State string `json:"state"` + Message string `json:"message"` +} + +func makeGrafanaHandler(messages chan<- string) func(http.ResponseWriter, *http.Request) { + return func(w http.ResponseWriter, r *http.Request) { + body, err := ioutil.ReadAll(r.Body) + fmt.Printf("%v", string(body)) + if err == nil { + var alert GrafanaAlert + err = json.Unmarshal(body, &alert) + if err == nil { + message := alert.State + ": " + alert.Title + "/" + alert.Message + "(" + alert.RuleUrl + ")" + messages <- message + } + } + } +} diff --git a/main.go b/main.go @@ -2,19 +2,24 @@ package main import ( "log" + "net/http" "os" + "strings" "time" "github.com/emgee/go-xmpp/src/xmpp" ) const ( - envXMPPID = "XMPP_ID" - envXMPPPASS = "XMPP_PASS" - errWrongArgs = "XMPP_ID or XMPP_PASS not set" - xmppBotAnswer = "im a dumb bot" - xmppConnErr = "failed to connect " - xmppFailedPause = 30 + envXMPPID = "XMPP_ID" + envXMPPPASS = "XMPP_PASS" + envXMPPReceivers = "XMPP_RECEIVERS" + errWrongArgs = "XMPP_ID, XMPP_PASS or XMPP_RECEIVERS not set" + xmppBotAnswer = "im a dumb bot" + xmppConnErr = "failed to connect " + xmppOfflineErr = "not connected to XMPP server, dropped message" + xmppFailedPause = 30 + webHookAddr = ":4321" ) // starts xmpp session and returns the xmpp client @@ -75,9 +80,10 @@ func main() { // get xmpp credentials from ENV xi := os.Getenv(envXMPPID) xp := os.Getenv(envXMPPPASS) + xr := os.Getenv(envXMPPReceivers) - // check if xmpp credentials are supplied - if len(xi) < 1 || len(xp) < 1 { + // check if xmpp credentials and receiver list are supplied + if len(xi) < 1 || len(xp) < 1 || len(xr) < 1 { log.Fatal(errWrongArgs) } @@ -93,12 +99,36 @@ func main() { log.Print(xmppConnErr, err) time.Sleep(time.Second * time.Duration(xmppFailedPause)) } else { - // send initial presence and dispatch channels to handler + // send initial presence and dispatch channels to handler for incoming messages xc.Out <- xmpp.Presence{} handleXMPPStanza(xc.In, xc.Out) } } }() - select {} + // create channel for alerts (Webhook -> XMPP) + alertChan := make(chan string) + + // create handler for outgoing XMPP messages + go func() { + for message := range alertChan { + for _, r := range strings.Split(xr, ",") { + if xc != nil { + xc.Out <- xmpp.Message{ + To: r, + Body: xmppBodyCreate(message), + } + } else { + log.Print(xmppOfflineErr) + } + } + } + }() + + // initialize HTTP handlers with chan for alerts + grafanaHandler := makeGrafanaHandler(alertChan) + http.HandleFunc("/grafana", grafanaHandler) + + // listen for requests + http.ListenAndServe(webHookAddr, nil) }