[GH-ISSUE #52] Feature Request: Webhook Variables #29

Closed
opened 2026-02-25 23:40:50 +03:00 by kerem · 7 comments
Owner

Originally created by @stevenmcastano on GitHub (Apr 6, 2016).
Original GitHub issue: https://github.com/healthchecks/healthchecks/issues/52

Based on our previous conversation:

Possibly writing web hooks with variable in them?

Can you please open a separate issue for this? I'm guessing the interesting variables would be check's status (up/down) and its name and code.

Yes, exactly what you suggested would be great, I basically have a service that's got TONS of notification options built into it including a pretty easy to hit http/https REST API.

So, if I wanted to send a message out, I'd do it like this:

http://notificationcentral.mydomain.com/api/v3.0/send?subject=Health Check Down&message=Check Backup Cron Job has missed a ping&priority=1&selectcode=xpg

Basically, the stuff that's a little more static, I'd love to make it so a "DOWN" notification gets a variable called maybe 'severity' and it's '1' for down '0' for up, that way services can actually use different sounds and styles... my app supports everything from '-5' up to '5' meaning '-5' send me a message but don't make a noise and it can be quick, or '0' hey this is info look at it, then finally '5' "OMG OMG OMG, I'm going to beep, buzz and play EVERYTHING until you acknowledge this!

The "selectcode" is something that can by typed into the webhook when that make it like 'x' sends the messages to XBMC/Kodi, 'p' for Pushover. 'b' for PushBullet, 'e' for email, 'g' for Growl or 'a' for "all services".

So basically I would love to have a variable for the "subject", "message" and "priority", and maybe a setting for each check for the priority level of the up and down values, if not 1 for down, 0 for up.

Does that sound possible?

Originally created by @stevenmcastano on GitHub (Apr 6, 2016). Original GitHub issue: https://github.com/healthchecks/healthchecks/issues/52 Based on our previous conversation: > Possibly writing web hooks with variable in them? > > Can you please open a separate issue for this? I'm guessing the interesting variables would be check's status (up/down) and its name and code. Yes, exactly what you suggested would be great, I basically have a service that's got TONS of notification options built into it including a pretty easy to hit http/https REST API. So, if I wanted to send a message out, I'd do it like this: http://notificationcentral.mydomain.com/api/v3.0/send?subject=Health Check Down&message=Check Backup Cron Job has missed a ping&priority=1&selectcode=xpg Basically, the stuff that's a little more static, I'd love to make it so a "DOWN" notification gets a variable called maybe 'severity' and it's '1' for down '0' for up, that way services can actually use different sounds and styles... my app supports everything from '-5' up to '5' meaning '-5' send me a message but don't make a noise and it can be quick, or '0' hey this is info look at it, then finally '5' "OMG OMG OMG, I'm going to beep, buzz and play EVERYTHING until you acknowledge this! The "selectcode" is something that can by typed into the webhook when that make it like 'x' sends the messages to XBMC/Kodi, 'p' for Pushover. 'b' for PushBullet, 'e' for email, 'g' for Growl or 'a' for "all services". So basically I would love to have a variable for the "subject", "message" and "priority", and maybe a setting for each check for the priority level of the up and down values, if not 1 for down, 0 for up. Does that sound possible?
kerem closed this issue 2026-02-25 23:40:50 +03:00
Author
Owner

@cuu508 commented on GitHub (Apr 8, 2016):

OK, so I'm thinking about adding two separate features for webhooks.

First one is variables in webhook URLs. The following tokens would be replaced with actual values if they appear anywhere in the webhook URL:

  • $NAME name of the check (or code, if name is empty)
  • $CODE the assigned code for the check
  • $STATUS – either "up" or "down"
  • $TAG1, $TAG2, $TAG3, ... – 1st, 2nd, 3rd etc. tag

Your webhook URL would look something like:

http://notificationcentral.mydomain.com/api/v3.0/send?subject=Health Check Down&message=Check $NAME has missed a ping&priority=$TAG1&selectcode=$TAG2 

I'm not dead set on the exact syntax for placeholders. Maybe there is an argument for having e.g. {name} or {{ name }} or something else instead of $NAME?

The second feature: when you set up a webhook, let user enter two separate URLs, one for "down" events and the other for "up" events. If either is left blank, these events don't get reported. In the second webhook URL field you would then put:

http://notificationcentral.mydomain.com/api/v3.0/send?subject=Health Check Up&message=Check $NAME has received a ping&priority=$TAG1&selectcode=$TAG2  
<!-- gh-comment-id:207406426 --> @cuu508 commented on GitHub (Apr 8, 2016): OK, so I'm thinking about adding two separate features for webhooks. First one is variables in webhook URLs. The following tokens would be replaced with actual values if they appear anywhere in the webhook URL: - `$NAME` name of the check (or code, if name is empty) - `$CODE` the assigned code for the check - `$STATUS` – either "up" or "down" - `$TAG1`, `$TAG2`, `$TAG3`, ... – 1st, 2nd, 3rd etc. tag Your webhook URL would look something like: ``` http://notificationcentral.mydomain.com/api/v3.0/send?subject=Health Check Down&message=Check $NAME has missed a ping&priority=$TAG1&selectcode=$TAG2 ``` I'm not dead set on the exact syntax for placeholders. Maybe there is an argument for having e.g. `{name}` or `{{ name }}` or something else instead of `$NAME`? The second feature: when you set up a webhook, let user enter two separate URLs, one for "down" events and the other for "up" events. If either is left blank, these events don't get reported. In the second webhook URL field you would then put: ``` http://notificationcentral.mydomain.com/api/v3.0/send?subject=Health Check Up&message=Check $NAME has received a ping&priority=$TAG1&selectcode=$TAG2 ```
Author
Owner

@stevenmcastano commented on GitHub (Apr 10, 2016):

Yeah, that sounds great!! I especially like the second notification so you have one for "up" and one for "down", that would surely allow a system like mine to assign a priority setting to each like a "high" for down and "low" for up.

I might suggest also, that you put in the ability to sent notifications, 1 for warn, and 1 for clear... or maybe make the total 3

1) Check is "late"
2) Check is "down"
3) Check is "clear"

