add json body, Pushbullet example
This commit is contained in:
parent
4b9230bd90
commit
7b84c74754
49
README.md
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.
|
`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>
|
||||||
<details>
|
<details>
|
||||||
<summary>How to use with Twilio</summary>
|
<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>
|
<details>
|
||||||
<summary>How to use with Nexmo, Mailjet, and other webhook-enabled services</summary>
|
<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.
|
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.
|
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.
|
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
|
```json
|
||||||
{
|
{
|
||||||
|
@ -208,7 +237,7 @@ The examples below are shown with Twilio and Mailgun, as taken from their `curl`
|
||||||
"name": "Example Site",
|
"name": "Example Site",
|
||||||
"url": "https://example.com/",
|
"url": "https://example.com/",
|
||||||
"keywords": "My Site",
|
"keywords": "My Site",
|
||||||
"webhooks": ["my_mailgun", "my_twilio"],
|
"webhooks": ["my_mailgun", "my_pushbullet", "my_twilio"],
|
||||||
"recover_script": "systemctl restart example-site"
|
"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."
|
"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",
|
"name": "my_twilio",
|
||||||
"method": "POST",
|
"method": "POST",
|
||||||
|
|
32
watchdog.go
32
watchdog.go
|
@ -138,7 +138,10 @@ func (d *Dog) watch() {
|
||||||
err := d.check()
|
err := d.check()
|
||||||
if nil != err {
|
if nil != err {
|
||||||
failure = true
|
failure = true
|
||||||
|
} else {
|
||||||
|
failure = false
|
||||||
}
|
}
|
||||||
|
|
||||||
// We should notify if
|
// We should notify if
|
||||||
// * We've had success since the last notification
|
// * We've had success since the last notification
|
||||||
// * It's been at least 5 minutes 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) {
|
if d.lastPassed.After(d.lastNotified) && d.lastNotified.Before(fiveMinutesAgo) {
|
||||||
d.notify(failure)
|
d.notify(failure)
|
||||||
}
|
}
|
||||||
if d.failures >= 5 {
|
if !failure || d.failures >= 5 {
|
||||||
// go back to the main 5-minute loop
|
// go back to the main 5-minute loop
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -213,7 +216,7 @@ func (d *Dog) recover() {
|
||||||
err = cmd.Wait()
|
err = cmd.Wait()
|
||||||
cancel()
|
cancel()
|
||||||
if nil != err {
|
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 body *strings.Reader
|
||||||
|
var err error
|
||||||
|
// TODO real templates
|
||||||
if 0 != len(h.Form) {
|
if 0 != len(h.Form) {
|
||||||
form := url.Values{}
|
form := url.Values{}
|
||||||
for k := range h.Form {
|
for k := range h.Form {
|
||||||
v := h.Form[k]
|
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)
|
v = strings.Replace(v, "{{ .Name }}", d.Name, -1)
|
||||||
|
d.logger <- fmt.Sprintf("[HEADER] %s: %s", k, v)
|
||||||
form.Set(k, v)
|
form.Set(k, v)
|
||||||
}
|
}
|
||||||
body = strings.NewReader(form.Encode())
|
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()
|
client := NewHTTPClient()
|
||||||
req, err := http.NewRequest(h.Method, h.URL, body)
|
req, err := http.NewRequest(h.Method, h.URL, body)
|
||||||
if nil != err {
|
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
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if 0 != len(h.Form) {
|
if 0 != len(h.Form) {
|
||||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
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) {
|
if 0 != len(h.Auth) {
|
||||||
|
@ -282,12 +299,12 @@ func (d *Dog) notify(hardFail bool) {
|
||||||
|
|
||||||
resp, err := client.Do(req)
|
resp, err := client.Do(req)
|
||||||
if nil != err {
|
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
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if !(resp.StatusCode >= 200 && resp.StatusCode < 300) {
|
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
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -297,7 +314,7 @@ func (d *Dog) notify(hardFail bool) {
|
||||||
decoder := json.NewDecoder(resp.Body)
|
decoder := json.NewDecoder(resp.Body)
|
||||||
err = decoder.Decode(&data)
|
err = decoder.Decode(&data)
|
||||||
if err != nil {
|
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
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -326,6 +343,7 @@ type ConfigWebhook struct {
|
||||||
Auth map[string]string `json:"auth"`
|
Auth map[string]string `json:"auth"`
|
||||||
Headers map[string]string `json:"headers"`
|
Headers map[string]string `json:"headers"`
|
||||||
Form map[string]string `json:"form"`
|
Form map[string]string `json:"form"`
|
||||||
|
JSON map[string]string `json:"json"`
|
||||||
Config map[string]string `json:"config"`
|
Config map[string]string `json:"config"`
|
||||||
Configs []map[string]string `json:"configs"`
|
Configs []map[string]string `json:"configs"`
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue