convert notifier struct values to nullstring's

pull/760/head
hunterlong 2020-07-22 12:07:42 -07:00
parent 37c8adb4d9
commit d16c2aad72
26 changed files with 172 additions and 166 deletions

View File

@ -9,6 +9,7 @@
- Modified SASS api endpoints (base, layout, forms, mixins, mobile, variables)
- Added additional testing
- Modified node version from 10.x to 12.18.2
- Modified Notifier's struct values to be NullString and NullInt to allow empty values
# 0.90.60 (07-15-2020)
- Added LETSENCRYPT_ENABLE (boolean) env to enable/disable letsencrypt SSL

View File

@ -5,6 +5,7 @@ import (
"github.com/statping/statping/types/failures"
"github.com/statping/statping/types/notifications"
"github.com/statping/statping/types/notifier"
"github.com/statping/statping/types/null"
"github.com/statping/statping/types/services"
"github.com/statping/statping/utils"
"strings"
@ -29,8 +30,8 @@ var Command = &commandLine{&notifications.Notification{
AuthorUrl: "https://github.com/hunterlong",
Delay: time.Duration(1 * time.Second),
Icon: "fas fa-terminal",
SuccessData: "/usr/bin/curl -L http://localhost:8080",
FailureData: "/usr/bin/curl -L http://localhost:8080",
SuccessData: null.NewNullString("/usr/bin/curl -L http://localhost:8080"),
FailureData: null.NewNullString("/usr/bin/curl -L http://localhost:8080"),
DataType: "text",
Limits: 60,
}}
@ -51,21 +52,21 @@ func runCommand(cmd string) (string, string, error) {
// OnSuccess for commandLine will trigger successful service
func (c *commandLine) OnSuccess(s services.Service) (string, error) {
tmpl := ReplaceVars(c.SuccessData, s, failures.Failure{})
tmpl := ReplaceVars(c.SuccessData.String, s, failures.Failure{})
out, _, err := runCommand(tmpl)
return out, err
}
// OnFailure for commandLine will trigger failing service
func (c *commandLine) OnFailure(s services.Service, f failures.Failure) (string, error) {
tmpl := ReplaceVars(c.FailureData, s, f)
tmpl := ReplaceVars(c.FailureData.String, s, f)
out, _, err := runCommand(tmpl)
return out, err
}
// OnTest for commandLine triggers when this notifier has been saved
func (c *commandLine) OnTest() (string, error) {
tmpl := ReplaceVars(c.Var1, services.Example(true), failures.Example())
tmpl := ReplaceVars(c.Var1.String, services.Example(true), failures.Example())
in, out, err := runCommand(tmpl)
utils.Log.Infoln(in)
utils.Log.Infoln(out)

View File

@ -25,9 +25,9 @@ func TestCommandNotifier(t *testing.T) {
core.Example()
t.Run("Load Command", func(t *testing.T) {
Command.Host = "/bin/echo"
Command.Var1 = "service {{.Service.Domain}} is online"
Command.Var2 = "service {{.Service.Domain}} is offline"
Command.Host = null.NewNullString("/bin/echo")
Command.Var1 = null.NewNullString("service {{.Service.Domain}} is online")
Command.Var2 = null.NewNullString("service {{.Service.Domain}} is offline")
Command.Delay = time.Duration(100 * time.Millisecond)
Command.Limits = 99
Command.Enabled = null.NewNullBool(true)

View File

@ -7,6 +7,7 @@ import (
"github.com/statping/statping/types/failures"
"github.com/statping/statping/types/notifications"
"github.com/statping/statping/types/notifier"
"github.com/statping/statping/types/null"
"github.com/statping/statping/types/services"
"github.com/statping/statping/utils"
"strings"
@ -26,10 +27,10 @@ var Discorder = &discord{&notifications.Notification{
Author: "Hunter Long",
AuthorUrl: "https://github.com/hunterlong",
Delay: time.Duration(5 * time.Second),
Host: "https://discordapp.com/api/webhooks/****/*****",
Host: null.NewNullString("https://discordapp.com/api/webhooks/****/*****"),
Icon: "fab fa-discord",
SuccessData: `{"content": "Your service '{{.Service.Name}}' is currently online!"}`,
FailureData: `{"content": "Your service '{{.Service.Name}}' is currently failing! Reason: {{.Failure.Issue}}"}`,
SuccessData: null.NewNullString(`{"content": "Your service '{{.Service.Name}}' is currently online!"}`),
FailureData: null.NewNullString(`{"content": "Your service '{{.Service.Name}}' is currently failing! Reason: {{.Failure.Issue}}"}`),
DataType: "json",
Limits: 60,
Form: []notifications.NotificationForm{{
@ -52,13 +53,13 @@ func (d *discord) Select() *notifications.Notification {
// OnFailure will trigger failing service
func (d *discord) OnFailure(s services.Service, f failures.Failure) (string, error) {
out, err := d.sendRequest(ReplaceVars(d.FailureData, s, f))
out, err := d.sendRequest(ReplaceVars(d.FailureData.String, s, f))
return out, err
}
// OnSuccess will trigger successful service
func (d *discord) OnSuccess(s services.Service) (string, error) {
out, err := d.sendRequest(ReplaceVars(d.SuccessData, s, failures.Failure{}))
out, err := d.sendRequest(ReplaceVars(d.SuccessData.String, s, failures.Failure{}))
return out, err
}
@ -66,7 +67,7 @@ func (d *discord) OnSuccess(s services.Service) (string, error) {
func (d *discord) OnTest() (string, error) {
outError := errors.New("Incorrect discord URL, please confirm URL is correct")
message := `{"content": "Testing the discord notifier"}`
contents, _, err := utils.HttpRequest(Discorder.Host, "POST", "application/json", nil, bytes.NewBuffer([]byte(message)), time.Duration(10*time.Second), true, nil)
contents, _, err := utils.HttpRequest(Discorder.Host.String, "POST", "application/json", nil, bytes.NewBuffer([]byte(message)), time.Duration(10*time.Second), true, nil)
if string(contents) == "" {
return "", nil
}

View File

@ -35,14 +35,14 @@ func TestDiscordNotifier(t *testing.T) {
}
t.Run("Load discord", func(t *testing.T) {
Discorder.Host = DISCORD_URL
Discorder.Host = null.NewNullString(DISCORD_URL)
Discorder.Delay = time.Duration(100 * time.Millisecond)
Discorder.Enabled = null.NewNullBool(true)
Add(Discorder)
assert.Equal(t, "Hunter Long", Discorder.Author)
assert.Equal(t, DISCORD_URL, Discorder.Host)
assert.Equal(t, DISCORD_URL, Discorder.Host.String)
})
t.Run("discord Notifier Tester", func(t *testing.T) {

View File

@ -90,10 +90,10 @@ func (e *emailer) OnFailure(s services.Service, f failures.Failure) (string, err
subject := fmt.Sprintf("Service %s is Offline", s.Name)
tmpl := renderEmail(s, f)
email := &emailOutgoing{
To: e.Var2,
To: e.Var2.String,
Subject: subject,
Template: tmpl,
From: e.Var1,
From: e.Var1.String,
}
return tmpl, e.dialSend(email)
}
@ -103,10 +103,10 @@ func (e *emailer) OnSuccess(s services.Service) (string, error) {
subject := fmt.Sprintf("Service %s is Back Online", s.Name)
tmpl := renderEmail(s, failures.Failure{})
email := &emailOutgoing{
To: e.Var2,
To: e.Var2.String,
Subject: subject,
Template: tmpl,
From: e.Var1,
From: e.Var1.String,
}
return tmpl, e.dialSend(email)
}
@ -140,10 +140,10 @@ func (e *emailer) OnTest() (string, error) {
service := services.Example(true)
subject := fmt.Sprintf("Service %v is Back Online", service.Name)
email := &emailOutgoing{
To: e.Var2,
To: e.Var2.String,
Subject: subject,
Template: renderEmail(service, failures.Example()),
From: e.Var1,
From: e.Var1.String,
}
return subject, e.dialSend(email)
}
@ -154,10 +154,10 @@ func (e *emailer) OnSave() (string, error) {
}
func (e *emailer) dialSend(email *emailOutgoing) error {
mailer = mail.NewDialer(e.Host, e.Port, e.Username, e.Password)
mailer = mail.NewDialer(e.Host.String, int(e.Port.Int64), e.Username.String, e.Password.String)
m := mail.NewMessage()
// if email setting TLS is Disabled
if e.ApiKey == "true" {
if e.ApiKey.String == "true" {
mailer.SSL = false
} else {
mailer.TLSConfig = &tls.Config{InsecureSkipVerify: true}

View File

@ -46,18 +46,18 @@ func TestEmailNotifier(t *testing.T) {
}
t.Run("New email", func(t *testing.T) {
email.Host = EMAIL_HOST
email.Username = EMAIL_USER
email.Password = EMAIL_PASS
email.Var1 = EMAIL_OUTGOING
email.Var2 = EMAIL_SEND_TO
email.Port = int(EMAIL_PORT)
email.Host = null.NewNullString(EMAIL_HOST)
email.Username = null.NewNullString(EMAIL_USER)
email.Password = null.NewNullString(EMAIL_PASS)
email.Var1 = null.NewNullString(EMAIL_OUTGOING)
email.Var2 = null.NewNullString(EMAIL_SEND_TO)
email.Port = null.NewNullInt64(EMAIL_PORT)
email.Delay = time.Duration(100 * time.Millisecond)
email.Enabled = null.NewNullBool(true)
Add(email)
assert.Equal(t, "Hunter Long", email.Author)
assert.Equal(t, EMAIL_HOST, email.Host)
assert.Equal(t, EMAIL_HOST, email.Host.String)
})
t.Run("email Within Limits", func(t *testing.T) {

View File

@ -1,6 +1,7 @@
package notifiers
import (
"github.com/statping/statping/types/null"
"strings"
"time"
@ -30,8 +31,8 @@ var Gotify = &gotify{&notifications.Notification{
Icon: "broadcast-tower",
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}`,
SuccessData: null.NewNullString(`{"title": "{{.Service.Name}}", "message": "Your service '{{.Service.Name}}' is currently online!", "priority": 2}`),
FailureData: null.NewNullString(`{"title": "{{.Service.Name}}", "message": "Your service '{{.Service.Name}}' is currently failing! Reason: {{.Failure.Issue}}", "priority": 5}`),
DataType: "json",
Form: []notifications.NotificationForm{{
Type: "text",
@ -53,13 +54,13 @@ var Gotify = &gotify{&notifications.Notification{
// 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"
if strings.HasSuffix(g.Host.String, "/") {
url = g.Host.String + "message"
} else {
url = g.Host + "/message"
url = g.Host.String + "/message"
}
headers := []string{"X-Gotify-Key=" + g.ApiKey}
headers := []string{"X-Gotify-Key=" + g.ApiKey.String}
content, _, err := utils.HttpRequest(url, "POST", "application/json", headers, strings.NewReader(msg), time.Duration(10*time.Second), true, nil)
@ -68,13 +69,13 @@ func (g *gotify) sendMessage(msg string) (string, error) {
// 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))
out, err := g.sendMessage(ReplaceVars(g.FailureData.String, 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{}))
out, err := g.sendMessage(ReplaceVars(g.SuccessData.String, s, failures.Failure{}))
return out, err
}

View File

@ -42,14 +42,14 @@ func TestGotifyNotifier(t *testing.T) {
}
t.Run("Load gotify", func(t *testing.T) {
Gotify.Host = GOTIFY_URL
Gotify.Host = null.NewNullString(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)
assert.Equal(t, GOTIFY_URL, Gotify.Host.String)
})
t.Run("gotify Notifier Tester", func(t *testing.T) {

View File

@ -93,7 +93,7 @@ func (m *mobilePush) OnTest() (string, error) {
msg := &pushArray{
Message: "Testing the Mobile Notifier",
Title: "Testing Notifications",
Tokens: []string{m.Var1},
Tokens: []string{m.Var1.String},
Platform: 2,
}
body, err := pushRequest(msg)
@ -115,7 +115,7 @@ func (m *mobilePush) OnTest() (string, error) {
// Send will send message to Statping push notifications endpoint
func (m *mobilePush) Send(pushMessage *pushArray) error {
pushMessage.Tokens = []string{m.Var1}
pushMessage.Tokens = []string{m.Var1.String}
pushMessage.Platform = utils.ToInt(m.Var2)
_, err := pushRequest(pushMessage)
if err != nil {

View File

@ -24,7 +24,12 @@ func TestMobileNotifier(t *testing.T) {
require.Nil(t, err)
mobileToken = utils.Params.GetString("MOBILE_TOKEN")
Mobile.Var1 = mobileToken
if mobileToken == "" {
t.Log("Mobile notifier testing skipped, missing MOBILE_ID environment variable")
t.SkipNow()
}
Mobile.Var1 = null.NewNullString(mobileToken)
db, err := database.OpenTester()
require.Nil(t, err)
@ -32,14 +37,8 @@ func TestMobileNotifier(t *testing.T) {
notifications.SetDB(db)
core.Example()
Mobile.Var1 = mobileToken
if mobileToken == "" {
t.Log("Mobile notifier testing skipped, missing MOBILE_ID environment variable")
t.SkipNow()
}
t.Run("Load Mobile", func(t *testing.T) {
Mobile.Var1 = mobileToken
Mobile.Var1 = null.NewNullString(mobileToken)
Mobile.Delay = time.Duration(100 * time.Millisecond)
Mobile.Limits = 10
Mobile.Enabled = null.NewNullBool(true)

View File

@ -5,6 +5,7 @@ import (
"github.com/statping/statping/types/failures"
"github.com/statping/statping/types/notifications"
"github.com/statping/statping/types/notifier"
"github.com/statping/statping/types/null"
"github.com/statping/statping/types/services"
"github.com/statping/statping/utils"
"net/url"
@ -35,8 +36,8 @@ var Pushover = &pushover{&notifications.Notification{
Icon: "fa dot-circle",
Delay: time.Duration(10 * time.Second),
Limits: 60,
SuccessData: `Your service '{{.Service.Name}}' is currently online!`,
FailureData: `Your service '{{.Service.Name}}' is currently offline!`,
SuccessData: null.NewNullString(`Your service '{{.Service.Name}}' is currently online!`),
FailureData: null.NewNullString(`Your service '{{.Service.Name}}' is currently offline!`),
DataType: "text",
Form: []notifications.NotificationForm{{
Type: "text",
@ -88,12 +89,12 @@ func priority(val string) string {
// Send will send a HTTP Post to the Pushover API. It accepts type: string
func (t *pushover) sendMessage(message string) (string, error) {
v := url.Values{}
v.Set("token", t.ApiSecret)
v.Set("user", t.ApiKey)
v.Set("token", t.ApiSecret.String)
v.Set("user", t.ApiKey.String)
v.Set("message", message)
v.Set("priority", priority(t.Var1))
if t.Var2 != "" {
v.Set("sound", t.Var2)
v.Set("priority", priority(t.Var1.String))
if t.Var2.String != "" {
v.Set("sound", t.Var2.String)
}
rb := strings.NewReader(v.Encode())
@ -106,14 +107,14 @@ func (t *pushover) sendMessage(message string) (string, error) {
// OnFailure will trigger failing service
func (t *pushover) OnFailure(s services.Service, f failures.Failure) (string, error) {
message := ReplaceVars(t.FailureData, s, f)
message := ReplaceVars(t.FailureData.String, s, f)
out, err := t.sendMessage(message)
return out, err
}
// OnSuccess will trigger successful service
func (t *pushover) OnSuccess(s services.Service) (string, error) {
message := ReplaceVars(t.SuccessData, s, failures.Failure{})
message := ReplaceVars(t.SuccessData.String, s, failures.Failure{})
out, err := t.sendMessage(message)
return out, err
}

View File

@ -37,10 +37,10 @@ func TestPushoverNotifier(t *testing.T) {
}
t.Run("Load Pushover", func(t *testing.T) {
Pushover.ApiKey = PUSHOVER_TOKEN
Pushover.ApiSecret = PUSHOVER_API
Pushover.Var1 = "Normal"
Pushover.Var2 = "vibrate"
Pushover.ApiKey = null.NewNullString(PUSHOVER_TOKEN)
Pushover.ApiSecret = null.NewNullString(PUSHOVER_API)
Pushover.Var1 = null.NewNullString("Normal")
Pushover.Var2 = null.NewNullString("vibrate")
Pushover.Enabled = null.NewNullBool(true)
Add(Pushover)

View File

@ -6,6 +6,7 @@ import (
"github.com/statping/statping/types/failures"
"github.com/statping/statping/types/notifications"
"github.com/statping/statping/types/notifier"
"github.com/statping/statping/types/null"
"github.com/statping/statping/types/services"
"github.com/statping/statping/utils"
"strings"
@ -33,10 +34,10 @@ var slacker = &slack{&notifications.Notification{
Author: "Hunter Long",
AuthorUrl: "https://github.com/hunterlong",
Delay: time.Duration(10 * time.Second),
Host: "https://webhooksurl.slack.com/***",
Host: null.NewNullString("https://webhooksurl.slack.com/***"),
Icon: "fab fa-slack",
SuccessData: `{ "blocks": [ { "type": "section", "text": { "type": "mrkdwn", "text": "The service {{.Service.Name}} is back online." } }, { "type": "actions", "elements": [ { "type": "button", "text": { "type": "plain_text", "text": "View Service", "emoji": true }, "style": "primary", "url": "{{.Core.Domain}}/service/{{.Service.Id}}" }, { "type": "button", "text": { "type": "plain_text", "text": "Go to Statping", "emoji": true }, "url": "{{.Core.Domain}}" } ] } ] }`,
FailureData: `{ "blocks": [ { "type": "section", "text": { "type": "mrkdwn", "text": ":warning: The service {{.Service.Name}} is currently offline! :warning:" } }, { "type": "divider" }, { "type": "section", "fields": [ { "type": "mrkdwn", "text": "*Service:*\n{{.Service.Name}}" }, { "type": "mrkdwn", "text": "*URL:*\n{{.Service.Domain}}" }, { "type": "mrkdwn", "text": "*Status Code:*\n{{.Service.LastStatusCode}}" }, { "type": "mrkdwn", "text": "*When:*\n{{.Failure.CreatedAt}}" }, { "type": "mrkdwn", "text": "*Downtime:*\n{{.Service.DowntimeAgo}}" }, { "type": "plain_text", "text": "*Error:*\n{{.Failure.Issue}}" } ] }, { "type": "divider" }, { "type": "actions", "elements": [ { "type": "button", "text": { "type": "plain_text", "text": "View Offline Service", "emoji": true }, "style": "danger", "url": "{{.Core.Domain}}/service/{{.Service.Id}}" }, { "type": "button", "text": { "type": "plain_text", "text": "Go to Statping", "emoji": true }, "url": "{{.Core.Domain}}" } ] } ] }`,
SuccessData: null.NewNullString(`{ "blocks": [ { "type": "section", "text": { "type": "mrkdwn", "text": "The service {{.Service.Name}} is back online." } }, { "type": "actions", "elements": [ { "type": "button", "text": { "type": "plain_text", "text": "View Service", "emoji": true }, "style": "primary", "url": "{{.Core.Domain}}/service/{{.Service.Id}}" }, { "type": "button", "text": { "type": "plain_text", "text": "Go to Statping", "emoji": true }, "url": "{{.Core.Domain}}" } ] } ] }`),
FailureData: null.NewNullString(`{ "blocks": [ { "type": "section", "text": { "type": "mrkdwn", "text": ":warning: The service {{.Service.Name}} is currently offline! :warning:" } }, { "type": "divider" }, { "type": "section", "fields": [ { "type": "mrkdwn", "text": "*Service:*\n{{.Service.Name}}" }, { "type": "mrkdwn", "text": "*URL:*\n{{.Service.Domain}}" }, { "type": "mrkdwn", "text": "*Status Code:*\n{{.Service.LastStatusCode}}" }, { "type": "mrkdwn", "text": "*When:*\n{{.Failure.CreatedAt}}" }, { "type": "mrkdwn", "text": "*Downtime:*\n{{.Service.DowntimeAgo}}" }, { "type": "plain_text", "text": "*Error:*\n{{.Failure.Issue}}" } ] }, { "type": "divider" }, { "type": "actions", "elements": [ { "type": "button", "text": { "type": "plain_text", "text": "View Offline Service", "emoji": true }, "style": "danger", "url": "{{.Core.Domain}}/service/{{.Service.Id}}" }, { "type": "button", "text": { "type": "plain_text", "text": "Go to Statping", "emoji": true }, "url": "{{.Core.Domain}}" } ] } ] }`),
DataType: "json",
RequestInfo: "Slack allows you to customize your own messages with many complex components. Checkout the <a target=\"_blank\" href=\"https://api.slack.com/reference/surfaces/formatting\">Slack Message API</a> to learn how you can create your own.",
Limits: 60,
@ -52,7 +53,7 @@ var slacker = &slack{&notifications.Notification{
// Send will send a HTTP Post to the slack webhooker API. It accepts type: string
func (s *slack) sendSlack(msg string) (string, error) {
resp, _, err := utils.HttpRequest(s.Host, "POST", "application/json", nil, strings.NewReader(msg), time.Duration(10*time.Second), true, nil)
resp, _, err := utils.HttpRequest(s.Host.String, "POST", "application/json", nil, strings.NewReader(msg), time.Duration(10*time.Second), true, nil)
if err != nil {
return "", err
}
@ -61,8 +62,8 @@ func (s *slack) sendSlack(msg string) (string, error) {
func (s *slack) OnTest() (string, error) {
example := services.Example(true)
testMsg := ReplaceVars(s.SuccessData, example, failures.Failure{})
contents, resp, err := utils.HttpRequest(s.Host, "POST", "application/json", nil, bytes.NewBuffer([]byte(testMsg)), time.Duration(10*time.Second), true, nil)
testMsg := ReplaceVars(s.SuccessData.String, example, failures.Failure{})
contents, resp, err := utils.HttpRequest(s.Host.String, "POST", "application/json", nil, bytes.NewBuffer([]byte(testMsg)), time.Duration(10*time.Second), true, nil)
if err != nil {
return "", err
}
@ -75,14 +76,14 @@ func (s *slack) OnTest() (string, error) {
// OnFailure will trigger failing service
func (s *slack) OnFailure(srv services.Service, f failures.Failure) (string, error) {
msg := ReplaceVars(s.FailureData, srv, f)
msg := ReplaceVars(s.FailureData.String, srv, f)
out, err := s.sendSlack(msg)
return out, err
}
// OnSuccess will trigger successful service
func (s *slack) OnSuccess(srv services.Service) (string, error) {
msg := ReplaceVars(s.SuccessData, srv, failures.Failure{})
msg := ReplaceVars(s.SuccessData.String, srv, failures.Failure{})
out, err := s.sendSlack(msg)
return out, err
}

View File

@ -28,21 +28,21 @@ func TestSlackNotifier(t *testing.T) {
core.Example()
SLACK_URL = utils.Params.GetString("SLACK_URL")
slacker.Host = SLACK_URL
slacker.Enabled = null.NewNullBool(true)
if SLACK_URL == "" {
t.Log("slack notifier testing skipped, missing SLACK_URL environment variable")
t.SkipNow()
}
slacker.Host = null.NewNullString(SLACK_URL)
slacker.Enabled = null.NewNullBool(true)
t.Run("Load slack", func(t *testing.T) {
slacker.Host = SLACK_URL
slacker.Host = null.NewNullString(SLACK_URL)
slacker.Delay = time.Duration(100 * time.Millisecond)
slacker.Limits = 3
Add(slacker)
assert.Equal(t, "Hunter Long", slacker.Author)
assert.Equal(t, SLACK_URL, slacker.Host)
assert.Equal(t, SLACK_URL, slacker.Host.String)
})
t.Run("slack Within Limits", func(t *testing.T) {

View File

@ -69,7 +69,7 @@ type statpingMail struct {
// OnFailure will trigger failing service
func (s *statpingEmailer) OnFailure(srv services.Service, f failures.Failure) (string, error) {
ee := statpingMail{
Email: s.Host,
Email: s.Host.String,
Core: *core.App,
Service: srv,
Failure: f,
@ -80,7 +80,7 @@ func (s *statpingEmailer) OnFailure(srv services.Service, f failures.Failure) (s
// OnSuccess will trigger successful service
func (s *statpingEmailer) OnSuccess(srv services.Service) (string, error) {
ee := statpingMail{
Email: s.Host,
Email: s.Host.String,
Core: *core.App,
Service: srv,
Failure: failures.Failure{},
@ -91,7 +91,7 @@ func (s *statpingEmailer) OnSuccess(srv services.Service) (string, error) {
// OnSave will trigger when this notifier is saved
func (s *statpingEmailer) OnSave() (string, error) {
ee := statpingMail{
Email: s.Host,
Email: s.Host.String,
Core: *core.App,
Service: services.Service{},
Failure: failures.Failure{},

View File

@ -28,7 +28,7 @@ func TestStatpingEmailerNotifier(t *testing.T) {
core.Example()
testEmail = utils.Params.GetString("TEST_EMAIL")
statpingMailer.Host = testEmail
statpingMailer.Host = null.NewNullString(testEmail)
statpingMailer.Enabled = null.NewNullBool(true)
if testEmail == "" {
@ -37,12 +37,12 @@ func TestStatpingEmailerNotifier(t *testing.T) {
}
t.Run("Load statping emailer", func(t *testing.T) {
statpingMailer.Host = testEmail
statpingMailer.Host = null.NewNullString(testEmail)
statpingMailer.Delay = time.Duration(100 * time.Millisecond)
statpingMailer.Limits = 3
Add(statpingMailer)
assert.Equal(t, "Hunter Long", statpingMailer.Author)
assert.Equal(t, testEmail, statpingMailer.Host)
assert.Equal(t, testEmail, statpingMailer.Host.String)
})
t.Run("statping emailer Within Limits", func(t *testing.T) {

View File

@ -7,6 +7,7 @@ import (
"github.com/statping/statping/types/failures"
"github.com/statping/statping/types/notifications"
"github.com/statping/statping/types/notifier"
"github.com/statping/statping/types/null"
"github.com/statping/statping/types/services"
"github.com/statping/statping/utils"
"net/url"
@ -32,8 +33,8 @@ var Telegram = &telegram{&notifications.Notification{
AuthorUrl: "https://github.com/hunterlong",
Icon: "fab fa-telegram-plane",
Delay: time.Duration(5 * time.Second),
SuccessData: "Your service '{{.Service.Name}}' is currently online!",
FailureData: "Your service '{{.Service.Name}}' is currently offline!",
SuccessData: null.NewNullString("Your service '{{.Service.Name}}' is currently online!"),
FailureData: null.NewNullString("Your service '{{.Service.Name}}' is currently offline!"),
DataType: "text",
Limits: 60,
Form: []notifications.NotificationForm{{
@ -58,7 +59,7 @@ func (t *telegram) sendMessage(message string) (string, error) {
apiEndpoint := fmt.Sprintf("https://api.telegram.org/bot%v/sendMessage", t.ApiSecret)
v := url.Values{}
v.Set("chat_id", t.Var1)
v.Set("chat_id", t.Var1.String)
v.Set("text", message)
contents, _, err := utils.HttpRequest(apiEndpoint, "POST", "application/x-www-form-urlencoded", nil, strings.NewReader(v.Encode()), time.Duration(10*time.Second), true, nil)
@ -74,16 +75,14 @@ func (t *telegram) sendMessage(message string) (string, error) {
// OnFailure will trigger failing service
func (t *telegram) OnFailure(s services.Service, f failures.Failure) (string, error) {
msg := ReplaceVars(t.FailureData, s, f)
out, err := t.sendMessage(msg)
return out, err
msg := ReplaceVars(t.FailureData.String, s, f)
return t.sendMessage(msg)
}
// OnSuccess will trigger successful service
func (t *telegram) OnSuccess(s services.Service) (string, error) {
msg := ReplaceVars(t.SuccessData, s, failures.Failure{})
out, err := t.sendMessage(msg)
return out, err
msg := ReplaceVars(t.SuccessData.String, s, failures.Failure{})
return t.sendMessage(msg)
}
// OnTest will test the Twilio SMS messaging

View File

@ -20,13 +20,18 @@ var (
)
func TestTelegramNotifier(t *testing.T) {
if telegramToken == "" || telegramChannel == "" {
t.Log("Telegram notifier testing skipped, missing TELEGRAM_TOKEN and TELEGRAM_CHANNEL environment variable")
t.SkipNow()
}
err := utils.InitLogs()
require.Nil(t, err)
telegramToken = utils.Params.GetString("TELEGRAM_TOKEN")
telegramChannel = utils.Params.GetString("TELEGRAM_CHANNEL")
Telegram.ApiSecret = telegramToken
Telegram.Var1 = telegramChannel
Telegram.ApiSecret = null.NewNullString(telegramToken)
Telegram.Var1 = null.NewNullString(telegramChannel)
db, err := database.OpenTester()
require.Nil(t, err)
@ -34,22 +39,17 @@ func TestTelegramNotifier(t *testing.T) {
notifications.SetDB(db)
core.Example()
if telegramToken == "" || telegramChannel == "" {
t.Log("Telegram notifier testing skipped, missing TELEGRAM_TOKEN and TELEGRAM_CHANNEL environment variable")
t.SkipNow()
}
t.Run("Load Telegram", func(t *testing.T) {
Telegram.ApiSecret = telegramToken
Telegram.Var1 = telegramChannel
Telegram.ApiSecret = null.NewNullString(telegramToken)
Telegram.Var1 = null.NewNullString(telegramChannel)
Telegram.Delay = time.Duration(1 * time.Second)
Telegram.Enabled = null.NewNullBool(true)
Add(Telegram)
assert.Equal(t, "Hunter Long", Telegram.Author)
assert.Equal(t, telegramToken, Telegram.ApiSecret)
assert.Equal(t, telegramChannel, Telegram.Var1)
assert.Equal(t, telegramToken, Telegram.ApiSecret.String)
assert.Equal(t, telegramChannel, Telegram.Var1.String)
})
t.Run("Telegram Within Limits", func(t *testing.T) {

View File

@ -8,6 +8,7 @@ import (
"github.com/statping/statping/types/failures"
"github.com/statping/statping/types/notifications"
"github.com/statping/statping/types/notifier"
"github.com/statping/statping/types/null"
"github.com/statping/statping/types/services"
"github.com/statping/statping/utils"
"net/url"
@ -33,8 +34,8 @@ var Twilio = &twilio{&notifications.Notification{
AuthorUrl: "https://github.com/hunterlong",
Icon: "far fa-comment-alt",
Delay: time.Duration(10 * time.Second),
SuccessData: "Your service '{{.Service.Name}}' is currently online!",
FailureData: "Your service '{{.Service.Name}}' is currently offline!",
SuccessData: null.NewNullString("Your service '{{.Service.Name}}' is currently online!"),
FailureData: null.NewNullString("Your service '{{.Service.Name}}' is currently offline!"),
DataType: "text",
Limits: 15,
Form: []notifications.NotificationForm{{
@ -66,15 +67,15 @@ var Twilio = &twilio{&notifications.Notification{
// Send will send a HTTP Post to the Twilio SMS API. It accepts type: string
func (t *twilio) sendMessage(message string) (string, error) {
twilioUrl := fmt.Sprintf("https://api.twilio.com/2010-04-01/Accounts/%s/Messages.json", t.ApiKey)
twilioUrl := fmt.Sprintf("https://api.twilio.com/2010-04-01/Accounts/%s/Messages.json", t.ApiKey.String)
v := url.Values{}
v.Set("To", "+"+t.Var1)
v.Set("From", "+"+t.Var2)
v.Set("To", "+"+t.Var1.String)
v.Set("From", "+"+t.Var2.String)
v.Set("Body", message)
rb := strings.NewReader(v.Encode())
authHeader := base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", t.ApiKey, t.ApiSecret)))
authHeader := base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", t.ApiKey.String, t.ApiSecret.String)))
contents, _, err := utils.HttpRequest(twilioUrl, "POST", "application/x-www-form-urlencoded", []string{"Authorization=Basic " + authHeader}, rb, 10*time.Second, true, nil)
success, _ := twilioSuccess(contents)
@ -91,13 +92,13 @@ func (t *twilio) sendMessage(message string) (string, error) {
// OnFailure will trigger failing service
func (t *twilio) OnFailure(s services.Service, f failures.Failure) (string, error) {
msg := ReplaceVars(t.FailureData, s, f)
msg := ReplaceVars(t.FailureData.String, s, f)
return t.sendMessage(msg)
}
// OnSuccess will trigger successful service
func (t *twilio) OnSuccess(s services.Service) (string, error) {
msg := ReplaceVars(t.SuccessData, s, failures.Failure{})
msg := ReplaceVars(t.SuccessData.String, s, failures.Failure{})
return t.sendMessage(msg)
}

View File

@ -38,10 +38,10 @@ func TestTwilioNotifier(t *testing.T) {
}
t.Run("Load Twilio", func(t *testing.T) {
Twilio.ApiKey = TWILIO_SID
Twilio.ApiSecret = TWILIO_SECRET
Twilio.Var1 = "15005550006"
Twilio.Var2 = "15005550006"
Twilio.ApiKey = null.NewNullString(TWILIO_SID)
Twilio.ApiSecret = null.NewNullString(TWILIO_SECRET)
Twilio.Var1 = null.NewNullString("15005550006")
Twilio.Var2 = null.NewNullString("15005550006")
Twilio.Delay = 100 * time.Millisecond
Twilio.Enabled = null.NewNullBool(true)
@ -49,7 +49,7 @@ func TestTwilioNotifier(t *testing.T) {
assert.Nil(t, err)
assert.Equal(t, "Hunter Long", Twilio.Author)
assert.Equal(t, TWILIO_SID, Twilio.ApiKey)
assert.Equal(t, TWILIO_SID, Twilio.ApiKey.String)
})
t.Run("Twilio Within Limits", func(t *testing.T) {

View File

@ -6,6 +6,7 @@ import (
"github.com/statping/statping/types/failures"
"github.com/statping/statping/types/notifications"
"github.com/statping/statping/types/notifier"
"github.com/statping/statping/types/null"
"github.com/statping/statping/types/services"
"github.com/statping/statping/utils"
"io/ioutil"
@ -32,8 +33,8 @@ var Webhook = &webhooker{&notifications.Notification{
AuthorUrl: "https://github.com/hunterlong",
Icon: "fas fa-code-branch",
Delay: time.Duration(3 * time.Second),
SuccessData: `{"id": "{{.Service.Id}}", "online": true}`,
FailureData: `{"id": "{{.Service.Id}}", "online": false}`,
SuccessData: null.NewNullString(`{"id": "{{.Service.Id}}", "online": true}`),
FailureData: null.NewNullString(`{"id": "{{.Service.Id}}", "online": false}`),
DataType: "json",
Limits: 180,
Form: []notifications.NotificationForm{{
@ -83,12 +84,12 @@ func (w *webhooker) sendHttpWebhook(body string) (*http.Response, error) {
utils.Log.Infoln(fmt.Sprintf("sending body: '%v' to %v as a %v request", body, w.Host, w.Var1))
client := new(http.Client)
client.Timeout = 10 * time.Second
req, err := http.NewRequest(w.Var1, w.Host, bytes.NewBufferString(body))
req, err := http.NewRequest(w.Var1.String, w.Host.String, bytes.NewBufferString(body))
if err != nil {
return nil, err
}
if w.ApiSecret != "" {
keyVal := strings.SplitN(w.ApiSecret, "=", 2)
if w.ApiSecret.String != "" {
keyVal := strings.SplitN(w.ApiSecret.String, "=", 2)
if len(keyVal) == 2 {
if keyVal[0] != "" && keyVal[1] != "" {
if strings.ToLower(keyVal[0]) == "host" {
@ -99,8 +100,8 @@ func (w *webhooker) sendHttpWebhook(body string) (*http.Response, error) {
}
}
}
if w.ApiKey != "" {
req.Header.Add("Content-Type", w.ApiKey)
if w.ApiKey.String != "" {
req.Header.Add("Content-Type", w.ApiKey.String)
} else {
req.Header.Add("Content-Type", "application/json")
}
@ -117,7 +118,7 @@ func (w *webhooker) sendHttpWebhook(body string) (*http.Response, error) {
func (w *webhooker) OnTest() (string, error) {
f := failures.Example()
s := services.Example(false)
body := ReplaceVars(w.SuccessData, s, f)
body := ReplaceVars(w.SuccessData.String, s, f)
resp, err := w.sendHttpWebhook(body)
if err != nil {
return "", err
@ -131,7 +132,7 @@ func (w *webhooker) OnTest() (string, error) {
// OnFailure will trigger failing service
func (w *webhooker) OnFailure(s services.Service, f failures.Failure) (string, error) {
msg := ReplaceVars(w.FailureData, s, f)
msg := ReplaceVars(w.FailureData.String, s, f)
resp, err := w.sendHttpWebhook(msg)
if err != nil {
return "", err
@ -143,7 +144,7 @@ func (w *webhooker) OnFailure(s services.Service, f failures.Failure) (string, e
// OnSuccess will trigger successful service
func (w *webhooker) OnSuccess(s services.Service) (string, error) {
msg := ReplaceVars(w.SuccessData, s, failures.Failure{})
msg := ReplaceVars(w.SuccessData.String, s, failures.Failure{})
resp, err := w.sendHttpWebhook(msg)
if err != nil {
return "", err

View File

@ -31,10 +31,10 @@ func TestWebhookNotifier(t *testing.T) {
core.Example()
t.Run("Load webhooker", func(t *testing.T) {
Webhook.Host = webhookTestUrl
Webhook.Var1 = "POST"
Webhook.Var2 = webhookMessage
Webhook.ApiKey = "application/json"
Webhook.Host = null.NewNullString(webhookTestUrl)
Webhook.Var1 = null.NewNullString("POST")
Webhook.Var2 = null.NewNullString(webhookMessage)
Webhook.ApiKey = null.NewNullString("application/json")
Webhook.Enabled = null.NewNullBool(true)
Add(Webhook)

View File

@ -32,10 +32,10 @@ func (n *Notification) Create() error {
}
return nil
}
if p.FailureData == "" {
if p.FailureData.String == "" {
p.FailureData = n.FailureData
}
if p.SuccessData == "" {
if p.SuccessData.String == "" {
p.SuccessData = n.SuccessData
}
if err := p.Update(); err != nil {

View File

@ -45,21 +45,21 @@ func (n *Notification) CanSend() bool {
func (n *Notification) GetValue(dbField string) string {
switch strings.ToLower(dbField) {
case "host":
return n.Host
return n.Host.String
case "port":
return fmt.Sprintf("%d", n.Port)
return fmt.Sprintf("%d", n.Port.Int64)
case "username":
return n.Username
return n.Username.String
case "password":
return n.Password
return n.Password.String
case "var1":
return n.Var1
return n.Var1.String
case "var2":
return n.Var2
return n.Var2.String
case "api_key":
return n.ApiKey
return n.ApiKey.String
case "api_secret":
return n.ApiSecret
return n.ApiSecret.String
case "limits":
return utils.ToString(n.Limits)
default:

View File

@ -13,32 +13,32 @@ var (
// Notification contains all the fields for a Statping Notifier.
type Notification struct {
Id int64 `gorm:"primary_key;column:id" json:"id"`
Method string `gorm:"column:method" json:"method"`
Host string `gorm:"not null;column:host" json:"host,omitempty"`
Port int `gorm:"not null;column:port" json:"port,omitempty"`
Username string `gorm:"not null;column:username" json:"username,omitempty"`
Password string `gorm:"not null;column:password" json:"password,omitempty"`
Var1 string `gorm:"not null;column:var1" json:"var1,omitempty"`
Var2 string `gorm:"not null;column:var2" json:"var2,omitempty"`
ApiKey string `gorm:"not null;column:api_key" json:"api_key,omitempty"`
ApiSecret string `gorm:"not null;column:api_secret" json:"api_secret,omitempty"`
Enabled null.NullBool `gorm:"column:enabled;type:boolean;default:false" json:"enabled,omitempty"`
Limits int `gorm:"not null;column:limits" json:"limits"`
Removable bool `gorm:"column:removable" json:"removable"`
SuccessData string `gorm:"type:text;column:success_data" json:"success_data,omitempty"`
FailureData string `gorm:"type:text;column:failure_data" json:"failure_data,omitempty"`
DataType string `gorm:"-" json:"data_type,omitempty"`
RequestInfo string `gorm:"-" json:"request_info,omitempty"`
CreatedAt time.Time `gorm:"column:created_at" json:"created_at"`
UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at"`
Title string `gorm:"-" json:"title"`
Description string `gorm:"-" json:"description"`
Author string `gorm:"-" json:"author"`
AuthorUrl string `gorm:"-" json:"author_url"`
Icon string `gorm:"-" json:"icon"`
Delay time.Duration `gorm:"-" json:"delay,string"`
Running chan bool `gorm:"-" json:"-"`
Id int64 `gorm:"primary_key;column:id" json:"id"`
Method string `gorm:"column:method" json:"method"`
Host null.NullString `gorm:"column:host" json:"host,omitempty"`
Port null.NullInt64 `gorm:"column:port" json:"port,omitempty"`
Username null.NullString `gorm:"column:username" json:"username,omitempty"`
Password null.NullString `gorm:"column:password" json:"password,omitempty"`
Var1 null.NullString `gorm:"column:var1" json:"var1,omitempty"`
Var2 null.NullString `gorm:"column:var2" json:"var2,omitempty"`
ApiKey null.NullString `gorm:"column:api_key" json:"api_key,omitempty"`
ApiSecret null.NullString `gorm:"column:api_secret" json:"api_secret,omitempty"`
Enabled null.NullBool `gorm:"column:enabled;type:boolean;default:false" json:"enabled,omitempty"`
Limits int `gorm:"not null;column:limits" json:"limits"`
Removable bool `gorm:"column:removable" json:"removable"`
SuccessData null.NullString `gorm:"type:text;column:success_data" json:"success_data,omitempty"`
FailureData null.NullString `gorm:"type:text;column:failure_data" json:"failure_data,omitempty"`
DataType string `gorm:"-" json:"data_type,omitempty"`
RequestInfo string `gorm:"-" json:"request_info,omitempty"`
CreatedAt time.Time `gorm:"column:created_at" json:"created_at"`
UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at"`
Title string `gorm:"-" json:"title"`
Description string `gorm:"-" json:"description"`
Author string `gorm:"-" json:"author"`
AuthorUrl string `gorm:"-" json:"author_url"`
Icon string `gorm:"-" json:"icon"`
Delay time.Duration `gorm:"-" json:"delay,string"`
Running chan bool `gorm:"-" json:"-"`
Form []NotificationForm `gorm:"-" json:"form"`
lastSent time.Time `gorm:"-" json:"-"`