Most modern websites are dynamic web applications that are expected to work across a myriad of devices and browsers.  Since the most common way of accessing web applications nowadays is via mobile browsers, users expect the same level of interactivity they get with native apps on the web.

Some web apps are optimised for mobile to the point where the difference between native applications and web applications is next to none.

One notable exception to this was push notifications, until recently there was no way to send users of your web application notifications messages. This was until the good folks at Chrome implemented a web push feature that allowed web developers to re-engage users via notifications. Web push allows messages to be delivered to user's browsers even when they are not active on your web app. Giving developers the same level of interaction with their users as mobile developers do through push notifications.

We recently had to implement push notifications for a large commercial real estate marketplace app. A challenge with implementing this was we needed to ensure that our app can keep sending messages to multiple subscribers and allow us to see what was sent to who and when. To overcome this challenge we used the Voluntary Application Server Identification (VAPID) for Web Push.

In this post, we will go through how to implement web push functionality in a Ruby on Rails project using VAPID.

So how does WebPush work?

To get Web Push working you’ll need:

  • Your rails server equipped with service workers.
  • Your subscriber accessing a browser that has Web Push supported
  • A push service provider like Google or Mozilla

Implementing Web Push

Setup Vapid Keys

  • The first step in sending a push message is to set up a pair of one time VAPID keys (public/private) to be saved on your server. These keys will be used to sign the Push API requests. VAPID keys are used as a means of encrypting and sending messages using the web push protocol without needing to send it through a service like Google Cloud Messaging.
  • A manifest.json file that helps to identify your application
  • You will need to set up a service worker and install on the user’s browser, the service worker is subscribed to push events with your public VAPID key.
  • Your server will need to make an API request to send a notification to the user's subscription
  • Your service worker will be set up with a receive ‘push’ event to trigger a notification event on the client side, displaying the notification

The diagram below gives a good outline of how it all works

How web push works Source: W3.org
Sheda uses Design, Artificial Intelligence and technology to solve complex problems with an emphasis on delivering solutions that make and accelerate impact and bring about social change.

Getting Started

You can use this Git Repository to follow along or set up a new rails app and implement as you read.

There are a few things you will need to set up before you start sending messages.

Gems to install:

  • WebPush

Go into the project root and install the web push gem

This gem is used for the push of the data itself, it deals with all the encryption and requests

  • Serviceworkers:

<p>CODE: https://gist.github.com/lachlanagnew/cb2ba9513b63f195bb59ce8cb6c8700c.js</p>

Serviceworkers-rails is a gem that allows a rails server to serve out a service-worker.js file making it look like it’s from the root directory.

A serviceworker is a bit of javascript that is always running in the background of the browser even if the page isn’t open.They have many useful applications apart from listening for push notifications like offline loading and periodic background syncs. To learn more about service workers you can read up here - https://developers.google.com/web/fundamentals/primers/service-workers/

Setting up VAPID keys:

Setting up your VAPID keys gives your server a unique signature to sign the messages send out over the subscription.

Open up your ruby console and do the following:

<p>CODE: https://gist.github.com/lachlanagnew/8008a0cc5ccc3011719019f958b95e83.js</p>

VAPID is a protocol used for secure data transfer, you can read up more about it in the spec. You will want to store these keys in a secure location for future use.

Declare manifest.json

The manifest.json is used to pass settings to the browser on the server that is sending push notifications.

<p>CODE: https://gist.github.com/lachlanagnew/a5c2169c41e921414deb9f3160d1171d.js</p>

And link that in the head tag of your application:

<p>CODE: https://gist.github.com/lachlanagnew/dddc600e2b0eb73ffbc70327714c97f7.js</p>

Set up Service worker:

Install service worker files,

<p>CODE: https://gist.github.com/lachlanagnew/d5311b1ca46d714678d1abbdb304e992.js</p>

Then you declare all the files you wish to be included with the service worker

<p>CODE: https://gist.github.com/lachlanagnew/ba462f4f9122033d085e24cf15aa081d.js</p>

This declares which files will be served and referenced like they are coming from the root directory, so any file that the service worker references will need to be declared here.

Setting up the ServiceWorker:

Set up the service worker to listen to a push:

<p>CODE: https://gist.github.com/lachlanagnew/9386c0151d3ce486cdf008d97f6451a9.js</p>

Get subscription:

To allow the server to send a push to you, you must first be subscribed to the VAPID public key.

<p>CODE: https://gist.github.com/lachlanagnew/30759d6d1936c80875ab9a8a334816fa.js</p>

This does a lot so let's break it down;

  1. If the browser does not support notifications, then send out an error to stop it from continuing
  2. If they have already accepted push notifications, then get the subscription keys
  3. If they haven’t already then get a request to send them push notifications
  4. If they accept this, then again get the keys
  5. Register the service worker
  6. Subscribe the service worker to the servers public key
  7. Send the subscription data to the server

Once the data is sent to the server you should save what you received from your user's data table, this will allow you to send a notification out to a particular user.

Send push:

Finally, now you have all of the data necessary, you can send out a message to your client.

<p>CODE: https://gist.github.com/lachlanagnew/4baa96de9df0233e7b298aedb166d0ab.js</p>

With the subscription details saved under your user's data table, you can send out a push notification to that user using the web push gem as shown above. You should then see a notification get triggered.

You can access a Rails Web Push demo project via our Github. The README in the repository has details on how to run this service.

Further reading about push notifications: 

https://web-push-book.gauntface.com/ 

https://rossta.net/blog/using-the-web-push-api-with-vapid.html

https://tools.ietf.org/html/draft-ietf-webpush-protocol-12

If you encounter any issues drop us a line in the comments below.

Want some help growing your business and creating products/service that your customers will love on Ruby on Rails? Drop us a line or click on the floating head to chat with us.

By

Lachi Agnew

Software Developer
@ Sheda

Call us

Call +61 3 9028 6936

Drop in and say hi

4 Brunswick Pl,
Fitzroy VIC 3065
get directions

Follow us

Contact

Thank you! Your submission has been received!

Hmm... Something's not right. Try submitting again.