According to Wikipedia, web hooks are user-defined HTTP callbacks. They are usually triggered by some event - presence events in this case. When that event occurs, the source site (the PubNub network) makes an HTTP request to the URI configured for the web hook (for the Presence add-on on your keys in your PubNub Account).

PubNub Presence provides a means for you to know when other users are joining and leaving a channel or when the user's state changes. Presence Web Hooks provide a means for your server to be notified whenever presence events occur on any channel for your keys. This provides an easy to scale solution for your server side application to monitor the presence events.

Why Web Hooks?

Without Presence Web Hooks, your server would have to subscribe to all the channels' -pnpres channels, but this can be a tedious task to stay on top of if your app has thousands of channels or more. There are network, memory and CPU limitations to your server and so you will have to scale this across multiple server instances without duplicating presence channel subscriptions. This is commonly referred to as a fan-in (many publishers to one/few subscribers) design pattern.

This can be done and has been done by some PubNub customers but it is not a solution we will be laying out in this post. If you require a fan-in architecture, please contact PubNub Support to talk to your Customer Success Manager and Solutions Architect about fan-in best practices.

So if you are going to have thousands of channels and you would rather not go down the fan-in implementation road, then you will find Web Hooks to be easier to implement and scale with traditional, well-known web infrastructure (load balancers, web and app servers provided by your application service providers like Heroku, Rackspace, Azure, Amazon and others).

PubNub Presence Web Hooks

PubNub Presence Web Hooks are a means for the PubNub network to invoke a REST endpoint your server directly as presence events occur rather than having a long running connection on your server waiting for presence events to be published. This puts the load balancer/web server/app server layers to work to handle the load in a distributed way rather than making you do the work or distributing the channel subscriptions across your server instances.

There are four user level presence events: join, leave, timeout and state-change, and two channel level events: active and inactive. You are likely familiar with the four user level presence events but perhaps the channel level events are new to you. When a channel occupancy goes from 0 to 1, it is active and when it goes from 1 to 0, it is inactive.

Each event has it's own Web Hook for which you can provide a REST endpoint to your server to handle the event. Or you can provide one REST endpoint for all of them and just implement conditional logic on the action attribute on your server to handle each individual event.

Whatever you choose, you need to provide the sub-key and the REST URIs to PubNub Support to configure this for you. You likely will have more than one sub-key with different endpoints for different server environments (dev, test, production, for example).

Once your server's REST endpoints are implemented and the PubNub key configuration is in place, you are ready to go. But before you implement the REST endpoints, it might be helpful to know what the events' data looks like (content-type is application/json). Here is an example of a join:

HTTP POST

Content-Type: application/json

{
    'action': 'join',
    'sub_key': 'sub-c-...',
    'channel': 'lacrosse'
    'uuid': '1234-5678-90ab-cdef',
    'timestamp': 1440568311,
    'occupancy': 1,
    'data': {'foo': 'bar'}
} 

This would be the same for leave and timeout and state-change except for the action value, of course. The data key/value would only be included if there was state data involved, but this is everything you need to consider.

For active and inactive, the content-type is multipart/form-data:

HTTP POST

Content-Type: multipart/form-data

status=active
timestamp=1440568311
sub_key=sub-c-...
channel=lacrosse

Status value will be active or inactive.

It might be convenient to have separate endpoints for active/inactive and join/leave/timeout/state-change, but no reason it can't be all the same endpoint.

Web Hook Response Status

It is important that your REST endpoint implementation return a 200 response code immediately upon receiving the Web Hook from PubNub. Failure to do so will result in PubNub sending duplicate events because PubNub assumes no response means your server did not receive the event.

PubNub will wait five seconds for the 200 response before trying again. After a third retry (four total attempts), PubNub will no longer attempt to send that particular event to your server.


Sample Code

You can find full code in the PubNub Support sample Presence Web Hook code repo. The code is setup so that each Web Hook event has its own path: /active, /inactive, /join, /leave, /timeout, /statechange.  But you are free use a single REST endpoint URI for multiple Web Hook events, but we encourage you to configure at lease two paths: one for active and inactive and one for all the others because active and inactive events are multipart/form-data (non-JSON) and the others are application/json (see sample for clarity).