Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 720
BananaNeil Avatar asked May 15 '17 18:05

BananaNeil


People also ask

Can you put a link in a push notification?

How to Add the In-App Link in a Push Notification. After all pending changes are made live, you can begin to add the In-App Link to a push notification. When composing a new push notification in the Mobile App Studio, drag and drop the In-App link draggable into your message.

Does web push notification work when browser is closed?

This means the browser can have no windows open, and you'll still receive the push message in your service worker, because the browser in running in the background. The only time a push won't be received is when the browser is completely closed, i.e. not running at all (no marking).

Does Safari support web push notifications?

The good news is that Pusher Beams now has Safari support and we've been able to hide most of the complexity for developers by: We provide a unified API for triggering notifications to Push API browsers and Safari – you can send to both with a single API call (as well as to iOS/Android)


3 Answers

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
   }
})
like image 194
Jonas Wilms Avatar answered Oct 07 '22 17:10

Jonas Wilms


Custom data comes in event.notification object not in event directly(in notificationclick). So if you want to fetch the custom data variable in notificationclick function, then you should do it like this :)

self.addEventListener('notificationclick', function(event) {
  event.notification.close();
  event.waitUntil(
    clients.openWindow(event.notification.data.url + "?notification_id=" + event.notification.data.id)
  );
})
like image 38
munjal Avatar answered Oct 07 '22 16:10

munjal


For Webpush Ruby Gem, with some modifications, here's what worked for me:

Webpush.payload_send(
  endpoint: user.push_subscription.endpoint,
  message: {
    message: "A new service request is created",
    id: service_request.request_number,
    url: "https://google.com/"
  }.to_json,
  p256dh: user.push_subscription.key,
  auth: user.push_subscription.auth_key,
  ttl: 24 * 60 * 60,
  vapid: {
    subject: 'A Push Notification',
    public_key: ENV['VAPID_PUBLIC_KEY'],
    private_key: ENV['VAPID_PRIVATE_KEY']
  }
)

Where:

  • user.push_subscription.endpoint is a method defined in PushSubscription model to return the endpoint
  • user.push_subscription.key, user.push_subscription.auth_key are again methods defined in the same model

Inside /serviceworker.js.erb

self.addEventListener("push", (event) => {
  let response = event.data && event.data.text();
  let title = JSON.parse(response).message;
  let body = JSON.parse(response).id;
  let icon = '/assets/logo-blue-120x120.jpg';

  event.waitUntil(
    self.registration.showNotification(title, { body, icon, data: { url: JSON.parse(response).url } })
  )
});

self.addEventListener('notificationclick', function(event) {
  event.notification.close();
  event.waitUntil(
    clients.openWindow(event.notification.data.url)
  );
});
like image 2
Puneet Pandey Avatar answered Oct 07 '22 17:10

Puneet Pandey