diff --git a/README.md b/README.md
index b119c4c..e4ba53e 100644
--- a/README.md
+++ b/README.md
@@ -293,6 +293,32 @@ Enable E-mail notifications with this Notifier configuration:
The settings for `subject`, `smtp.port` (default to 25), `smtp.username` and `smtp.password` are optional.
+#### Mailgun notifier
+
+Enable notifications using Mailgun with this Notifier configuration:
+```js
+{
+ "type": "mailgun",
+ "apikey": "mailgun-api-key",
+ "domain": "mailgun-domain",
+ "from": "sender@example.com",
+ "to": "recipient@example.com"
+ "subject": "Custom subject line"
+}
+```
+
+#### Pushover notifier
+
+Enable notifications using Pushover with this Notifier configuration:
+```js
+{
+ "type": "pushover",
+ "token": "API_TOKEN",
+ "recipient": "USER_KEY"
+ "subject": "Custom subject line"
+}
+```
+
## Setting up storage on S3
The easiest way to do this is to give an IAM user these two privileges (keep the credentials secret):
diff --git a/go.mod b/go.mod
index 0e01477..dead54a 100644
--- a/go.mod
+++ b/go.mod
@@ -9,8 +9,10 @@ require (
github.com/fatih/color v1.9.0
github.com/google/go-github v17.0.0+incompatible
github.com/google/go-querystring v1.0.0 // indirect
+ github.com/gregdel/pushover v0.0.0-20200416074932-c8ad547caed4
github.com/jmoiron/sqlx v1.2.0
github.com/lib/pq v1.3.0
+ github.com/mailgun/mailgun-go/v4 v4.1.0
github.com/mattn/go-sqlite3 v2.0.3+incompatible
github.com/miekg/dns v1.1.29
github.com/parnurzeal/gorequest v0.2.16 // indirect
diff --git a/go.sum b/go.sum
index 80b2de4..555f9db 100644
--- a/go.sum
+++ b/go.sum
@@ -28,10 +28,15 @@ github.com/elazarl/goproxy v0.0.0-20200315184450-1f3cb6622dad h1:zPs0fNF2Io1Qytf
github.com/elazarl/goproxy v0.0.0-20200315184450-1f3cb6622dad/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM=
github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2 h1:dWB6v3RcOy03t/bUadywsbyrQwCqZeNIEX6M1OtSZOM=
github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8=
+github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64=
+github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg=
+github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0=
github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s=
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
+github.com/go-chi/chi v4.0.0+incompatible h1:SiLLEDyAkqNnw+T/uDTf3aFB9T4FTrwMpuYrgaRcnW4=
+github.com/go-chi/chi v4.0.0+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
@@ -56,6 +61,8 @@ github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
+github.com/gregdel/pushover v0.0.0-20200416074932-c8ad547caed4 h1:QZVozMeLCqyMOOhA+OuqQdNXkyu4uUQEu4+mPBB5pPQ=
+github.com/gregdel/pushover v0.0.0-20200416074932-c8ad547caed4/go.mod h1:EcaO66Nn1StkpEm1iKtBTV3d2A16SoMsVER1PthX7to=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
@@ -83,6 +90,10 @@ github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.3.0 h1:/qkRGz8zljWiDcFvgpwUpwIAPu3r07TDvs3Rws+o/pU=
github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
+github.com/mailgun/mailgun-go/v4 v4.1.0 h1:uLpVaYVGUn140doqoYoWscVnFis6x+0c8befRvXG6Z4=
+github.com/mailgun/mailgun-go/v4 v4.1.0/go.mod h1:R9kHUQBptF4iSEjhriCQizplCDwrnDShy8w/iPiOfaM=
+github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM=
+github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
@@ -102,6 +113,7 @@ github.com/parnurzeal/gorequest v0.2.16 h1:T/5x+/4BT+nj+3eSknXmCTnEVGSzFzPGdpqmU
github.com/parnurzeal/gorequest v0.2.16/go.mod h1:3Kh2QUMJoqw3icWAecsyzkpY7UzRfDhbRdTjtNwNiUE=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
diff --git a/notifier.go b/notifier.go
index 5f72ba5..17736bb 100644
--- a/notifier.go
+++ b/notifier.go
@@ -5,6 +5,8 @@ import (
"fmt"
"github.com/sourcegraph/checkup/notifier/mail"
+ "github.com/sourcegraph/checkup/notifier/mailgun"
+ "github.com/sourcegraph/checkup/notifier/pushover"
"github.com/sourcegraph/checkup/notifier/slack"
)
@@ -14,6 +16,10 @@ func notifierDecode(typeName string, config json.RawMessage) (Notifier, error) {
return mail.New(config)
case slack.Type:
return slack.New(config)
+ case mailgun.Type:
+ return mailgun.New(config)
+ case pushover.Type:
+ return pushover.New(config)
default:
return nil, fmt.Errorf(errUnknownNotifierType, typeName)
}
diff --git a/notifier/mailgun/mailgun.go b/notifier/mailgun/mailgun.go
new file mode 100644
index 0000000..7a7fe0f
--- /dev/null
+++ b/notifier/mailgun/mailgun.go
@@ -0,0 +1,67 @@
+package mailgun
+
+import (
+ "context"
+ "encoding/json"
+ "fmt"
+ "strings"
+ "time"
+
+ mailgun "github.com/mailgun/mailgun-go/v4"
+ "github.com/sourcegraph/checkup/types"
+)
+
+const Type = "mailgun"
+
+type Notifier struct {
+ APIKey string `json:"apikey"`
+ Domain string `json:"domain"`
+ From string `json:"from"`
+ To string `json:"to"`
+ Subject string `json:"subject,omitempty"`
+}
+
+func New(config json.RawMessage) (Notifier, error) {
+ var notifier Notifier
+ err := json.Unmarshal(config, ¬ifier)
+ if strings.TrimSpace(notifier.Subject) == "" {
+ notifier.Subject = "Checkup: Service Unavailable"
+ }
+ return notifier, err
+}
+
+func (Notifier) Type() string {
+ return Type
+}
+
+func (m Notifier) Notify(results []types.Result) error {
+ issues := []types.Result{}
+ for _, result := range results {
+ if !result.Healthy {
+ issues = append(issues, result)
+ }
+ }
+
+ if len(issues) == 0 {
+ return nil
+ }
+
+ mg := mailgun.NewMailgun(m.Domain, m.APIKey)
+ msg := mg.NewMessage(m.From, m.Subject, renderMessage(issues), m.To)
+
+ ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
+ defer cancel()
+
+ _, _, err := mg.Send(ctx, msg)
+ return err
+}
+
+func renderMessage(issues []types.Result) string {
+ body := []string{"Checkup has detected the following issues:", "
", "