Updated Notifiers (markdown)

master
Hunter Long 2018-09-11 19:14:56 -07:00
parent ee962d8eff
commit 2251a37170
1 changed files with 90 additions and 126 deletions

@ -1,165 +1,129 @@
Statup includes multiple Notifiers to alert you when your services are offline. You can also create your own notifier and send a Push Request to this repo! Creating a custom notifier is pretty easy as long as you follow the requirements. A notifier will automatically be installed into the users Statup database. Statup includes multiple Notifiers to alert you when your services are offline. You can also create your own notifier and send a Push Request to this repo! Creating a custom notifier is pretty easy as long as you follow the requirements. A notifier will automatically be installed into the users Statup database.
## Notifier Requirements ## Notifier Requirements
- Must have a unique `ID` for your notifier
- Must have a unique `METHOD` name - Must have a unique `METHOD` name
- Struct must have `*Notification` pointer in it. - Struct must have `*notifier.Notification` pointer in it.
- Must create and add your notifier variable in `init()` - Must create and add your notifier variable in `init()`
- Should have a form for user to input their variables/keys. `Form: []NotificationForm{}` - Should have a form for user to input their variables/keys. `Form: []notifier.NotificationForm`
## Notification Interface ## Notification Interface
Statup has the `Notifier` interface which you'll need to include in your notifier. Below is the current interface. Statup has the `Notifier` interface which you'll need to include in your notifier. Below is the current interface.
```go ```go
// Notifier interface is required to create a new Notifier
type Notifier interface { type Notifier interface {
Init() error // runs when notifier starts // Run will trigger inside of the notifier when enabled
Install() error // installs the notifier into the Statup database Run() error
Run() error // main notification go routine (loops and should run actions) // OnSave is triggered when the notifier is saved
OnFailure() error // anytime a service failure happens, this is ran OnSave() error
OnSuccess() error // anytime a service has a successful response this is ran // Test will run a function inside the notifier to Test if it works
Select() *Notification // required method to select the Notification from database Test() error
Test() error // a method to send a test for your notifier // Select returns the *Notification for a notifier
Select() *Notification
} }
``` ```
## Slack Notifier Include `OnSuccess` and `OnFailure` to receive triggers when a service is online or offline.
Below is a full example of the Slack notifier which will give you a good example of how to create your own. ```go
// BasicEvents includes the most minimal events, failing and successful service triggers
type BasicEvents interface {
// OnSuccess is triggered when a service is successful
OnSuccess(*types.Service)
// OnFailure is triggered when a service is failing
OnFailure(*types.Service, *types.Failure)
}
```
## Basic Example Notifier
Below is a full example of a Statup notifier which will give you a good example of how to create your own.
```go ```go
package notifiers package notifiers
import ( import (
"bytes" "github.com/hunterlong/statup/types"
"fmt" "github.com/hunterlong/statup/core/notifier"
"github.com/hunterlong/statup/utils"
"net/http"
"time"
) )
type Example struct {
*notifier.Notification // create a new struct using *Notification
}
const ( const (
SLACK_ID = 2 EXAMPLE_METHOD = "example" // give your notifier a unique name (no spaces)
SLACK_METHOD = "slack"
) )
var ( var example = &Example{&notifier.Notification{
slacker *Slack Method: EXAMPLE_METHOD,
slackMessages []string Host: "http://exmaplehost.com",
) Form: []notifier.NotificationForm{{
Type: "text",
type Slack struct { Title: "Host",
*Notification Placeholder: "Insert your Host here.",
DbField: "host",
}, {
Type: "text",
Title: "Username",
Placeholder: "Insert your Username here.",
DbField: "username",
}, {
Type: "password",
Title: "Password",
Placeholder: "Insert your Password here.",
DbField: "password",
}, {
Type: "number",
Title: "Port",
Placeholder: "Insert your Port here.",
DbField: "port",
}, {
Type: "text",
Title: "API Key",
Placeholder: "Insert your API Key here",
DbField: "api_key",
}, {
Type: "text",
Title: "API Secret",
Placeholder: "Insert your API Secret here",
DbField: "api_secret",
}, {
Type: "text",
Title: "Var 1",
Placeholder: "Insert your Var1 here",
DbField: "var1",
}, {
Type: "text",
Title: "Var2",
Placeholder: "Var2 goes here",
DbField: "var2",
}}},
} }
// DEFINE YOUR NOTIFICATION HERE. // AddNotifier(example) inside init() is required!
func init() { func init() {
slacker = &Slack{&Notification{ notifier.AddNotifier(example)
Id: SLACK_ID,
Method: SLACK_METHOD,
Host: "https://webhooksurl.slack.com/***",
Form: []NotificationForm{{
id: 2,
Type: "text",
Title: "Incoming Webhook Url",
Placeholder: "Insert your Slack webhook URL here.",
DbField: "Host",
}}},
}
add(slacker)
} }
// Select Obj // Run is required for the Notifier interface
func (u *Slack) Select() *Notification { func (n *Example) Run() error {
return u.Notification // this function can be a go routine if you need it
}
// WHEN NOTIFIER LOADS
func (u *Slack) Init() error {
err := u.Install()
if err == nil {
notifier, _ := SelectNotification(u.Id)
forms := u.Form
u.Notification = notifier
u.Form = forms
if u.Enabled {
go u.Run()
}
}
return err
}
func (u *Slack) Test() error {
SendSlack("Slack notifications on your Statup server is working!")
return nil return nil
} }
// AFTER NOTIFIER LOADS, IF ENABLED, START A QUEUE PROCESS // OnSave is required for the Notifier interface
func (u *Slack) Run() error { func (n *Example) OnSave() error {
for _, msg := range slackMessages { // this function is triggered when the notifier's form is saved
utils.Log(1, fmt.Sprintf("Sending JSON to Slack Webhook: %v", msg))
client := http.Client{Timeout: 15 * time.Second}
_, err := client.Post(u.Host, "application/json", bytes.NewBuffer([]byte(msg)))
if err != nil {
utils.Log(3, fmt.Sprintf("Issue sending Slack notification: %v", err))
}
slackMessages = uniqueMessages(slackMessages, msg)
}
time.Sleep(60 * time.Second)
if u.Enabled {
u.Run()
}
return nil return nil
} }
// CUSTOM FUNCTION FO SENDING SLACK MESSAGES // Select is required for the Notifier interface
func SendSlack(msg string) error { func (n *Example) Select() *Notification {
//if slackUrl == "" { return n.Notification
// return errors.New("Slack Webhook URL has not been set in settings")
//}
fullMessage := fmt.Sprintf("{\"text\":\"%v\"}", msg)
slackMessages = append(slackMessages, fullMessage)
return nil
} }
// ON SERVICE FAILURE, DO YOUR OWN FUNCTIONS func (n *Example) OnSuccess(s *types.Service) {
func (u *Slack) OnFailure() error { // When a service is successful this function will be triggered!
if u.Enabled {
utils.Log(1, fmt.Sprintf("Notification %v is receiving a failure notification.", u.Method))
// Do failing stuff here!
}
return nil
} }
// ON SERVICE SUCCESS, DO YOUR OWN FUNCTIONS func (n *Example) OnFailure(s *types.Service, f *types.Failure) {
func (u *Slack) OnSuccess() error { // When a service is failing this function will be triggered!
if u.Enabled {
utils.Log(1, fmt.Sprintf("Notification %v is receiving a successful notification.", u.Method))
// Do checking or any successful things here
}
return nil
} }
// ON SAVE OR UPDATE OF THE NOTIFIER FORM
func (u *Slack) OnSave() error {
utils.Log(1, fmt.Sprintf("Notification %v is receiving updated information.", u.Method))
// Do updating stuff here
return nil
}
// ON SERVICE FAILURE, DO YOUR OWN FUNCTIONS
func (u *Slack) Install() error {
inDb, err := slacker.Notification.isInDatabase()
if !inDb {
newNotifer, err := InsertDatabase(u.Notification)
if err != nil {
utils.Log(3, err)
return err
}
utils.Log(1, fmt.Sprintf("new notifier #%v installed: %v", newNotifer, u.Method))
}
return err
}
``` ```