WebHooks

WebHooks allow your server to be notified about events occurring within Pusher.

You can activate WebHooks in your account dashboard on a per app basis. For general information on WebHooks, see the webhooks.org Wiki.

WebHook Format

A WebHook is sent as a HTTP POST request to the url which you specify.

The POST request payload (body) contains a JSON document, and follows the following format:

{
  "time_ms": 1327078148132
  "events": [
    { "name": "event_name", "some": "data" }
  ]
}
  • The time_ms key provides the unix timestamp in milliseconds when the WebHook was created. This allows you to detect delayed WebHooks if necessary.
  • The events key contains one or more events. Each event contains a name, and event specific data.

Your server should respond to the POST request with a 2XX status code to indicate that the WebHook has been successfully received. If a non 2XX status code is returned, Pusher will retry sending the WebHook, with exponential backoff, for 5 minutes. This ensures that temporary failure should not affect your ability to receive all WebHooks.

Security

Encryption

You may use a HTTP or a HTTPS url for WebHooks. In most cases HTTP is sufficient, but HTTPS can be useful if your data is sensitive or if you wish to protect against replay attacks for example.

Authentication

Since anyone could in principle send WebHooks to your application, it’s important to verify that these WebHooks originated from Pusher. Valid WebHooks will therefore contain these headers which contain a HMAC signature of the WebHook payload (body):

  • X-Pusher-Key: A Pusher app may have multiple tokens. The oldest active token will be used, identified by this key.
  • X-Pusher-Signature: A HMAC SHA256 hex digest formed by signing the POST payload (body) with the token’s secret.

Events

Channel existence events

Notify your application when channels become occupied or vacated.

For example, this allows you to publish events to a channel only when somebody is actually subscribed.

channel_occupied

Pusher will send a channel_occupied event whenever any channel becomes occupied (i.e. there is at least one subscriber).

The event data for this event is as follows:

{ "name": "channel_occupied", "channel": "test_channel" }

channel_vacated

Pusher will send a channel_vacated event whenever any channel becomes vacated (i.e. there are no subscribers).

The event data for this event is as follows:

{ "name": "channel_vacated", "channel": "test_channel" }

Presence events

Notify your application whenever a user subscribes to or unsubscribes from a Presence channel.

For example, this allows you to synchronise channel presence state on your server as well as all your application clients.

member_added

Pusher will send a member_added event whenever a new user subscribes to a presence channel.

The event data for this event is as follows:

{
  "name": "member_added",
  "channel": "presence-your_channel_name",
  "user_id": "a_user_id"
}

member_removed

Pusher will send a member_removed event whenever a user unsubscribes from a presence channel.

The event data for this event is as follows:

{
  "name": "member_removed",
  "channel": "presence-your_channel_name",
  "user_id": "a_user_id"
}

Client events

Notify your application whenever a client event is sent.

Pusher will send a client_event event whenever a client event is sent on any private or presence channel.

The event data for this event is as follows:

{
  "name": "client_event",
  "channel": "name of the channel the event was published on",
  "event": "name of the event",
  "data": "data associated with the event",
  "socket_id": "socket_id of the sending socket",
  "user_id": "user_id associated with the sending socket" # Only for presence channels
}

Channel existence example

class PusherController < ApplicationController

  def webhook
    webhook = Pusher::WebHook.new(request)
    if webhook.valid?
      webhook.events.each do |event|
        case event["name"]
        when 'channel_occupied'
          puts "Channel occupied: #{event["channel"]}"
        when 'channel_vacated'
          puts "Channel vacated: #{event["channel"]}"
        end
      end
      render text: 'ok'
    else
      render text: 'invalid', status: 401
    end
  end

end
# The WebHook object should be initialised with a Rack::Request object, therefore it can be used with any Rack server. Here's a Sinatra example:
post '/webhooks' do
  webhook = Pusher::WebHook.new(request)
  if webhook.valid?
    webhook.events.each do |event|
      case event["name"]
      when 'channel_occupied'
        puts "Channel occupied: #{event["channel"]}"
      when 'channel_vacated'
        puts "Channel vacated: #{event["channel"]}"
      end
    end
  else
    status 401
  end
  return
end
<?php
  // environmental variable must be set
  $app_secret = getenv('PUSHER_APP_SECRET');

  $app_key = $_SERVER['HTTP_X_PUSHER_KEY'];
  $webhook_signature = $_SERVER ['HTTP_X_PUSHER_SIGNATURE'];
  
  $body = file_get_contents('php://input');

  $expected_signature = hash_hmac( 'sha256', $body, $app_secret, false );

  if($webhook_signature == $expected_signature) {
    // decode as associative array
    $payload = json_decode( $body, true );
    foreach($payload['events'] as &$event) {
      // do something with the event
    }

    header("Status: 200 OK");
  }
  else {
    header("Status: 401 Not authenticated");
  }
?>

Have you tried using the search to find what you’re after? If you still have a question then get in touch with us and let us help you out.