Deploying Real-Time Apps with Pusher Channels and ZEIT Now

How to get started building and deploying real-time apps with Channels on ZEIT Now.

Pusher Channels is a service that makes it easy to add real-time data and functionality to web and mobile apps by using WebSockets.

This guide demonstrates how to get started creating and deploying real-time apps with Channels and ZEIT Now.

Note: This guide is an overview. For the full code, see the linked example at the bottom of this page.

Step 1: Pusher Account Setup

Start by making an account on Pusher and creating a new app by clicking the Create new app button.

Creating a new app from the Channels dashboard.

Next, give your app a name and select a region. Choose a region closest to the majority of your customers to minimize latency.

Adding a name and region to the app from the Channels dashboard.

From your dashboard, find and click on the Channels app you just created.

Selecting the app from the Channels dashboard.

Next, click the App Keys tab. Copy these values so that you can save them as Now Secrets and then provide them to your app as environment variables.

Viewing the App Keys from the Channels dashboard.

Step 2: Set Up Your Project

With your Pusher Channels account and app set up, the next step is to create your project to deploy, with only a root directory for static files, and an /api directory for Serverless Functions.

mkdir -p pusher-channels/api && cd pusher-channels

Creating and entering into a /pusher-channels directory that contains an /api folder.

Create an index.html file in your project with the code below.

<!DOCTYPE html>
<html lang="en">
  <head>
    <link rel="stylesheet" href="style.css" />
  </head>
  <body>
    <script src="https://js.pusher.com/5.0/pusher.min.js"></script>
    <script src="main.js"></script>
  </body>
</html>

Adding script tags inside the body of your index.html file.

Create an instance of a Pusher Channels client that subscribes and reacts to events on the appropriate channel. Additionally, send data to your Serverless Function that will trigger a push event.

Create a main.js file where you will initialize a Channels object with your app-key, subscribe to the appropriate channel and bind a callback function to react to events within that channel.

// Initialize Channels client
let channels = new Pusher('app-key', {
  cluster: 'cluster-region'
})

// Subscribe to the appropriate channel
let channel = channels.subscribe('channel-name')

// Bind a callback function to an event within the subscribed channel
channel.bind('event-name', function(data) {
  // Do what you wish with the data from the event
})

Initializing a Channels client, subscribing to a channel, and binding to an event.

All that's remaining on the client is to create a way to send data to your Serverless Function to trigger push events. To achieve this, add the snippet below to your main.js file.

async function pushData(data) {
  const res = await fetch('/api/channels-event', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(data)
  })
  if (!res.ok) {
    console.error('failed to push data')
  }
}

A function in main.js to send event data to our /api endpoint.

Using Now CLI, add the following Now Secrets to your account and expose them as environment variables.

now secrets add channels-app-id [Your Channel's app ID]

Adding the channels-app-id as a Now Secret.

now secrets add channels-app-secret [Your Channel's app Secret]

Adding the channels-app-secret as a Now Secret.

Note: Since the app-key and cluster are already exposed on the client and are not sensitive, you do not need to add them as secrets.

Next, create a minimal now.json file to expose your secrets as environment variables, replacing app-key and cluster-region with the values provided by Channels.

{
  "version": 2,
  "env": {
    "APP_ID": "@channels-app-id",
    "KEY": "app-key",
    "SECRET": "@channels-ap-secret",
    "CLUSTER": "cluster-region"
  }
}

An example now.json file that provides the app with environment variables.

Add the dependencies for the Serverless Function from inside the /api directory.

cd api && npm init -y && npm i pusher

Entering the /api directory, initializing the package.json file and installing the pusher dependency.

Create a channels-event.js file inside the /api directory that initializes a new Channels object and receives data from the req.body helper method, before invoking channels.trigger to register the event.

const Channels = require('pusher')

const {
  APP_ID: appId,
  KEY: key,
  SECRET: secret,
  CLUSTER: cluster
} = process.env

const channels = new Channels({
  appId,
  key,
  secret,
  cluster
})

module.exports = (req, res) => {
  const data = req.body
  channels.trigger('event-channel', 'event-name', data)
  res.status(200).end('sent event successfully')
}

An example channels-event.js file inside the /api directory.

When channels.trigger is called, an event will be broadcast to all subscribed clients.

Step 3: Deploying with ZEIT Now

With your Channels app set up, it is ready to be deployed with ZEIT Now.

If you have not yet installed Now, you can do so by installing Now CLI. You are now ready to deploy your app with a single command.

now

Deploying your project with the now command.

If you want to deploy your Channels project when you push to a Git repository, you can use either Now for GitHub or Now for GitLab to have your project automatically deployed on every push, and aliased on push to master.

You can find a full code example of an app made with this guide in the ZEIT Now examples repository on GitHub, along with the live example deployed with ZEIT Now.



Written By
Written by coetrycoetry
on August 28th 2019