You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
statping/notifiers/mobile.go

175 lines
4.7 KiB

package notifiers
import (
"bytes"
"encoding/json"
"fmt"
"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"
"time"
)
var _ notifier.Notifier = (*mobilePush)(nil)
const mobileIdentifier = "com.statping"
type mobilePush struct {
*notifications.Notification
}
func (m *mobilePush) Select() *notifications.Notification {
return m.Notification
}
var Mobile = &mobilePush{&notifications.Notification{
Method: "mobile",
Title: "Mobile Notifications",
Description: `Receive push notifications on your Mobile device using the Statping App. You can scan the Authentication QR Code found in Settings to get the Mobile app setup in seconds.
<p align="center"><a href="https://play.google.com/store/apps/details?id=com.statping"><img src="https://img.cjx.io/google-play.svg"></a><a href="https://itunes.apple.com/us/app/apple-store/id1445513219"><img src="https://img.cjx.io/app-store-badge.svg"></a></p>`,
Author: "Hunter Long",
AuthorUrl: "https://github.com/hunterlong",
Delay: time.Duration(5 * time.Second),
Icon: "fas fa-mobile-alt",
Limits: 30,
Form: []notifications.NotificationForm{{
Type: "text",
Title: "Device Identifiers",
Placeholder: "A list of your Mobile device push notification ID's.",
DbField: "var1",
IsHidden: true,
}, {
Type: "number",
Title: "Array of device numbers",
Placeholder: "1 for iphone 2 for android",
DbField: "var2",
IsHidden: true,
}}},
}
func dataJson(s *services.Service, f *failures.Failure) map[string]interface{} {
serviceId := "0"
if s != nil {
serviceId = utils.ToString(s.Id)
}
online := "online"
if !s.Online {
online = "offline"
}
issue := ""
if f != nil {
issue = f.Issue
}
link := fmt.Sprintf("statping://service?id=%v", serviceId)
out := map[string]interface{}{
"status": online,
"id": serviceId,
"issue": issue,
"link": link,
}
return out
}
// OnFailure will trigger failing service
func (m *mobilePush) OnFailure(s *services.Service, f *failures.Failure) error {
data := dataJson(s, f)
msg := &pushArray{
Message: fmt.Sprintf("Your service '%v' is currently failing! Reason: %v", s.Name, f.Issue),
Title: "Service Offline",
Topic: mobileIdentifier,
Data: data,
}
return m.Send(msg)
}
// OnSuccess will trigger successful service
func (m *mobilePush) OnSuccess(s *services.Service) error {
data := dataJson(s, nil)
msg := &pushArray{
Message: "Service is Online!",
Title: "Service Online",
Topic: mobileIdentifier,
Data: data,
}
return m.Send(msg)
}
// OnTest triggers when this notifier has been saved
func (m *mobilePush) OnTest() error {
msg := &pushArray{
Message: "Testing the Mobile Notifier",
Title: "Testing Notifications",
Topic: mobileIdentifier,
Tokens: []string{m.Var1},
Platform: utils.ToInt(m.Var2),
}
body, err := pushRequest(msg)
if err != nil {
return err
}
var output mobileResponse
err = json.Unmarshal(body, &output)
if err != nil {
return err
}
if len(output.Logs) == 0 {
return nil
} else {
firstLog := output.Logs[0].Error
return fmt.Errorf("Mobile Notification error: %v", firstLog)
}
}
// Send will send message to Statping push notifications endpoint
func (m *mobilePush) Send(pushMessage *pushArray) error {
pushMessage.Tokens = []string{m.Var1}
pushMessage.Platform = utils.ToInt(m.Var2)
_, err := pushRequest(pushMessage)
if err != nil {
return err
}
return nil
}
func pushRequest(msg *pushArray) ([]byte, error) {
if msg.Platform == 1 {
msg.Title = ""
}
body, err := json.Marshal(&PushNotification{[]*pushArray{msg}})
if err != nil {
return nil, err
}
url := "https://push.statping.com/api/push"
body, _, err = utils.HttpRequest(url, "POST", "application/json", nil, bytes.NewBuffer(body), time.Duration(20*time.Second), true)
return body, err
}
type PushNotification struct {
Array []*pushArray `json:"notifications"`
}
type pushArray struct {
Tokens []string `json:"tokens"`
Platform int64 `json:"platform"`
Message string `json:"message"`
Topic string `json:"topic"`
Title string `json:"title,omitempty"`
Data map[string]interface{} `json:"data,omitempty"`
}
type mobileResponse struct {
Counts int `json:"counts"`
Logs []*mobileResponseLogs `json:"logs"`
Success string `json:"success"`
}
type mobileResponseLogs struct {
Type string `json:"type"`
Platform string `json:"platform"`
Token string `json:"token"`
Message string `json:"message"`
Error string `json:"error"`
}