diff --git a/notifiers/command.go b/notifiers/command.go
index e3ac1ea3..fa6bc004 100644
--- a/notifiers/command.go
+++ b/notifiers/command.go
@@ -34,23 +34,23 @@ var command = &commandLine{¬ifier.Notification{
AuthorUrl: "https://github.com/hunterlong",
Delay: time.Duration(1 * time.Second),
Icon: "fas fa-terminal",
- Host: "sh",
+ Host: "/bin/bash",
Form: []notifier.NotificationForm{{
Type: "text",
Title: "Shell or Bash",
- Placeholder: "sh",
+ Placeholder: "/bin/bash",
DbField: "host",
- SmallText: "You can use 'sh', 'bash' or even an absolute path for an application",
+ SmallText: "You can use '/bin/sh', '/bin/bash' or even an absolute path for an application",
}, {
Type: "text",
Title: "Command to Run on OnSuccess",
- Placeholder: "ping google.com",
+ Placeholder: "curl google.com",
DbField: "var1",
SmallText: "This command will run everytime a service is receiving a Successful event.",
}, {
Type: "text",
Title: "Command to Run on OnFailure",
- Placeholder: "ping offline.com",
+ Placeholder: "curl offline.com",
DbField: "var2",
SmallText: "This command will run everytime a service is receiving a Failing event.",
}}},
diff --git a/notifiers/mobile.go b/notifiers/mobile.go
index aa6c3a9a..3816a997 100644
--- a/notifiers/mobile.go
+++ b/notifiers/mobile.go
@@ -33,7 +33,7 @@ var mobile = &mobilePush{¬ifier.Notification{
Method: "mobile",
Title: "Mobile Notifications",
Description: `Receive push notifications on your Android or iPhone devices using the Statping App. You can scan the Authentication QR Code found in Settings to get the mobile app setup in seconds.
-

`,
+

`,
Author: "Hunter Long",
AuthorUrl: "https://github.com/hunterlong",
Delay: time.Duration(5 * time.Second),
diff --git a/notifiers/telegram.go b/notifiers/telegram.go
new file mode 100644
index 00000000..edc1628b
--- /dev/null
+++ b/notifiers/telegram.go
@@ -0,0 +1,165 @@
+// Statup
+// Copyright (C) 2018. Hunter Long and the project contributors
+// Written by Hunter Long and the project contributors
+//
+// https://github.com/hunterlong/statup
+//
+// The licenses for most software and other practical works are designed
+// to take away your freedom to share and change the works. By contrast,
+// the GNU General Public License is intended to guarantee your freedom to
+// share and change all versions of a program--to make sure it remains free
+// software for all its users.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+package notifiers
+
+import (
+ "encoding/json"
+ "errors"
+ "fmt"
+ "github.com/hunterlong/statping/core/notifier"
+ "github.com/hunterlong/statping/types"
+ "github.com/hunterlong/statping/utils"
+ "net/url"
+ "strings"
+ "time"
+)
+
+type telegram struct {
+ *notifier.Notification
+}
+
+var telegramNotifier = &telegram{¬ifier.Notification{
+ Method: "telegram",
+ Title: "Telegram",
+ Description: "Receive notifications on your Telegram channel when a service has an issue. You must get a Telegram API token from the /botfather. Review the Telegram API Tutorial to learn how to generate a new API Token.",
+ Author: "Hunter Long",
+ AuthorUrl: "https://github.com/hunterlong",
+ Icon: "fab fa-telegram-plane",
+ Delay: time.Duration(5 * time.Second),
+ Form: []notifier.NotificationForm{{
+ Type: "text",
+ Title: "Telegram API Token",
+ Placeholder: "383810182:EEx829dtCeufeQYXG7CUdiQopqdmmxBPO7-s",
+ SmallText: "Enter the API Token given to you from the /botfather chat.",
+ DbField: "api_secret",
+ Required: true,
+ }, {
+ Type: "text",
+ Title: "Channel or User ID",
+ Placeholder: "789325392",
+ SmallText: "Insert your Telegram Channel ID or User ID here.",
+ DbField: "Var1",
+ Required: true,
+ }}},
+}
+
+// DEFINE YOUR NOTIFICATION HERE.
+func init() {
+ err := notifier.AddNotifier(telegramNotifier)
+ if err != nil {
+ panic(err)
+ }
+}
+
+func (u *telegram) Select() *notifier.Notification {
+ return u.Notification
+}
+
+// Send will send a HTTP Post to the Telegram API. It accepts type: string
+func (u *telegram) Send(msg interface{}) error {
+ message := msg.(string)
+ apiEndpoint := fmt.Sprintf("https://api.telegram.org/bot%v/sendMessage", u.ApiSecret)
+
+ v := url.Values{}
+ v.Set("chat_id", u.Var1)
+ v.Set("text", message)
+ rb := *strings.NewReader(v.Encode())
+
+ contents, _, err := utils.HttpRequest(apiEndpoint, "GET", "application/x-www-form-urlencoded", nil, &rb, time.Duration(10*time.Second))
+
+ success, _ := telegramSuccess(contents)
+ if !success {
+ errorOut := telegramError(contents)
+ out := fmt.Sprintf("Error code %v - %v", errorOut.ErrorCode, errorOut.Description)
+ return errors.New(out)
+ }
+ return err
+}
+
+// OnFailure will trigger failing service
+func (u *telegram) OnFailure(s *types.Service, f *types.Failure) {
+ msg := fmt.Sprintf("Your service '%v' is currently offline!", s.Name)
+ u.AddQueue(s.Id, msg)
+ u.Online = false
+}
+
+// OnSuccess will trigger successful service
+func (u *telegram) OnSuccess(s *types.Service) {
+ if !u.Online {
+ u.ResetUniqueQueue(s.Id)
+ msg := fmt.Sprintf("Your service '%v' is back online!", s.Name)
+ u.AddQueue(s.Id, msg)
+ }
+ u.Online = true
+}
+
+// OnSave triggers when this notifier has been saved
+func (u *telegram) OnSave() error {
+ utils.Log(1, fmt.Sprintf("Notification %v is receiving updated information.", u.Method))
+
+ // Do updating stuff here
+
+ return nil
+}
+
+// OnTest will test the Twilio SMS messaging
+func (u *telegram) OnTest() error {
+ msg := fmt.Sprintf("Testing the Twilio SMS Notifier on your Statup server")
+ return u.Send(msg)
+}
+
+func telegramSuccess(res []byte) (bool, telegramResponse) {
+ var obj telegramResponse
+ json.Unmarshal(res, &obj)
+ if obj.Ok {
+ return true, obj
+ }
+ return false, obj
+}
+
+func telegramError(res []byte) telegramErrorObj {
+ var obj telegramErrorObj
+ json.Unmarshal(res, &obj)
+ return obj
+}
+
+type telegramErrorObj struct {
+ Ok bool `json:"ok"`
+ ErrorCode int `json:"error_code"`
+ Description string `json:"description"`
+}
+
+type telegramResponse struct {
+ Ok bool `json:"ok"`
+ Result struct {
+ MessageID int `json:"message_id"`
+ From struct {
+ ID int `json:"id"`
+ IsBot bool `json:"is_bot"`
+ FirstName string `json:"first_name"`
+ Username string `json:"username"`
+ } `json:"from"`
+ Chat struct {
+ ID int `json:"id"`
+ FirstName string `json:"first_name"`
+ LastName string `json:"last_name"`
+ Username string `json:"username"`
+ Type string `json:"type"`
+ } `json:"chat"`
+ Date int `json:"date"`
+ Text string `json:"text"`
+ } `json:"result"`
+}
diff --git a/notifiers/telegram_test.go b/notifiers/telegram_test.go
new file mode 100644
index 00000000..5e5a01c8
--- /dev/null
+++ b/notifiers/telegram_test.go
@@ -0,0 +1,108 @@
+// Statup
+// Copyright (C) 2018. Hunter Long and the project contributors
+// Written by Hunter Long and the project contributors
+//
+// https://github.com/hunterlong/statup
+//
+// The licenses for most software and other practical works are designed
+// to take away your freedom to share and change the works. By contrast,
+// the GNU General Public License is intended to guarantee your freedom to
+// share and change all versions of a program--to make sure it remains free
+// software for all its users.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+package notifiers
+
+import (
+ "github.com/hunterlong/statping/core/notifier"
+ "github.com/stretchr/testify/assert"
+ "os"
+ "testing"
+ "time"
+)
+
+var (
+ telegramToken string
+ telegramChannel string
+ telegramMessage = "The Telegram notifier on Statping has been tested!"
+)
+
+func init() {
+ telegramToken = os.Getenv("TELEGRAM_TOKEN")
+ telegramChannel = os.Getenv("TELEGRAM_CHANNEL")
+ telegramNotifier.ApiSecret = telegramToken
+ telegramNotifier.Var1 = telegramChannel
+}
+
+func TestTelegramNotifier(t *testing.T) {
+ t.Parallel()
+ if telegramToken == "" || telegramChannel == "" {
+ t.Log("Telegram notifier testing skipped, missing TELEGRAM_TOKEN and TELEGRAM_CHANNEL environment variable")
+ t.SkipNow()
+ }
+ currentCount = CountNotifiers()
+
+ t.Run("Load Telegram", func(t *testing.T) {
+ telegramNotifier.ApiSecret = telegramToken
+ telegramNotifier.Var1 = telegramChannel
+ telegramNotifier.Delay = time.Duration(1 * time.Second)
+ err := notifier.AddNotifier(telegramNotifier)
+ assert.Nil(t, err)
+ assert.Equal(t, "Hunter Long", telegramNotifier.Author)
+ assert.Equal(t, telegramToken, telegramNotifier.ApiSecret)
+ assert.Equal(t, telegramChannel, telegramNotifier.Var1)
+ })
+
+ t.Run("Load Telegram Notifier", func(t *testing.T) {
+ notifier.Load()
+ })
+
+ t.Run("Telegram Within Limits", func(t *testing.T) {
+ ok, err := telegramNotifier.WithinLimits()
+ assert.Nil(t, err)
+ assert.True(t, ok)
+ })
+
+ t.Run("Telegram OnFailure", func(t *testing.T) {
+ telegramNotifier.OnFailure(TestService, TestFailure)
+ assert.Equal(t, 1, len(telegramNotifier.Queue))
+ })
+
+ t.Run("Telegram Check Offline", func(t *testing.T) {
+ assert.False(t, telegramNotifier.Online)
+ })
+
+ t.Run("Telegram OnSuccess", func(t *testing.T) {
+ telegramNotifier.OnSuccess(TestService)
+ assert.Equal(t, 1, len(telegramNotifier.Queue))
+ })
+
+ t.Run("Telegram Check Back Online", func(t *testing.T) {
+ assert.True(t, telegramNotifier.Online)
+ })
+
+ t.Run("Telegram OnSuccess Again", func(t *testing.T) {
+ telegramNotifier.OnSuccess(TestService)
+ assert.Equal(t, 1, len(telegramNotifier.Queue))
+ })
+
+ t.Run("Telegram Send", func(t *testing.T) {
+ err := telegramNotifier.Send(telegramMessage)
+ assert.Nil(t, err)
+ })
+
+ t.Run("Telegram Test", func(t *testing.T) {
+ err := telegramNotifier.OnTest()
+ assert.Nil(t, err)
+ })
+
+ t.Run("Telegram Queue", func(t *testing.T) {
+ go notifier.Queue(telegramNotifier)
+ time.Sleep(3 * time.Second)
+ assert.Equal(t, telegramToken, telegramNotifier.ApiSecret)
+ assert.Equal(t, 0, len(telegramNotifier.Queue))
+ })
+
+}
diff --git a/notifiers/webhook_test.go b/notifiers/webhook_test.go
index 8d9bafe1..c1f5cd6b 100644
--- a/notifiers/webhook_test.go
+++ b/notifiers/webhook_test.go
@@ -23,7 +23,7 @@ import (
)
var (
- webhookTestUrl = "https://demo.statup.com/api/services"
+ webhookTestUrl = "https://demo.statping.com"
webhookMessage = `{"id": "%service.Id","name": "%service.Name","online": "%service.Online","issue": "%failure.Issue"}`
apiKey = "application/json"
fullMsg string
@@ -99,7 +99,7 @@ func TestWebhookNotifier(t *testing.T) {
t.Run("webhooker Send", func(t *testing.T) {
err := webhook.Send(fullMsg)
- assert.Error(t, err)
+ assert.Nil(t, err)
assert.Equal(t, len(webhook.Queue), 1)
})
diff --git a/source/css/base.css b/source/css/base.css
index 773c726c..58e687bc 100644
--- a/source/css/base.css
+++ b/source/css/base.css
@@ -444,8 +444,8 @@ HTML, BODY {
background-color: #ffffff; }
.card-body {
- font-size: 6pt;
- padding: 5px 5px; }
+ font-size: 10pt;
+ padding: 0px 10px; }
.lg_number {
font-size: 7.8vw; }
diff --git a/source/scss/mobile.scss b/source/scss/mobile.scss
index 12919abe..46565ae5 100644
--- a/source/scss/mobile.scss
+++ b/source/scss/mobile.scss
@@ -42,8 +42,8 @@
}
.card-body {
- font-size: 6pt;
- padding: 5px 5px;
+ font-size: 10pt;
+ padding: 0px 10px;
}
.lg_number {
diff --git a/source/tmpl/footer.gohtml b/source/tmpl/footer.gohtml
index b23590df..c3b425db 100644
--- a/source/tmpl/footer.gohtml
+++ b/source/tmpl/footer.gohtml
@@ -1,5 +1,5 @@
{{ define "footer"}}
-