2018-08-16 06:22:20 +00:00
// Statup
// Copyright (C) 2018. Hunter Long and the project contributors
// Written by Hunter Long <info@socialeck.com> 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 <http://www.gnu.org/licenses/>.
2018-07-10 12:05:20 +00:00
package notifiers
import (
"bytes"
2018-09-26 15:26:16 +00:00
"errors"
2018-07-10 12:05:20 +00:00
"fmt"
2018-09-12 04:14:22 +00:00
"github.com/hunterlong/statup/core/notifier"
2018-07-14 02:37:39 +00:00
"github.com/hunterlong/statup/types"
2018-09-26 15:26:16 +00:00
"io/ioutil"
2018-07-10 12:05:20 +00:00
"net/http"
2018-07-13 09:43:15 +00:00
"text/template"
2018-07-14 02:37:39 +00:00
"time"
2018-07-10 12:05:20 +00:00
)
const (
2018-10-06 05:05:50 +00:00
slackMethod = "slack"
failingTemplate = ` { "attachments": [ { "fallback": "Service {{ .Service .Name }} - is currently failing", "text": "< {{ .Service .Domain }} | {{ .Service .Name }} > - Your Statup service ' {{ .Service .Name }} ' has just received a Failure notification with a HTTP Status code of {{ .Service .LastStatusCode }} .", "fields": [ { "title": "Expected", "value": " {{ .Service .Expected }} ", "short": true }, { "title": "Status Code", "value": " {{ .Service .LastStatusCode }} ", "short": true } ], "color": "#FF0000", "thumb_url": "https://statup.io", "footer": "Statup", "footer_icon": "https://img.cjx.io/statuplogo32.png" } ] } `
successTemplate = ` { "attachments": [ { "fallback": "Service {{ .Service .Name }} - is now back online", "text": "< {{ .Service .Domain }} | {{ .Service .Name }} > - Your Statup service ' {{ .Service .Name }} ' has just received a Failure notification.", "fields": [ { "title": "Issue", "value": "Awesome Project", "short": true }, { "title": "Status Code", "value": " {{ .Service .LastStatusCode }} ", "short": true } ], "color": "#00FF00", "thumb_url": "https://statup.io", "footer": "Statup", "footer_icon": "https://img.cjx.io/statuplogo32.png" } ] } `
slackText = ` { "text":" {{ . }} "} `
2018-07-10 12:05:20 +00:00
)
2018-10-06 05:00:40 +00:00
type slack struct {
2018-09-12 04:14:22 +00:00
* notifier . Notification
2018-07-11 03:06:21 +00:00
}
2018-10-06 05:00:40 +00:00
var slacker = & slack { & notifier . Notification {
2018-10-06 05:05:50 +00:00
Method : slackMethod ,
2018-10-06 05:00:40 +00:00
Title : "slack" ,
Description : "Send notifications to your slack channel when a service is offline. Insert your Incoming webhooker URL for your channel to receive notifications. Based on the <a href=\"https://api.slack.com/incoming-webhooks\">slack API</a>." ,
2018-09-15 01:18:21 +00:00
Author : "Hunter Long" ,
AuthorUrl : "https://github.com/hunterlong" ,
Delay : time . Duration ( 10 * time . Second ) ,
Host : "https://webhooksurl.slack.com/***" ,
2018-09-12 04:14:22 +00:00
Form : [ ] notifier . NotificationForm { {
Type : "text" ,
2018-10-06 05:00:40 +00:00
Title : "Incoming webhooker Url" ,
Placeholder : "Insert your slack webhook URL here." ,
SmallText : "Incoming webhooker URL from <a href=\"https://api.slack.com/apps\" target=\"_blank\">slack Apps</a>" ,
2018-09-12 04:14:22 +00:00
DbField : "Host" ,
2018-09-27 01:49:21 +00:00
Required : true ,
2018-09-12 04:14:22 +00:00
} } } ,
}
2018-09-15 22:21:58 +00:00
func parseSlackMessage ( temp string , data interface { } ) error {
2018-09-15 01:18:21 +00:00
buf := new ( bytes . Buffer )
slackTemp , _ := template . New ( "slack" ) . Parse ( temp )
err := slackTemp . Execute ( buf , data )
if err != nil {
return err
}
slacker . AddQueue ( buf . String ( ) )
return nil
}
2018-10-06 05:03:10 +00:00
type slackMessage struct {
2018-09-15 01:18:21 +00:00
Service * types . Service
Template string
Time int64
}
2018-07-10 12:05:20 +00:00
// DEFINE YOUR NOTIFICATION HERE.
func init ( ) {
2018-09-12 04:14:22 +00:00
err := notifier . AddNotifier ( slacker )
2018-09-10 09:01:04 +00:00
if err != nil {
2018-09-12 04:14:22 +00:00
panic ( err )
2018-07-12 04:49:18 +00:00
}
2018-07-10 12:05:20 +00:00
}
2018-10-06 05:00:40 +00:00
// Send will send a HTTP Post to the slack webhooker API. It accepts type: string
func ( u * slack ) Send ( msg interface { } ) error {
2018-09-15 01:18:21 +00:00
message := msg . ( string )
client := new ( http . Client )
2018-09-15 22:21:58 +00:00
res , err := client . Post ( u . Host , "application/json" , bytes . NewBuffer ( [ ] byte ( message ) ) )
2018-09-15 01:18:21 +00:00
if err != nil {
return err
}
2018-09-15 22:21:58 +00:00
defer res . Body . Close ( )
2018-09-15 22:24:34 +00:00
//contents, _ := ioutil.ReadAll(res.Body)
2018-07-12 06:53:18 +00:00
return nil
}
2018-10-06 05:00:40 +00:00
func ( u * slack ) Select ( ) * notifier . Notification {
2018-09-15 01:18:21 +00:00
return u . Notification
2018-07-10 12:05:20 +00:00
}
2018-10-06 05:00:40 +00:00
func ( u * slack ) OnTest ( ) error {
2018-09-26 15:26:16 +00:00
client := new ( http . Client )
res , err := client . Post ( u . Host , "application/json" , bytes . NewBuffer ( [ ] byte ( ` { "text":"testing message"} ` ) ) )
if err != nil {
return err
}
defer res . Body . Close ( )
contents , _ := ioutil . ReadAll ( res . Body )
if string ( contents ) != "ok" {
2018-10-06 05:00:40 +00:00
return errors . New ( "The slack response was incorrect, check the URL" )
2018-09-26 15:26:16 +00:00
}
return err
2018-07-10 12:05:20 +00:00
}
2018-09-15 22:39:17 +00:00
// OnFailure will trigger failing service
2018-10-06 05:00:40 +00:00
func ( u * slack ) OnFailure ( s * types . Service , f * types . Failure ) {
2018-10-06 05:03:10 +00:00
message := slackMessage {
2018-09-15 01:18:21 +00:00
Service : s ,
2018-10-06 05:05:50 +00:00
Template : failingTemplate ,
2018-09-15 01:18:21 +00:00
Time : time . Now ( ) . Unix ( ) ,
2018-07-12 04:49:18 +00:00
}
2018-10-06 05:05:50 +00:00
parseSlackMessage ( failingTemplate , message )
2018-09-20 09:46:51 +00:00
u . Online = false
2018-07-10 12:05:20 +00:00
}
2018-09-15 22:39:17 +00:00
// OnSuccess will trigger successful service
2018-10-06 05:00:40 +00:00
func ( u * slack ) OnSuccess ( s * types . Service ) {
2018-09-20 09:46:51 +00:00
if ! u . Online {
2018-10-06 05:03:10 +00:00
message := slackMessage {
2018-09-20 09:46:51 +00:00
Service : s ,
2018-10-06 05:05:50 +00:00
Template : successTemplate ,
2018-09-20 09:46:51 +00:00
Time : time . Now ( ) . Unix ( ) ,
}
2018-10-06 05:05:50 +00:00
parseSlackMessage ( successTemplate , message )
2018-09-20 09:46:51 +00:00
}
u . Online = true
2018-07-10 12:05:20 +00:00
}
2018-09-15 22:39:17 +00:00
// OnSave triggers when this notifier has been saved
2018-10-06 05:00:40 +00:00
func ( u * slack ) OnSave ( ) error {
2018-09-15 01:18:21 +00:00
message := fmt . Sprintf ( "Notification %v is receiving updated information." , u . Method )
u . AddQueue ( message )
2018-07-10 12:05:20 +00:00
return nil
}