That might lead to a little bit more "proactive" ability to monitor on systems with a longer grace period.

<!-- gh-comment-id:208015106 --> @stevenmcastano commented on GitHub (Apr 10, 2016): Yeah, that sounds great!! I especially like the second notification so you have one for "up" and one for "down", that would surely allow a system like mine to assign a priority setting to each like a "high" for down and "low" for up. I might suggest also, that you put in the ability to sent notifications, 1 for warn, and 1 for clear... or maybe make the total 3 ``` 1) Check is "late" 2) Check is "down" 3) Check is "clear" ``` That might lead to a little bit more "proactive" ability to monitor on systems with a longer grace period.
Author
Owner

@brumle80 commented on GitHub (Apr 14, 2016):

this would also help with integrating with mattermost, as it really borks then channel you try and output to atm if you try the slack integration and webhook integration just fails atm.

http://docs.mattermost.com/developer/webhooks-incoming.html

<!-- gh-comment-id:209933453 --> @brumle80 commented on GitHub (Apr 14, 2016): this would also help with integrating with mattermost, as it really borks then channel you try and output to atm if you try the slack integration and webhook integration just fails atm. http://docs.mattermost.com/developer/webhooks-incoming.html
Author
Owner

@cuu508 commented on GitHub (Apr 14, 2016):

@brumle80 tried Slack integration with Mattermost.

On v2.1 it looks like the incoming webhooks don't work at (ticket: https://github.com/mattermost/platform/issues/2659)
On v2.0 yep, I saw what you meant by "really borks the channel".

I would prefer to use Slack integration for Mattermost, as it should get us nicer-looking notifications than webhooks. Just need to figure out what exactly in the notification payload trips Mattermost up.

