2018-12-04 05:57:11 +00:00
// Statping
2018-08-16 06:22:20 +00:00
// Copyright (C) 2018. Hunter Long and the project contributors
// Written by Hunter Long <info@socialeck.com> and the project contributors
//
2018-12-04 04:17:29 +00:00
// https://github.com/hunterlong/statping
2018-08-16 06:22:20 +00:00
//
// 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-12-04 04:17:29 +00:00
"github.com/hunterlong/statping/core/notifier"
"github.com/hunterlong/statping/types"
"github.com/hunterlong/statping/utils"
2018-11-25 03:56:09 +00:00
"strings"
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"
2018-12-04 05:57:11 +00:00
failingTemplate = ` { "attachments": [ { "fallback": "Service {{ .Service .Name }} - is currently failing", "text": "Your Statping service < {{ .Service .Domain }} | {{ .Service .Name }} > has just received a Failure notification based on your expected results. {{ .Service .Name }} responded with a HTTP Status code of {{ .Service .LastStatusCode }} .", "fields": [ { "title": "Expected Status Code", "value": " {{ .Service .ExpectedStatus }} ", "short": true }, { "title": "Received Status Code", "value": " {{ .Service .LastStatusCode }} ", "short": true } ], "color": "#FF0000", "thumb_url": "https://statping.com", "footer": "Statping", "footer_icon": "https://img.cjx.io/statuplogo32.png" } ] } `
successTemplate = ` { "attachments": [ { "fallback": "Service {{ .Service .Name }} - is now back online", "text": "Your Statping service < {{ .Service .Domain }} | {{ .Service .Name }} > is now back online and meets your expected responses.", "color": "#00FF00", "thumb_url": "https://statping.com", "footer": "Statping", "footer_icon": "https://img.cjx.io/statuplogo32.png" } ] } `
2018-10-06 05:05:50 +00:00
slackText = ` { "text":" {{ . }} "} `
2018-07-10 12:05:20 +00:00
)
2019-02-20 02:11:40 +00:00
func init ( ) {
err := notifier . AddNotifier ( slacker )
if err != nil {
panic ( err )
}
}
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-10-21 16:22:26 +00:00
Icon : "fab fa-slack" ,
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-11-01 14:37:20 +00:00
func parseSlackMessage ( id int64 , 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
}
2018-11-01 14:37:20 +00:00
slacker . AddQueue ( id , buf . String ( ) )
2018-09-15 01:18:21 +00:00
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-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 )
2018-11-25 10:18:21 +00:00
_ , _ , err := utils . HttpRequest ( u . Host , "POST" , "application/json" , nil , strings . NewReader ( message ) , time . Duration ( 10 * time . Second ) )
2018-11-25 03:56:09 +00:00
return err
2018-07-12 06:53:18 +00:00
}
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-11-25 10:18:21 +00:00
contents , _ , err := utils . HttpRequest ( u . Host , "POST" , "application/json" , nil , bytes . NewBuffer ( [ ] byte ( ` { "text":"testing message"} ` ) ) , time . Duration ( 10 * time . Second ) )
2018-09-26 15:26:16 +00:00
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-11-01 14:37:20 +00:00
parseSlackMessage ( s . Id , 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-11-01 14:37:20 +00:00
u . ResetUniqueQueue ( s . Id )
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-11-01 14:37:20 +00:00
parseSlackMessage ( s . Id , 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 )
2018-11-01 14:37:20 +00:00
u . AddQueue ( 0 , message )
2018-07-10 12:05:20 +00:00
return nil
}