diff --git a/Notifiers.md b/Notifiers.md index 9a62139..b4d8998 100644 --- a/Notifiers.md +++ b/Notifiers.md @@ -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. ## Notifier Requirements -- Must have a unique `ID` for your notifier - 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()` -- 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 Statup has the `Notifier` interface which you'll need to include in your notifier. Below is the current interface. ```go +// Notifier interface is required to create a new Notifier type Notifier interface { - Init() error // runs when notifier starts - Install() error // installs the notifier into the Statup database - Run() error // main notification go routine (loops and should run actions) - OnFailure() error // anytime a service failure happens, this is ran - OnSuccess() error // anytime a service has a successful response this is ran - Select() *Notification // required method to select the Notification from database - Test() error // a method to send a test for your notifier + // Run will trigger inside of the notifier when enabled + Run() error + // OnSave is triggered when the notifier is saved + OnSave() error + // Test will run a function inside the notifier to Test if it works + Test() error + // Select returns the *Notification for a notifier + Select() *Notification } ``` -## Slack Notifier -Below is a full example of the Slack notifier which will give you a good example of how to create your own. +Include `OnSuccess` and `OnFailure` to receive triggers when a service is online or offline. +```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 package notifiers import ( - "bytes" - "fmt" - "github.com/hunterlong/statup/utils" - "net/http" - "time" + "github.com/hunterlong/statup/types" + "github.com/hunterlong/statup/core/notifier" ) +type Example struct { + *notifier.Notification // create a new struct using *Notification +} + const ( - SLACK_ID = 2 - SLACK_METHOD = "slack" + EXAMPLE_METHOD = "example" // give your notifier a unique name (no spaces) ) -var ( - slacker *Slack - slackMessages []string -) - -type Slack struct { - *Notification +var example = &Example{¬ifier.Notification{ + Method: EXAMPLE_METHOD, + Host: "http://exmaplehost.com", + Form: []notifier.NotificationForm{{ + Type: "text", + Title: "Host", + 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() { - slacker = &Slack{&Notification{ - 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) + notifier.AddNotifier(example) } -// Select Obj -func (u *Slack) Select() *Notification { - return u.Notification -} - -// 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!") +// Run is required for the Notifier interface +func (n *Example) Run() error { + // this function can be a go routine if you need it return nil } -// AFTER NOTIFIER LOADS, IF ENABLED, START A QUEUE PROCESS -func (u *Slack) Run() error { - for _, msg := range slackMessages { - 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() - } +// OnSave is required for the Notifier interface +func (n *Example) OnSave() error { + // this function is triggered when the notifier's form is saved return nil } -// CUSTOM FUNCTION FO SENDING SLACK MESSAGES -func SendSlack(msg string) error { - //if slackUrl == "" { - // return errors.New("Slack Webhook URL has not been set in settings") - //} - fullMessage := fmt.Sprintf("{\"text\":\"%v\"}", msg) - slackMessages = append(slackMessages, fullMessage) - return nil +// Select is required for the Notifier interface +func (n *Example) Select() *Notification { + return n.Notification } -// ON SERVICE FAILURE, DO YOUR OWN FUNCTIONS -func (u *Slack) OnFailure() error { - if u.Enabled { - utils.Log(1, fmt.Sprintf("Notification %v is receiving a failure notification.", u.Method)) - // Do failing stuff here! - } - return nil +func (n *Example) OnSuccess(s *types.Service) { + // When a service is successful this function will be triggered! } -// ON SERVICE SUCCESS, DO YOUR OWN FUNCTIONS -func (u *Slack) OnSuccess() error { - 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 +func (n *Example) OnFailure(s *types.Service, f *types.Failure) { + // When a service is failing this function will be triggered! } - -// 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 -} - ``` \ No newline at end of file