Webhooks are great in principle, but it looks like there is no established standard or services are randomly deviating from it, or both.

So, I had the tedious problem of wanting to send notifications via webhook from pingdom to discord for reasons™, but it did not work. Thankfully, it is trivial to make a webhook proxy. Some tipps on how to deploy it follow below.

Install node.js on your server.

But not a super old terrible 0.10.x version of node.js, a relatively recent one.
On Debian and Ubuntu, I like to use this installation option instead of the other package manager options described on the website. Note the difference between 0.10.x and 10.x.x: The first is the terrible version you get in some package managers, the second is the current stable branch.

Find a node.js script for receiving webhooks:


var express = require('express'),
    bodyParser = require('body-parser'),
    app = express(),
    port = 3000;

app.post('/', function (req, res) {
    var body = req.body;
    console.log(body) // TODO add code to do something with webhook message body
        message: 'ok got it whatever'

var server = app.listen(port, function () {
        var host = server.address().address
        var port = server.address().port
        console.log('Webhook app listening at http://%s:%s', host, port)

Run the script

Make sure to install the depencies using npm install express and npm install body-parser in the directory where you put the script first.

Put a webserver configured as a proxy for localhost:3000 with a letsencrypt cert in front if your script

...so that your messages don't travel across the web in plain text. For example your could map the webhook proxy script to a subdomain like this in nginx:

server {
        listen 443 ssl http2;
        listen [::]:443 ssl http2;
        ssl_certificate /path/to/certchain;
        ssl_certificate_key /path/to/privkey;
        server_name pingdomproxy.example.com;
    location / {

This will result in a webhook pointing at https://pingdomproxy.example.com being forwarded to the node.js script, given that you configured your DNS settings correctly: An A record on the example.com domain mapping pingdomproxy to your server IP.
Note that there is no authentication, so if your webhook controls anything important, make sure to add that. Chances are, the service that calls your webhook proxy (here: pingdom) does not support any real authentication, but I'm sure you can find some field that gets sent in the webhook where you can stuff a static token somehow. For example, you could add a tag to your pingdom check called superSekritPassword and check for that in the body variable before you forward the hook.

Register your node.js script with systemd

...so when the script crashes once in a while or the server reboots, the script gets restarted.


Description=Webhook proxy for pingdom to discord


ExecStart=/usr/bin/node pingdomproxy.js
systemctl enable pingdomproxy
systemctl start pingdomproxy

Using specific, consistent naming really helps.

Forward the webhook

...to discord in this example, according to the specs of your target service' HTTP API. I personally like to use the node-fetch npm package for this, which implements the same syntax that you can use in browser javascript as well. So for this project, the code looks like this:

const fetch = require('node-fetch');

/*old code here that calls sendToDiscord*/

async function sendToDiscord(message){
    const headers = {
        'Content-Type': 'application/json'
    const url = 'https://discordapp.com/api/webhooks/124567890123456789/longCredentialsStringApiKeyWhateverFromDiscord'
    const res = await fetch(url, {
        body: JSON.stringify(message),
        method: 'post',
        headers: new fetch.Headers(headers),

The Discord API servers are picky about long messages, so careful about that.