This document acts as a guide for attendees at hackathons sponsored by Pusher.

If you haven’t heard of Pusher before, we provide you with a super simple hosted API that lets you easily (in less than 10 lines of code) build awesome realtime hacks that will wow the judges like:

  • Remote controlling things (like robots)

  • In-app collaboration

  • Realtime multiplayer games

  • 1-to-1 or group chat

  • Second-screen apps

All of these are made super easy to build with our API. We have libraries for all languages and it’s free.

We hope this guide proves useful to you, and that you enjoy using Pusher. Happy hacking!

If you get stuck or would like some help, check out our docs or tweet us, we’d be happy to help!

Getting Started

Go onto our website. If you’re new to Pusher, sign up for a free account.

You can create a new application if you wish - or just use your default 'Main' application. Take note of your app credentials: the app_id, key and secret.

Triggering Events

Quick terminology rundown: in Pusher, one uses channels to organize your realtime data. For instance, you might have a notifications-channel which contains all incoming data regarding notifications. Events have a name (e.g. new_notification) and a payload (e.g. {message: 'hello world). Events, and their data, are received in realtime by all clients subscribed to a channel.

First of all we install the Pusher package relevant to your app. For instance, gem install pusher, npm install pusher, pip install pusher and so on.

Then we import the package and instantiate a new Pusher connection. The example below uses the NodeJS package.

Then we call trigger on our Pusher instance, passing in the name of the channel, the name of the event, and the payload we wish to send over.

var Pusher = require('pusher'); (1)

var pusher = new Pusher({
  appId: YOUR_APP_ID,
  key: YOUR_APP_KEY,
  secret: YOUR_APP_SECRET
}); (2)

pusher.trigger('test_channel', 'my_event', {
  "message": "hello world"
}); (3)
1 Import Pusher.
2 Create a Pusher object with your app credentials.
3 Make your Pusher object trigger my_event on test_channel, with the payload of {"message": "hello world"}.

You can check that events have been triggered by going to your app’s debug console on our website.

More information about triggering events can be found here.

Listening For Events

Javascript

Add a <script> tag to your HTML linking in PusherJS:

 <script src="//js.pusher.com/3.0/pusher.min.js" type="text/javascript"></script>

On our client, we instantiate a Pusher object. We subscribe to a channel, which returns a Channel object. On that channel, we listen for events and pass in a callback to execute whenever data comes in.

var pusher = new Pusher(YOUR_APP_KEY); (1)
var channel = pusher.subscribe('test_channel'); (2)
channel.bind('my_event', function(data) {
  console.log(data); (3)
});
1 Create a new Pusher object.
2 Subscribe to a channel called test_channel.
3 Listen for my_event on the channel and console.log incoming data.

More information about listening to events can be found here.

iOS

Install the Pusher library using CocoaPods:

pod 'libPusher', '~> 1.5'

Import Pusher into the class that wants to make use of the library:

#import <Pusher/Pusher.h>

Create a connection:

self.client = [PTPusher pusherWithKey:@"YOUR_APP_KEY" delegate:self];

[self.client connect];

Subscribe to a channel and listen for events:

PTPusherChannel *channel = [self.client subscribeToChannelNamed:@"my-channel"];

PTPusherChannel *channel = [self.client subscribeToChannelNamed:@"my-channel"];
[channel bindToEventNamed:@"my-event" handleWithBlock:^(PTPusherEvent *channelEvent) {
  // channelEvent.data is a NSDictianary of the JSON object received
}];

Android

The pusher-java-client is available in Maven Central:

<dependency>
  <groupId>com.pusher</groupId>
  <artifactId>pusher-java-client</artifactId>
  <version>0.3.3</version>
</dependency>

Create a new Pusher instance:

Pusher pusher = new Pusher(YOUR_APP_KEY);

Subscribe to a channel:

Channel channel = pusher.subscribe("my-channel");

Bind to an event triggered on a channel:

channel.bind("my-event", new SubscriptionEventListener() {
    @Override
    public void onEvent(String channel, String event, String data) {
        System.out.println("Received event with data: " + data);
    }
});

Getting Started Repositories

To help you get up and running quickly we have some repositories that have Pusher functionality implemented for you to build upon:

Controlling Access To Realtime Data

In order to restrict who is able to subscribe to a channel, we use private channels. Subscribing to one is simple:

var privateChannel = pusher.subscribe('private-my_channel');

Private-channel names must be prefixed with ’private-'.

Authenticating Users

Upon attempting to subscribe to a private channel, a POST request will be sent to '/pusher/auth' asking for authentication.

Usually, private channels must be authenticated by your server in order to restrict access to data. We understand that some of you may not wish to build a server; in which case, see the workarounds we built for you here. However, if you need private channels and you plan on using particular business logic to control access, read on.

You authenticate a private channel using one of our server libraries. The example below uses our NodeJS library.

app.post( '/pusher/auth', function( req, res ) {
  var socketId = req.body.socket_id;
  var channel = req.body.channel_name;
  var auth = pusher.authenticate( socketId, channel );
  res.send( auth );
} );

More information about private channels can be found here.

Showing Who’s Online In Realtime

One of Pusher’s most popular features is presence channels. It allows you to create live user lists, along with any custom data that you attach to a particular user when they come online.

To subscribe to a presence channel, we prefix the channel name with 'presence-':

var presenceChannel = pusher.subscribe('presence-my_channel');

Presence-channels emit their own special events whenever you come online, another user comes online, or if another user goes offline. These are 'pusher:subscription_succeeded', 'pusher:member_added', and 'pusher:member_removed'.

pusher:subscription_succeeded

Whenever the user successfully subscribes to a presence channel, they receive the 'pusher:subscription_succeeded' event. This passes to a callback the members who are already on the channel.

presenceChannel.bind('pusher:subscription_succeeded', function(members) {
  members.each(function(member) {
    console.log(member);
  });
})

pusher:member_added

Whenever somebody else has come online, you receive the 'pusher:member_added' event, along with information about that member.

channel.bind('pusher:member_added', function(member) {
  console.log(member)
});

pusher:member_removed

The opposite of 'pusher:member_added', 'pusher:member_removed' passes to a callback the information about a user who has just left the channel.

channel.bind('pusher:member_removed', function(member) {
  console.log(member)
});

Authenticating Users

Like private channels, presence channels require authentication. Usually this is to allow you to determine who has rights to access that channel’s data. But - given that you are pressured for time and may not wish to start up a server - you can use one of the workarounds we built for you here. If you have any particular business logic that needs to be implemented regarding presence channel access, or if you need a server, then read on.

You can authenticate presence channels by using one of our libraries. At the authentication endpoint, you must assign a user_id to the member object that will show up in the presence channel. Optionally, you can pass in a user_info field containing any custom data you want to show up as member.info.

app.post( '/pusher/auth', function( req, res ) {
  var socketId = req.body.socket_id;
  var channel = req.body.channel_name;
  var presenceData = {
    user_id: 'unique_user_id',
    user_info: {
      name: 'Mr Pusher',
      twitter_id: '@pusher'
    }
  };
  var auth = pusher.authenticate( socketId, channel, presenceData );
  res.send( auth );
} );

More information about presence channels can be found here.

Triggering Events From The Client

If you are using a private- or presence- channel, you can trigger events from the client and not the server, if you wish. Firstly, go on your Pusher dashboard, click on your application, and go to your Settings. Then enable client events for your application.

Then, on your client, call trigger on the channel object, and not on the Pusher instance itself.

Any client-events must have names prefixed with 'client-'.

var privateChannel = pusher.subscribe('presence-my_channel');

privateChannel.trigger('client-my_event', {message: 'hello world'});

Note that you may send a maximum of 10 client-events per second. However, it is fairly straightforward to implement a queueing system, such as in this example.

More information about client events can be found here.

I Don’t Want A Server

We appreciate your time-constraints, and that some of you may not wish to have a server or need to secure your private and presence channels. So we came up with options for you to use to skip channel authentication.

pusher-js-client-auth

pusher-js-client-auth is simple to use. Firstly, link this script in your HTML, after linking in the Pusher library itself.

<script src="https://cdn.rawgit.com/leggetter/pusher-js-client-auth/master/dist/pusher-js-client-auth.js"></script>

Now instantiate a Pusher instance like below, passing in your app’s key, secret. For presence channels, pass in the user_id and user_info to be associated with a member.

var pusher = new Pusher(APP_KEY, {
    authTransport: 'client',
    clientAuth: {
      key: APP_KEY
      secret: APP_SECRET,
      user_id: USER_ID,
      user_info: {}
    }
});

pusher-hackathon

The pusher-hackathon gem starts up a server for you that authenticates your private and presence channels.

Firstly, install the gem.

$ [sudo] gem install pusher-hackathon

Then enter pusher-hackathon run, passing in your Pusher app id, key and secret as flags. Optionally, you can choose a port on which to run the server.

$ pusher-hackathon run --id your_app_id \
                       --secret your_app_secret \
                       --key your_app_key \
                       [--port your_port]

This will set up a Sinatra server for you. The default port it will be running on is 9090.

Then, in your Javascript code, make the Pusher connection point to this server’s 'pusher/auth endpoint' for authentication. For presence channels, you can also specify information to be associated with a channel member. As mentioned before, a user_id is required, and user_info is optional. If you are passing in user_info, you must JSON.stringify the object to be passed in.

var pusher = new Pusher('APP_KEY', {
  authEndpoint: "http://localhost:9090/pusher/auth", // 9090 can be substituted for the port you specified.

  auth: {
    params: {
      user_id: 1,
      user_info: JSON.stringify({twitter: "pusher"}) // optional
    }
  }
});

Webhooks

If you do have a server, you can get notified about certain Pusher-specific events with our webhooks service. These events pertain to channel-existence - when a channel is vacated or first becomes occupied - and presence-channels - when a member comes online or goes offline.

You can set up webhooks on your dashboard for the type of events you would like to receive, and the endpoint at which you wish to receive POST requests.

app.post( '/pusher/webhook', function( req, res ) {
  var webhook = pusher.webhook(request);
  if webhook.isValid(){
    console.log(webhook.getData());
  }
} );

channel_occupied/channel_vacated

This will be the payload you receive when 'test_channel' becomes occupied.

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

If the channel has become vacated, the "name" key of the payload will be 'channel_vacated'.

member_added/member_removed

When a member has successfully subscribed to a presence channel, you will receive this payload, containing the name of the channel and their user_id:

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

When a member has left the channel, the "name" key will be "member_removed".

More information about webhooks can be found here.

Pusher Libraries

Below you can find a list of libraries and their Github repos where you can find more specific examples about how to integrate Pusher into your stack.