Search code examples
javascriptnotificationsweb-push

Open a custom url when clicking on a web push notification


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?


Solution

  • 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
       }
    })