2018-12-04 05:57:11 +00:00
// Statping
2018-10-03 08:17:25 +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-10-03 08:17:25 +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/>.
package notifiers
import (
"bytes"
"fmt"
2020-03-04 10:29:00 +00:00
"github.com/hunterlong/statping/types/failures"
"github.com/hunterlong/statping/types/notifications"
"github.com/hunterlong/statping/types/services"
2018-12-04 04:17:29 +00:00
"github.com/hunterlong/statping/utils"
2018-10-03 08:17:25 +00:00
"io/ioutil"
"net/http"
"strings"
"time"
)
const (
2019-10-25 15:13:32 +00:00
webhookMethod = "Webhook"
2018-10-03 08:17:25 +00:00
)
2018-10-06 05:00:40 +00:00
type webhooker struct {
2020-03-04 10:29:00 +00:00
* notifications . Notification
2018-10-03 08:17:25 +00:00
}
2020-03-04 10:29:00 +00:00
var Webhook = & webhooker { & notifications . Notification {
2018-10-06 05:05:50 +00:00
Method : webhookMethod ,
2018-10-06 05:00:40 +00:00
Title : "HTTP webhooker" ,
2019-01-17 22:19:18 +00:00
Description : "Send a custom HTTP request to a specific URL with your own body, headers, and parameters." ,
2018-10-03 08:17:25 +00:00
Author : "Hunter Long" ,
AuthorUrl : "https://github.com/hunterlong" ,
2018-10-21 16:22:26 +00:00
Icon : "fas fa-code-branch" ,
2018-10-03 08:17:25 +00:00
Delay : time . Duration ( 1 * time . Second ) ,
2020-03-04 10:29:00 +00:00
Form : [ ] notifications . NotificationForm { {
2018-10-03 08:17:25 +00:00
Type : "text" ,
Title : "HTTP Endpoint" ,
Placeholder : "http://webhookurl.com/JW2MCP4SKQP" ,
2019-01-17 22:19:18 +00:00
SmallText : "Insert the URL for your HTTP Requests." ,
2018-10-03 08:17:25 +00:00
DbField : "Host" ,
Required : true ,
} , {
Type : "text" ,
Title : "HTTP Method" ,
Placeholder : "POST" ,
2019-01-17 22:19:18 +00:00
SmallText : "Choose a HTTP method for example: GET, POST, DELETE, or PATCH." ,
2018-10-03 08:17:25 +00:00
DbField : "Var1" ,
Required : true ,
} , {
Type : "textarea" ,
Title : "HTTP Body" ,
Placeholder : ` { "service_id": "%s.Id", "service_name": "%s.Name"} ` ,
2018-10-03 10:47:32 +00:00
SmallText : "Optional HTTP body for a POST request. You can insert variables into your body request.<br>%service.Id, %service.Name, %service.Online<br>%failure.Issue" ,
2018-10-03 08:17:25 +00:00
DbField : "Var2" ,
} , {
Type : "text" ,
Title : "Content Type" ,
Placeholder : ` application/json ` ,
SmallText : "Optional content type for example: application/json or text/plain" ,
DbField : "api_key" ,
} , {
Type : "text" ,
Title : "Header" ,
Placeholder : "Authorization=Token12345" ,
SmallText : "Optional Headers for request use format: KEY=Value,Key=Value" ,
DbField : "api_secret" ,
} ,
} } }
2018-10-06 05:00:40 +00:00
// Send will send a HTTP Post to the webhooker API. It accepts type: string
func ( w * webhooker ) Send ( msg interface { } ) error {
2018-11-10 03:42:32 +00:00
resp , err := w . sendHttpWebhook ( msg . ( string ) )
2018-10-03 10:47:32 +00:00
if err == nil {
resp . Body . Close ( )
}
2018-10-03 08:17:25 +00:00
return err
}
2020-03-04 10:29:00 +00:00
func ( w * webhooker ) Select ( ) * notifications . Notification {
2018-10-03 08:17:25 +00:00
return w . Notification
}
2020-03-04 10:29:00 +00:00
func replaceBodyText ( body string , s * services . Service , f * failures . Failure ) string {
2019-04-30 20:57:29 +00:00
body = utils . ConvertInterface ( body , s )
body = utils . ConvertInterface ( body , f )
2018-10-03 08:17:25 +00:00
return body
}
2018-11-10 03:42:32 +00:00
func ( w * webhooker ) sendHttpWebhook ( body string ) ( * http . Response , error ) {
2019-12-28 09:01:07 +00:00
utils . Log . Infoln ( fmt . Sprintf ( "sending body: '%v' to %v as a %v request" , body , w . Host , w . Var1 ) )
2018-10-03 08:17:25 +00:00
client := new ( http . Client )
client . Timeout = time . Duration ( 10 * time . Second )
var buf * bytes . Buffer
buf = bytes . NewBuffer ( nil )
if w . Var2 != "" {
2018-11-10 03:42:32 +00:00
buf = bytes . NewBuffer ( [ ] byte ( body ) )
2018-10-03 08:17:25 +00:00
}
req , err := http . NewRequest ( w . Var1 , w . Host , buf )
if err != nil {
return nil , err
}
if w . ApiSecret != "" {
splitArray := strings . Split ( w . ApiSecret , "," )
for _ , a := range splitArray {
split := strings . Split ( a , "=" )
req . Header . Add ( split [ 0 ] , split [ 1 ] )
}
}
2018-10-11 09:25:16 +00:00
if w . ApiKey != "" {
req . Header . Add ( "Content-Type" , w . ApiKey )
2018-10-03 08:17:25 +00:00
}
2018-12-04 05:57:11 +00:00
req . Header . Set ( "User-Agent" , "Statping" )
2018-10-03 08:17:25 +00:00
resp , err := client . Do ( req )
if err != nil {
return nil , err
}
return resp , err
}
2018-10-06 05:00:40 +00:00
func ( w * webhooker ) OnTest ( ) error {
2020-03-04 10:29:00 +00:00
body := replaceBodyText ( w . Var2 , notifications . ExampleService , nil )
2018-11-10 03:42:32 +00:00
resp , err := w . sendHttpWebhook ( body )
2018-10-03 08:17:25 +00:00
if err != nil {
return err
}
defer resp . Body . Close ( )
content , err := ioutil . ReadAll ( resp . Body )
2019-12-28 09:01:07 +00:00
utils . Log . Infoln ( fmt . Sprintf ( "Webhook notifier received: '%v'" , string ( content ) ) )
2018-10-03 08:17:25 +00:00
return err
}
// OnFailure will trigger failing service
2020-03-04 10:29:00 +00:00
func ( w * webhooker ) OnFailure ( s * services . Service , f * failures . Failure ) {
2018-10-03 08:17:25 +00:00
msg := replaceBodyText ( w . Var2 , s , f )
2019-03-04 17:18:50 +00:00
w . AddQueue ( fmt . Sprintf ( "service_%v" , s . Id ) , msg )
2018-10-03 08:17:25 +00:00
}
// OnSuccess will trigger successful service
2020-03-04 10:29:00 +00:00
func ( w * webhooker ) OnSuccess ( s * services . Service ) {
2019-08-15 23:26:36 +00:00
if ! s . Online {
2019-03-04 17:18:50 +00:00
w . ResetUniqueQueue ( fmt . Sprintf ( "service_%v" , s . Id ) )
2018-10-03 08:17:25 +00:00
msg := replaceBodyText ( w . Var2 , s , nil )
2019-03-04 17:18:50 +00:00
w . AddQueue ( fmt . Sprintf ( "service_%v" , s . Id ) , msg )
2018-10-03 08:17:25 +00:00
}
}
// OnSave triggers when this notifier has been saved
2018-10-06 05:00:40 +00:00
func ( w * webhooker ) OnSave ( ) error {
2018-10-03 08:17:25 +00:00
return nil
}