WebSocket Server

Webhook Relay provides users an ability to directly subscribe to webhooks from their applications without using our stand-alone agent.

Socket server allows connecting to Webhook Relay service directly from your application using WebSocket protocol. Communication is done using JSON encoded messages. In order to start streaming, create a new bucket with your desired name.

Once you have a bucket, you can start receiving webhooks to your public endpoint (one public endpoint will be created by default upon bucket creation).

WebSockets will receive events with webhook data when both no outputs are defined or for every internal output specified. If you only have public outputs, neither WebSockets nor relay agent will receive them.

Protocol

Step 1: Connect

Your API keys allow multiple simultaneous connections. Connect to:

wss://my.webhookrelay.com/v1/socket

Step 2: Authenticate

You must authenticate before you can make any other requests. Generate a new key & secret pair in your tokens page (https://my.webhookrelay.com/tokens). To authenticate, send:

{
    "action":"auth",
    "key":"YOUR_KEY",
    "secret":"YOUR_SECRET"
}

Once authenticated, you will receive the following message:

{
    "type": "status",
    "status": "authenticated",
    "message": "connected successfully, subscribe to buckets"
}

Step 3: Subscribe to webhooks stream

Once authenticated, you can request a stream. Buckets (https://my.webhookrelay.com/buckets) are used for grouping and routing. You can request multiple bucket streams. To subscribe, send:

{
    "action":"subscribe",
    "buckets": [ "my-1-bucket-name", "my-2-bucket-id" ]
}

Field buckets works as a filter, checking for bucket ID or bucket name. To subscribe to all buckets in your account, send only {"action":"subscribe"} message.

Once subscribed, you will receive the following message, confirming your stream:

{
    "type": "status",
    "status": "subscribed",
    "message": "subscribed to buckets: my-1-bucket-name, my-2-bucket-id"
}

Schema

All incoming webhooks will have event type set to webhook and attached meta field with additional information such as bucket ID, bucket name, input ID, input name:

{
  "type": "webhook",             // event type
  "meta": {                      // bucket, input and output information 
    "bucked_id": "1593fe5f-45f9-45cc-ba23-675fdc7c1638", 
    "bucket_name": "my-1-bucket-name",                                
    "input_id": "b90f2fe9-621d-4290-9e74-edd5b61325dd",
    "input_name": "Default public endpoint",
    "output_name": "111",
        "output_destination": "http://localhost:8080"
  },
  "headers": {                   // request headers
    "Content-Type": [
      "application/json"
    ]
  },
  "query": "foo=bar",            // query (ie: /some-path?foo=bar)
  "body": "{\"hi\": \"there\"}", // request body
  "method": "PUT"                // request method
}

Answering to pings

In order to ensure that idle connections are not cut by the load balancers and routers, our servers are constantly sending both WebSocket protocol pings and regular messages over the open connection. For better availability, please add handler in your WebSocket client that responds to:

{
    "type": "status",
    "status": "ping"
}

with a:

{
    "action": "pong"
}

message. You can view such handler in our JavaScript package here.

JavaScript Example

Here's a short example application written in JavaScript that subscribes to a stream of webhooks:

// client.js
const WebSocket = require('ws');

var server = 'wss://my.webhookrelay.com/v1/socket';
var reconnectInterval = 1000 * 3;
var ws;

var apiKey = process.env.RELAY_KEY;
var apiSecret = process.env.RELAY_SECRET;

var connect = function(){
    ws = new WebSocket(server);
    ws.on('open', function() {        
        console.log('connected, sending authentication request');
        ws.send(JSON.stringify({ action: 'auth', key: apiKey, secret: apiSecret }));
    });

    ws.on('message', function incoming(data) {
      console.log(data)

      // parse message and if we have authenticated, subscribe to our bucket
      var msg = JSON.parse(data);
      if (msg.type === 'status' && msg.status === 'authenticated') {
        ws.send(JSON.stringify({ action: 'subscribe', buckets: ['my-bucket'] }));
      }
    });

    ws.on('error', function() {
        console.log('socket error');       
    });

    ws.on('close', function() {
        console.log('socket closed, reconnecting');
        setTimeout(connect, reconnectInterval);
    });
};

connect();

To run:

1. Install websocket library ws:

npm i ws

2. Set token key and secret (from tokens page):

export RELAY_KEY=your-token-key
export RELAY_SECRET=your-token-secret

3. Start it:

node client.js

Now, if you send a webhook to your public input endpoint, you should see something similar:

$ node client.js
{"type":"status","status":"authenticated","message":"connected successfully, subscribe to buckets"}
{"type":"status","status":"subscribed","message":"subscribed to buckets: 123"}
{"type":"webhook","meta":{"bucked_id":"89e44c32-27ff-4832-8655-8a42d3851b6f","bucket_name":"123","input_id":"ee4ac550-12a4-41a7-837d-dd3356ed1771","input_name":"Default public endpoint"},"headers":{"Content-Length":["15"],"User-Agent":["insomnia/6.0.2"],"Cookie":["__cfduid=dc244a014f0b1e2965544ddb483c3fe1b1525866866"],"Content-Type":["application/json"],"Accept":["*/*"]},"query":"","body":"{\"hi\": \"there\"}","method":"PUT"}

JavaScript SDK example

Javascript library is available via npm. Library source code is available on GitHub. It's written in Typescript is a thin wrapper around our WebSocket server client. It can only subscribe to buckets but cannot create/update/delete them.

To install it:

npm i webhookrelay-ws-client

Library usage

var ws = require(`webhookrelay-ws-client`);

// handler function has to accept a JSON string and parse on its own
var handler = function (data) {
    console.log(data)
}

// create a client with specified token key and secret from https://my.webhookrelay.com/tokens and any buckets that
// can be created here https://my.webhookrelay.com/buckets. Handler function is called whenever there's a new message
var client = new ws.WebhookRelayClient('your-token-key', 'your-token-secret', ['bucket-1', 'bucket-2'], handler)

// connect starts a websocket connection to Webhook Relay 
client.connect();

Example application

Set tokens as environment variables:

export RELAY_KEY=[YOUR TOKEN KEY]
export RELAY_SECRET=[YOUR TOKEN SECRET]
// app.js
var ws = require(`webhookrelay-ws-client`);

var apiKey = process.env.RELAY_KEY;
var apiSecret = process.env.RELAY_SECRET;

var handler = function (data) {
    console.log(data)
}

var run = function () {    
    var client = new ws.WebhookRelayClient(apiKey, apiSecret, ['nodered'], handler)
    client.connect();

    // do some work

    // disconnect whenever connection is no longer needed
    setTimeout(function(){ 
        console.log('disconnecting')
        client.disconnect();
    }, 10000);
}

run();

To run it:

node app.js

Now, whenever you send webhooks to your public endpoint https://my.webhookrelay.com/v1/webhooks/<your input ID>, they will be received inside your application. You can subscribe to multiple buckets. Each message will have a JSON string that you can parse:

{
  "type": "webhook",             // event type
  "meta": {                      // bucket, input and output information 
    "bucked_id": "1593fe5f-45f9-45cc-ba23-675fdc7c1638", 
    "bucket_name": "my-1-bucket-name",                                
    "input_id": "b90f2fe9-621d-4290-9e74-edd5b61325dd",
    "input_name": "Default public endpoint",
    "output_name": "111",
        "output_destination": "http://localhost:8080"
  },
  "headers": {                   // request headers
    "Content-Type": [
      "application/json"
    ]
  },
  "query": "foo=bar",            // query (ie: /some-path?foo=bar)
  "body": "{\"hi\": \"there\"}", // request body
  "method": "PUT"                // request method
}

Last updated