Open a custom url when clicking on a web push notification

BananaNeil picture BananaNeil · May 15, 2017 · Viewed 21k times · Source

I am implementing the Webpush ruby gem to send push notifications to users of my website.

Server code:

  Webpush.payload_send({
      message: notification.message,
      url: notification.url,  # I can't figure out how to access this key
      id: notification.id,    # or this key from the service worker
      endpoint: endpoint,
      p256dh: p256dh_key,
      vapid: vapid_keys,
      ttl: 24 * 60 * 60,
      auth: auth_key,
    })

I have a service worker set up on the client side to show the notification and make it clickable.

self.addEventListener("push", function (event) {
  var title = (event.data && event.data.text()) || "New Message";

  event.waitUntil(
    self.registration.showNotification(title, {
      body: "New push notification",
      icon: "/images/[email protected]",
      tag:  "push-notification-tag",
      data: {
        url: event.data.url, // This is returning null
        id: event.data.id // And this is returning null
      }
    })
  )
});

self.addEventListener('notificationclick', function(event) {
  event.notification.close();
  event.waitUntil(
    clients.openWindow(event.data.url + "?notification_id=" + event.data.id)
  );
})

It is all working fine, except the custom keys (url, id) that I am passing through are not accessible from within the service worker.

Does anyone know how to pass custom data through the WebPush gem?

Answer

Jonas Wilms picture Jonas Wilms · May 17, 2017

From the Webpush (with a payload) documentation, it seems that you should put all your data into the message, using the JSON.stringify() method, and retrieve it in the service worker with JSON.parse().

Server:

Webpush.payload_send({
  message:JSON.stringify({
    message: notification.message,
    url: notification.url,
    id: notification.id,
  }),
  endpoint: endpoint,
  p256dh: p256dh_key,
  vapid: vapid_keys,
  ttl: 24 * 60 * 60,
  auth: auth_key,
})

Client:

 event.waitUntil(
   self.registration.showNotification(title, {
   body: "New push notification",
   icon: "/images/[email protected]",
   tag:  "push-notification-tag",
   data: {
     url: JSON.parse(event.message).url
   }
})