add SlackNotifier

master
Norwin 5 years ago
parent 528c9122f2
commit e9ddf63dad

@ -42,6 +42,7 @@ Run `osem_notify help config` for details and an example configuration.
`transport` | `options` `transport` | `options`
------------|------------ ------------|------------
`email` | `recipients`: list of email addresses `email` | `recipients`: list of email addresses
`slack` | -
`xmpp` | `recipients`: list of JIDs `xmpp` | `recipients`: list of JIDs
Want more? [add it](#contribute)! Want more? [add it](#contribute)!

@ -59,6 +59,10 @@ var configHelpCmd = &cobra.Command{
pass: bar pass: bar
from: hildegunst@example.com from: hildegunst@example.com
# only needed when sending notifications via Slack
slack:
webhook: https://hooks.slack.com/services/T030YPW07/xxxxxxx/xxxxxxxxxxxxxxxxxxxxxx
# only needed when sending notifications via XMPP # only needed when sending notifications via XMPP
xmpp: xmpp:
host: jabber.example.com:5222 host: jabber.example.com:5222
@ -72,6 +76,7 @@ var configHelpCmd = &cobra.Command{
transport | options transport | options
----------|------------------------------------- ----------|-------------------------------------
email | recipients: list of email addresses email | recipients: list of email addresses
slack | -
xmpp | recipients: list of JIDs xmpp | recipients: list of JIDs

@ -0,0 +1,73 @@
package core
import (
"fmt"
"io/ioutil"
"net/http"
"github.com/dghubble/sling"
"github.com/spf13/viper"
)
var slackClient = sling.New().Client(&http.Client{})
var notificationColors = map[string]string {
CheckOk: "#00ff00",
CheckErr: "#ff0000",
}
// slack Notifier has no configuration
type SlackNotifier struct {
webhook string
}
type SlackMessage struct {
Text string `json:"text"`
Username string `json:"username,omitempty`
Attachments []SlackAttachment `json:"attachments,omitempty"`
}
type SlackAttachment struct {
Text string `json:"text"`
Color string `json:"color,omitempty"`
}
func (n SlackNotifier) New(config TransportConfig) (AbstractNotifier, error) {
// validate transport configuration
// :TransportConfSourceHack
baseUrl := viper.GetString("slack.webhook")
if baseUrl == "" {
return nil, fmt.Errorf("Missing configuration key slack.webhook")
}
return SlackNotifier{
webhook: baseUrl,
}, nil
}
func (n SlackNotifier) Submit(notification Notification) error {
message := &SlackMessage{
Username: "osem_notify box healthcheck",
Text: notification.Subject,
Attachments: []SlackAttachment{ { notification.Body, notificationColors[notification.Status] } },
}
req, err := slackClient.Post(n.webhook).BodyJSON(message).Request()
if err != nil {
return err
}
c := http.Client{}
res, err2 := c.Do(req)
if err2 != nil {
return err2
}
if res.StatusCode > 200 {
defer res.Body.Close()
body, _ := ioutil.ReadAll(res.Body)
return fmt.Errorf("slack webhook failed: %s", body)
}
return nil
}

@ -8,7 +8,7 @@ import (
"github.com/spf13/viper" "github.com/spf13/viper"
) )
var client = &xmpp.Client{} // @Hacky var xmppClient = &xmpp.Client{} // @Hacky
// box config required for the XmppNotifier (TransportConfig.Options) // box config required for the XmppNotifier (TransportConfig.Options)
type XmppNotifier struct { type XmppNotifier struct {
@ -27,12 +27,12 @@ func (n XmppNotifier) New(config TransportConfig) (AbstractNotifier, error) {
// establish connection with server once, and share it accross instances // establish connection with server once, and share it accross instances
// @Hacky // @Hacky
if client.JID() == "" { if xmppClient.JID() == "" {
c, err := connectXmpp() c, err := connectXmpp()
if err != nil { if err != nil {
return nil, err return nil, err
} }
client = c xmppClient = c
} }
// assign configuration to the notifier after ensuring the correct type. // assign configuration to the notifier after ensuring the correct type.
@ -65,12 +65,12 @@ func (n XmppNotifier) New(config TransportConfig) (AbstractNotifier, error) {
} }
func (n XmppNotifier) Submit(notification Notification) error { func (n XmppNotifier) Submit(notification Notification) error {
if client.JID() == "" { if xmppClient.JID() == "" {
return fmt.Errorf("xmpp client not correctly initialized!") return fmt.Errorf("xmpp client not correctly initialized!")
} }
for _, recipient := range n.Recipients { for _, recipient := range n.Recipients {
_, err := client.Send(xmpp.Chat{ _, err := xmppClient.Send(xmpp.Chat{
Remote: recipient, Remote: recipient,
Subject: notification.Subject, Subject: notification.Subject,
Text: fmt.Sprintf("%s\n\n%s", notification.Subject, notification.Body), Text: fmt.Sprintf("%s\n\n%s", notification.Subject, notification.Body),

@ -10,6 +10,7 @@ import (
var Notifiers = map[string]AbstractNotifier{ var Notifiers = map[string]AbstractNotifier{
"email": EmailNotifier{}, "email": EmailNotifier{},
"slack": SlackNotifier{},
"xmpp": XmppNotifier{}, "xmpp": XmppNotifier{},
} }
@ -19,6 +20,7 @@ type AbstractNotifier interface {
} }
type Notification struct { type Notification struct {
Status string // one of CheckOk | CheckErr
Body string Body string
Subject string Subject string
} }
@ -137,17 +139,21 @@ func ComposeNotification(box *Box, checks []CheckResult) Notification {
resolved string resolved string
resolvedList string resolvedList string
errList string errList string
status string
) )
if len(resolvedTexts) != 0 { if len(resolvedTexts) != 0 {
resolvedList = fmt.Sprintf("Resolved issue(s):\n\n%s\n\n", strings.Join(resolvedTexts, "\n")) resolvedList = fmt.Sprintf("Resolved issue(s):\n\n%s\n\n", strings.Join(resolvedTexts, "\n"))
} }
if len(errTexts) != 0 { if len(errTexts) != 0 {
errList = fmt.Sprintf("New issue(s):\n\n%s\n\n", strings.Join(errTexts, "\n")) errList = fmt.Sprintf("New issue(s):\n\n%s\n\n", strings.Join(errTexts, "\n"))
status = CheckErr
} else { } else {
resolved = "resolved " resolved = "resolved "
status = CheckOk
} }
return Notification{ return Notification{
Status: status,
Subject: fmt.Sprintf("Issues %swith your box \"%s\" on opensensemap.org!", resolved, box.Name), Subject: fmt.Sprintf("Issues %swith your box \"%s\" on opensensemap.org!", resolved, box.Name),
Body: fmt.Sprintf("A check at %s identified the following updates for your box \"%s\":\n\n%s%sYou may visit https://opensensemap.org/explore/%s for more details.\n\n--\nSent automatically by osem_notify (https://github.com/noerw/osem_notify)", Body: fmt.Sprintf("A check at %s identified the following updates for your box \"%s\":\n\n%s%sYou may visit https://opensensemap.org/explore/%s for more details.\n\n--\nSent automatically by osem_notify (https://github.com/noerw/osem_notify)",
time.Now().Round(time.Minute), box.Name, errList, resolvedList, box.Id), time.Now().Round(time.Minute), box.Name, errList, resolvedList, box.Id),

Loading…
Cancel
Save