<!-- gh-comment-id:209990828 --> @cuu508 commented on GitHub (Apr 14, 2016): @brumle80 tried Slack integration with Mattermost. On v2.1 it looks like the incoming webhooks don't work at (ticket: https://github.com/mattermost/platform/issues/2659) On v2.0 yep, I saw what you meant by "really borks the channel". I would prefer to use Slack integration for Mattermost, as it should get us nicer-looking notifications than webhooks. Just need to figure out what exactly in the notification payload trips Mattermost up.
Author
Owner

@brumle80 commented on GitHub (Apr 14, 2016):

we had to delete the channel messages from the database for the channel to start working again, but here are what we could se from the logs, it complains about missing details like what name to post as, not sure if this helps.

logs from mattermost:

`[2016/04/14 14:08:08 CEST] [EROR] /api/v1/admin/log_client:client code=0 rid=agyk8uen7fd3mcy8mny34bn6ny uid=usshnu6kzjntzfmi87jdfygqgr ip=*.*.*.238 msg: TypeError: M[e] is undefined row: 15 col: 18448 stack: TypeError: M[e] is undefined url: https://domain.name.no/static/js/react-0.14.3.min.js [details: ]
[2016/04/14 14:08:08 CEST] [EROR] /api/v1/admin/log_client:client code=0 rid=4yib4qo7ajb8beecqqrb9oew4y uid=usshnu6kzjntzfmi87jdfygqgr ip=*.*.*.238 msg: TypeError: M[e] is undefined row: 15 col: 18448 stack: TypeError: M[e] is undefined url: https://domain.name.no/static/js/react-0.14.3.min.js [details: ]
[2016/04/14 14:08:09 CEST] [EROR] /api/v1/admin/log_client:client code=0 rid=myabmq9zjpyetj5et5gktcknpy uid=usshnu6kzjntzfmi87jdfygqgr ip=*.*.*.238 msg: TypeError: i is null row: 13 col: 13083 stack: TypeError: i is null url: https://domain.name.no/static/js/react-0.14.3.min.js [details: ]
[2016/04/14 14:08:09 CEST] [EROR] /api/v1/admin/log_client:client code=0 rid=scgoreds67fh7ea45eqkyr1roo uid=usshnu6kzjntzfmi87jdfygqgr ip=*.*.*.238 msg: TypeError: i is null row: 13 col: 13083 stack: TypeError: i is null url: https://domain.name.no/static/js/react-0.14.3.min.js [details: ]

portion of sql we had to fix:

| 81jfcq9jpirpi8tf5mrngogwnh | 1460633552243 | 1460633552243 |        0 | usshnu6kzjntzfmi87jdfygqgr | oqxk4x4ttfrpz81t3yubruwpio |        |          |            |         | slack_attachment | {"attachments":[{"color":"good","fallback":"The check \"test\" is UP.","fields":[{"short":true,"title":"Period","value":"1 minute "},{"short":true,"title":"Last Ping","value":"now"},{"short":true,"title":"Tags","value":"`bash` "},{"short":true,"title":"Total Pings","value":4}],"mrkdwn_in":["fields"],"text":"“test” is UP."}],"from_webhook":"true","override_icon_url":"https://healthchecks.io/static/img/logo@2x.png","override_username":"healthchecks.io"}                      |          | []        |
| tq4gysan8py4pbziw4kbboh9ch | 1460633732759 | 1460633732759 |        0 | usshnu6kzjntzfmi87jdfygqgr | oqxk4x4ttfrpz81t3yubruwpio |        |          |            |         | slack_attachment | {"attachments":[{"color":"danger","fallback":"The check \"test\" is DOWN.","fields":[{"short":true,"title":"Period","value":"1 minute "},{"short":true,"title":"Last Ping","value":"3 minutes ago"},{"short":true,"title":"Tags","value":"`bash` "},{"short":true,"title":"Total Pings","value":4}],"mrkdwn_in":["fields"],"text":"“test” is DOWN."}],"from_webhook":"true","override_icon_url":"https://healthchecks.io/static/img/logo@2x.png","override_username":"healthchecks.io"}      |          | []        |
| Id                         | CreateAt      | UpdateAt      | DeleteAt | UserId                     | ChannelId                  | RootId | ParentId | OriginalId | Message | Type             | Props                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | Hashtags | Filenames |
| 81jfcq9jpirpi8tf5mrngogwnh | 1460633552243 | 1460633552243 |        0 | usshnu6kzjntzfmi87jdfygqgr | oqxk4x4ttfrpz81t3yubruwpio |        |          |            |         | slack_attachment | {"attachments":[{"color":"good","fallback":"The check \"test\" is UP.","fields":[{"short":true,"title":"Period","value":"1 minute "},{"short":true,"title":"Last Ping","value":"now"},{"short":true,"title":"Tags","value":"`bash` "},{"short":true,"title":"Total Pings","value":4}],"mrkdwn_in":["fields"],"text":"“test” is UP."}],"from_webhook":"true","override_icon_url":"https://healthchecks.io/static/img/logo@2x.png","override_username":"healthchecks.io"}                      |          | []        |
| tq4gysan8py4pbziw4kbboh9ch | 1460633732759 | 1460633732759 |        0 | usshnu6kzjntzfmi87jdfygqgr | oqxk4x4ttfrpz81t3yubruwpio |        |          |            |         | slack_attachment | {"attachments":[{"color":"danger","fallback":"The check \"test\" is DOWN.","fields":[{"short":true,"title":"Period","value":"1 minute "},{"short":true,"title":"Last Ping","value":"3 minutes ago"},{"short":true,"title":"Tags","value":"`bash` "},{"short":true,"title":"Total Pings","value":4}],"mrkdwn_in":["fields"],"text":"“test” is DOWN."}],"from_webhook":"true","override_icon_url":"https://healthchecks.io/static/img/logo@2x.png","override_username":"healthchecks.io"}      |          | []        |
<!-- gh-comment-id:210000442 --> @brumle80 commented on GitHub (Apr 14, 2016): we had to delete the channel messages from the database for the channel to start working again, but here are what we could se from the logs, it complains about missing details like what name to post as, not sure if this helps. logs from mattermost: ``` `[2016/04/14 14:08:08 CEST] [EROR] /api/v1/admin/log_client:client code=0 rid=agyk8uen7fd3mcy8mny34bn6ny uid=usshnu6kzjntzfmi87jdfygqgr ip=*.*.*.238 msg: TypeError: M[e] is undefined row: 15 col: 18448 stack: TypeError: M[e] is undefined url: https://domain.name.no/static/js/react-0.14.3.min.js [details: ] [2016/04/14 14:08:08 CEST] [EROR] /api/v1/admin/log_client:client code=0 rid=4yib4qo7ajb8beecqqrb9oew4y uid=usshnu6kzjntzfmi87jdfygqgr ip=*.*.*.238 msg: TypeError: M[e] is undefined row: 15 col: 18448 stack: TypeError: M[e] is undefined url: https://domain.name.no/static/js/react-0.14.3.min.js [details: ] [2016/04/14 14:08:09 CEST] [EROR] /api/v1/admin/log_client:client code=0 rid=myabmq9zjpyetj5et5gktcknpy uid=usshnu6kzjntzfmi87jdfygqgr ip=*.*.*.238 msg: TypeError: i is null row: 13 col: 13083 stack: TypeError: i is null url: https://domain.name.no/static/js/react-0.14.3.min.js [details: ] [2016/04/14 14:08:09 CEST] [EROR] /api/v1/admin/log_client:client code=0 rid=scgoreds67fh7ea45eqkyr1roo uid=usshnu6kzjntzfmi87jdfygqgr ip=*.*.*.238 msg: TypeError: i is null row: 13 col: 13083 stack: TypeError: i is null url: https://domain.name.no/static/js/react-0.14.3.min.js [details: ] ``` portion of sql we had to fix: ``` | 81jfcq9jpirpi8tf5mrngogwnh | 1460633552243 | 1460633552243 | 0 | usshnu6kzjntzfmi87jdfygqgr | oqxk4x4ttfrpz81t3yubruwpio | | | | | slack_attachment | {"attachments":[{"color":"good","fallback":"The check \"test\" is UP.","fields":[{"short":true,"title":"Period","value":"1 minute "},{"short":true,"title":"Last Ping","value":"now"},{"short":true,"title":"Tags","value":"`bash` "},{"short":true,"title":"Total Pings","value":4}],"mrkdwn_in":["fields"],"text":"“test” is UP."}],"from_webhook":"true","override_icon_url":"https://healthchecks.io/static/img/logo@2x.png","override_username":"healthchecks.io"} | | [] | | tq4gysan8py4pbziw4kbboh9ch | 1460633732759 | 1460633732759 | 0 | usshnu6kzjntzfmi87jdfygqgr | oqxk4x4ttfrpz81t3yubruwpio | | | | | slack_attachment | {"attachments":[{"color":"danger","fallback":"The check \"test\" is DOWN.","fields":[{"short":true,"title":"Period","value":"1 minute "},{"short":true,"title":"Last Ping","value":"3 minutes ago"},{"short":true,"title":"Tags","value":"`bash` "},{"short":true,"title":"Total Pings","value":4}],"mrkdwn_in":["fields"],"text":"“test” is DOWN."}],"from_webhook":"true","override_icon_url":"https://healthchecks.io/static/img/logo@2x.png","override_username":"healthchecks.io"} | | [] | ``` ``` | Id | CreateAt | UpdateAt | DeleteAt | UserId | ChannelId | RootId | ParentId | OriginalId | Message | Type | Props | Hashtags | Filenames | | 81jfcq9jpirpi8tf5mrngogwnh | 1460633552243 | 1460633552243 | 0 | usshnu6kzjntzfmi87jdfygqgr | oqxk4x4ttfrpz81t3yubruwpio | | | | | slack_attachment | {"attachments":[{"color":"good","fallback":"The check \"test\" is UP.","fields":[{"short":true,"title":"Period","value":"1 minute "},{"short":true,"title":"Last Ping","value":"now"},{"short":true,"title":"Tags","value":"`bash` "},{"short":true,"title":"Total Pings","value":4}],"mrkdwn_in":["fields"],"text":"“test” is UP."}],"from_webhook":"true","override_icon_url":"https://healthchecks.io/static/img/logo@2x.png","override_username":"healthchecks.io"} | | [] | | tq4gysan8py4pbziw4kbboh9ch | 1460633732759 | 1460633732759 | 0 | usshnu6kzjntzfmi87jdfygqgr | oqxk4x4ttfrpz81t3yubruwpio | | | | | slack_attachment | {"attachments":[{"color":"danger","fallback":"The check \"test\" is DOWN.","fields":[{"short":true,"title":"Period","value":"1 minute "},{"short":true,"title":"Last Ping","value":"3 minutes ago"},{"short":true,"title":"Tags","value":"`bash` "},{"short":true,"title":"Total Pings","value":4}],"mrkdwn_in":["fields"],"text":"“test” is DOWN."}],"from_webhook":"true","override_icon_url":"https://healthchecks.io/static/img/logo@2x.png","override_username":"healthchecks.io"} | | [] | ```
Author
Owner

@cuu508 commented on GitHub (Apr 14, 2016):

@brumle80 think I've managed to track down the problem with Mattermost: it assumes all fields in JSON payload will be strings, but one of the fields was actually an integer ("Total Pings"). So I changed it to string.

I've deployed this fix on https://healthchecks.io, so when you get a chance you can try the Slack integration with Mattermost again. Maybe try with a throwaway channel first...

<!-- gh-comment-id:210153221 --> @cuu508 commented on GitHub (Apr 14, 2016): @brumle80 think I've managed to track down the problem with Mattermost: it assumes all fields in JSON payload will be strings, but one of the fields was actually an integer ("Total Pings"). So I changed it to string. I've deployed this fix on https://healthchecks.io, so when you get a chance you can try the Slack integration with Mattermost again. Maybe try with a throwaway channel first...
Author
Owner

@brumle80 commented on GitHub (Apr 15, 2016):

tested and works perfectly :)

<!-- gh-comment-id:210348888 --> @brumle80 commented on GitHub (Apr 15, 2016): tested and works perfectly :)
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/healthchecks#29
No description provided.