diff --git a/notifiers/gotify.go b/notifiers/gotify.go new file mode 100644 index 00000000..d49ace5f --- /dev/null +++ b/notifiers/gotify.go @@ -0,0 +1,91 @@ +package notifiers + +import ( + "strings" + "time" + + "github.com/statping/statping/types/failures" + "github.com/statping/statping/types/notifications" + "github.com/statping/statping/types/notifier" + "github.com/statping/statping/types/services" + "github.com/statping/statping/utils" +) + +var _ notifier.Notifier = (*gotify)(nil) + +type gotify struct { + *notifications.Notification +} + +func (g *gotify) Select() *notifications.Notification { + return g.Notification +} + +var Gotify = &gotify{¬ifications.Notification{ + Method: "gotify", + Title: "Gotify", + Host: "https://gotify.myserver.com", + Description: "Use Gotify to receive push notifications. Add your Gotify URL and App Token to receive notifications.", + Author: "Hugo van Rijswijk", + AuthorUrl: "https://github.com/hugo-vrijswijk", + Icon: "fa dot-circle", + Delay: time.Duration(5 * time.Second), + Limits: 60, + SuccessData: `{"title": "{{.Service.Name}}", "message": "Your service '{{.Service.Name}}' is currently online!", "priority": 2}`, + FailureData: `{"title": "{{.Service.Name}}", "message": "Your service '{{.Service.Name}}' is currently failing! Reason: {{.Failure.Issue}}", "priority": 5}`, + DataType: "json", + Form: []notifications.NotificationForm{{ + Type: "text", + Title: "Gotify URL", + SmallText: "Gotify server URL, including http(s):// and port if needed", + DbField: "Host", + Required: true, + }, { + Type: "text", + Title: "App Token", + SmallText: "The Application Token generated by Gotify", + DbField: "api_key", + Required: true, + }}}, +} + +// Send will send a HTTP Post to the Gotify API. It accepts type: string +func (g *gotify) sendMessage(msg string) (string, error) { + var url string + if strings.HasSuffix(g.Host, "/") { + url = g.Host + "message" + } else { + url = g.Host + "/message" + } + + headers := []string{"X-Gotify-Key=" + g.ApiKey} + + content, _, err := utils.HttpRequest(url, "POST", "application/json", headers, strings.NewReader(msg), time.Duration(10*time.Second), true, nil) + + return string(content), err +} + +// OnFailure will trigger failing service +func (g *gotify) OnFailure(s services.Service, f failures.Failure) (string, error) { + out, err := g.sendMessage(ReplaceVars(g.FailureData, s, f)) + return out, err +} + +// OnSuccess will trigger successful service +func (g *gotify) OnSuccess(s services.Service) (string, error) { + out, err := g.sendMessage(ReplaceVars(g.SuccessData, s, failures.Failure{})) + return out, err +} + +// OnTest will test the Gotify notifier +func (g *gotify) OnTest() (string, error) { + msg := `{"title:" "Test" "message": "Testing the Gotify Notifier", "priority": 0}` + content, err := g.sendMessage(msg) + + return content, err +} + +// OnSave will trigger when this notifier is saved +func (g *gotify) OnSave() (string, error) { + return "", nil +} diff --git a/notifiers/gotify_test.go b/notifiers/gotify_test.go new file mode 100644 index 00000000..d1718629 --- /dev/null +++ b/notifiers/gotify_test.go @@ -0,0 +1,79 @@ +package notifiers + +import ( + "testing" + "time" + + "github.com/statping/statping/database" + "github.com/statping/statping/types/core" + "github.com/statping/statping/types/failures" + "github.com/statping/statping/types/notifications" + "github.com/statping/statping/types/null" + "github.com/statping/statping/types/services" + "github.com/statping/statping/utils" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +var ( + GOTIFY_URL string + GOTIFY_TOKEN string +) + +func TestGotifyNotifier(t *testing.T) { + err := utils.InitLogs() + require.Nil(t, err) + GOTIFY_URL = utils.Params.GetString("GOTIFY_URL") + GOTIFY_TOKEN = utils.Params.GetString("GOTIFY_TOKEN") + + db, err := database.OpenTester() + require.Nil(t, err) + db.AutoMigrate(¬ifications.Notification{}) + notifications.SetDB(db) + core.Example() + + if GOTIFY_URL == "" { + t.Log("gotify notifier testing skipped, missing GOTIFY_URL environment variable") + t.SkipNow() + } + if GOTIFY_TOKEN == "" { + t.Log("gotify notifier testing skipped, missing GOTIFY_TOKEN environment variable") + t.SkipNow() + } + + t.Run("Load gotify", func(t *testing.T) { + Gotify.Host = GOTIFY_URL + Gotify.Delay = time.Duration(100 * time.Millisecond) + Gotify.Enabled = null.NewNullBool(true) + + Add(Gotify) + + assert.Equal(t, "Hugo van Rijswijk", Gotify.Author) + assert.Equal(t, GOTIFY_URL, Gotify.Host) + }) + + t.Run("gotify Notifier Tester", func(t *testing.T) { + assert.True(t, Gotify.CanSend()) + }) + + t.Run("gotify Notifier Tester OnSave", func(t *testing.T) { + _, err := Gotify.OnSave() + assert.Nil(t, err) + }) + + t.Run("gotify OnFailure", func(t *testing.T) { + _, err := Gotify.OnFailure(services.Example(false), failures.Example()) + assert.Nil(t, err) + }) + + t.Run("gotify OnSuccess", func(t *testing.T) { + _, err := Gotify.OnSuccess(services.Example(true)) + assert.Nil(t, err) + }) + + t.Run("gotify Test", func(t *testing.T) { + _, err := Gotify.OnTest() + assert.Nil(t, err) + }) + +} diff --git a/notifiers/notifiers.go b/notifiers/notifiers.go index d1a74a26..f7e59dee 100644 --- a/notifiers/notifiers.go +++ b/notifiers/notifiers.go @@ -32,6 +32,7 @@ func InitNotifiers() { Mobile, Pushover, statpingMailer, + Gotify, ) }