Browse Source

add json body, Pushbullet example

cmd
AJ ONeal 5 years ago
parent
commit
7b84c74754
  1. 49
      README.md
  2. 32
      watchdog.go

49
README.md

@ -147,6 +147,35 @@ The `from` address can be _any_ domain in your mailgun account.
`subject` is the plain-text subject and `text` must be plain-text (not html) email contents.
</details>
<details>
<summary>How to use with Pushbullet</summary>
Pushbullet is a push notification service that I found pretty easy to work with.
I logged in with my iPhone through facebook, as well as in a web browser,
grabbed the API token, and I was able to test the documentation all in just a few minutes.
### `my_pushbullet`
Replace `my_pushbullet` with whatever name you like, or leave it the same.
It's an arbitrary name for you to reference.
For example, you may have different Pushbullet configurations for different domains.
### `xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx`
Replace `xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx` in the HTTP Access-Token header
with your API token.
You'll find this on the Pushbullet dashboard under Settings, Account, Access Tokens,
and you'll have to click to create it:
- <https://www.pushbullet.com/#settings/account>
The example was taken from the Pushbullet API documentation:
- <https://docs.pushbullet.com/#create-push>
</details>
<details>
<summary>How to use with Twilio</summary>
@ -188,7 +217,7 @@ All phone numbers should have the country code prefix (`+1` for USA) attached.
<details>
<summary>How to use with Nexmo, Mailjet, and other webhook-enabled services</summary>
See the examples of Twilio and Mailgun.
See the examples of Mailgun, Pushbullet, Twilio.
Look for "curl" in the documentation of the service that you're using.
It should be fairly easy to just look at the headers that are being set and repeat.
@ -199,7 +228,7 @@ It should be fairly easy to just look at the headers that are being set and repe
You can set notifications for _any_ service that supports HTTPS webhooks.
The examples below are shown with Twilio and Mailgun, as taken from their `curl` documentation.
The examples below are shown with Mailgun, Pushbullet, and Twilio, as taken from their `curl` documentation.
```json
{
@ -208,7 +237,7 @@ The examples below are shown with Twilio and Mailgun, as taken from their `curl`
"name": "Example Site",
"url": "https://example.com/",
"keywords": "My Site",
"webhooks": ["my_mailgun", "my_twilio"],
"webhooks": ["my_mailgun", "my_pushbullet", "my_twilio"],
"recover_script": "systemctl restart example-site"
}
],
@ -231,6 +260,20 @@ The examples below are shown with Twilio and Mailgun, as taken from their `curl`
"text": "The system is down. Check up on {{ .Name }} ASAP."
}
},
{
"name": "my_pushbullet",
"method": "POST",
"url": "https://api.pushbullet.com/v2/pushes",
"headers": {
"Access-Token": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"User-Agent": "Watchdog/1.0"
},
"json": {
"body": "The system is down. Check up on {{ .Name }} ASAP.",
"title": "{{ .Name }} is down.",
"type": "note"
}
},
{
"name": "my_twilio",
"method": "POST",

32
watchdog.go

@ -138,7 +138,10 @@ func (d *Dog) watch() {
err := d.check()
if nil != err {
failure = true
} else {
failure = false
}
// We should notify if
// * We've had success since the last notification
// * It's been at least 5 minutes since the last notification
@ -146,7 +149,7 @@ func (d *Dog) watch() {
if d.lastPassed.After(d.lastNotified) && d.lastNotified.Before(fiveMinutesAgo) {
d.notify(failure)
}
if d.failures >= 5 {
if !failure || d.failures >= 5 {
// go back to the main 5-minute loop
break
}
@ -213,7 +216,7 @@ func (d *Dog) recover() {
err = cmd.Wait()
cancel()
if nil != err {
d.logger <- fmt.Sprintf("[Recover] '%s' failed: %s", d.Recover, err)
d.logger <- fmt.Sprintf("[Recover] '%s' failed for '%s': %s", d.Recover, d.Name, err)
}
}
@ -241,26 +244,40 @@ func (d *Dog) notify(hardFail bool) {
}
var body *strings.Reader
var err error
// TODO real templates
if 0 != len(h.Form) {
form := url.Values{}
for k := range h.Form {
v := h.Form[k]
// TODO real templates
// because `{{` gets urlencoded
//k = strings.Replace(k, "{{ .Name }}", d.Name, -1)
v = strings.Replace(v, "{{ .Name }}", d.Name, -1)
d.logger <- fmt.Sprintf("[HEADER] %s: %s", k, v)
form.Set(k, v)
}
body = strings.NewReader(form.Encode())
} else if 0 != len(h.JSON) {
bodyBuf, err := json.Marshal(h.JSON)
if nil != err {
d.logger <- fmt.Sprintf("[Notify] JSON Marshal Error for '%s': %s", h.Name, err)
continue
}
// `{{` should be left alone
body = strings.NewReader(strings.Replace(string(bodyBuf), "{{ .Name }}", d.Name, -1))
}
client := NewHTTPClient()
req, err := http.NewRequest(h.Method, h.URL, body)
if nil != err {
log.Println("[Notify] HTTP Client Network Error:", err)
d.logger <- fmt.Sprintf("[Notify] HTTP Client Network Error for '%s': %s", h.Name, err)
continue
}
if 0 != len(h.Form) {
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
} else if 0 != len(h.JSON) {
req.Header.Set("Content-Type", "application/json")
}
if 0 != len(h.Auth) {
@ -282,12 +299,12 @@ func (d *Dog) notify(hardFail bool) {
resp, err := client.Do(req)
if nil != err {
d.logger <- fmt.Sprintf("[Notify] HTTP Client Error: %s", err)
d.logger <- fmt.Sprintf("[Notify] HTTP Client Error for '%s': %s", h.Name, err)
continue
}
if !(resp.StatusCode >= 200 && resp.StatusCode < 300) {
d.logger <- fmt.Sprintf("[Notify] Response Error: %s", resp.Status)
d.logger <- fmt.Sprintf("[Notify] Response Error for '%s': %s", h.Name, resp.Status)
continue
}
@ -297,7 +314,7 @@ func (d *Dog) notify(hardFail bool) {
decoder := json.NewDecoder(resp.Body)
err = decoder.Decode(&data)
if err != nil {
d.logger <- fmt.Sprintf("[Notify] Response Body Error: %s", resp.Status)
d.logger <- fmt.Sprintf("[Notify] Response Body Error for '%s': %s", h.Name, resp.Status)
continue
}
@ -326,6 +343,7 @@ type ConfigWebhook struct {
Auth map[string]string `json:"auth"`
Headers map[string]string `json:"headers"`
Form map[string]string `json:"form"`
JSON map[string]string `json:"json"`
Config map[string]string `json:"config"`
Configs []map[string]string `json:"configs"`
}

Loading…
Cancel
Save