Открывать настраиваемый URL-адрес при нажатии на веб-push-уведомление

Я использую рубиновый гем Webpush для отправки push-уведомлений пользователям моего веб-сайта.

Код сервера:

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

У меня есть сервисный работник, настроенный на стороне клиента, чтобы показывать уведомление и делать его кликабельным.

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

Все работает нормально, за исключением того, что пользовательские ключи (url, id), которые я передаю, недоступны изнутри сервис-воркера.

Кто-нибудь знает, как передавать пользовательские данные через гем WebPush?


person BananaNeil    schedule 15.05.2017    source источник
comment
Я не эксперт в этом, но я бы сделал: message: JSON.stringify (уведомление) на сервере и JSON.parse на клиенте ...   -  person Jonas Wilms    schedule 15.05.2017
comment
@Jonasw - В итоге я выбрал ваше решение. Если вы напишете это как ответ, я приму. Спасибо за помощь.   -  person BananaNeil    schedule 17.05.2017


Ответы (4)


Из документации Webpush (с полезной нагрузкой) кажется, что вам следует поместить все ваши данные в сообщение, используя метод JSON.stringify(), и получить их в сервис-воркере с помощью JSON.parse().

Сервер:

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

Клиент:

 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
   }
})
person Jonas Wilms    schedule 17.05.2017

Пользовательские данные поступают в объект event.notification, а не в событие напрямую (в notificationclick). Поэтому, если вы хотите получить пользовательскую переменную данных в функции notificationclick, вам следует сделать это следующим образом :)

self.addEventListener('notificationclick', function(event) {
  event.notification.close();
  event.waitUntil(
    clients.openWindow(event.notification.data.url + "?notification_id=" + event.notification.data.id)
  );
})
person munjal    schedule 06.06.2017
comment
Проблема заключалась в получении данных из события push, а не из события щелчка. Но вы правы, это была еще одна ошибка, которую мне пришлось исправить. - person BananaNeil; 07.06.2017
comment
@BananaNeil, не могли бы вы упомянуть, как вы это исправили? Проблема заключалась в получении данных из события push, а не из события щелчка. потому что я также не могу отправлять данные со стороны сервера на сторону клиента ... - person usama; 01.10.2019
comment
@usama Взгляните на принятый ответ, в нем есть код сервера / клиента - person BananaNeil; 05.12.2019

Вот что сработало для Webpush Ruby Gem с некоторыми изменениями:

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']
  }
)

Где:

  • user.push_subscription.endpoint - это метод, определенный в PushSubscription модели для возврата конечной точки
  • user.push_subscription.key, user.push_subscription.auth_key снова методы, определенные в той же модели

Внутри /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)
  );
});
person Puneet Pandey    schedule 21.08.2020

Добавьте это в свой проект Angular внутри node_modules/@angular/service-worker/ngsw-worker.js

this.scope.addEventListener('notificationclick', (event) => {
            console.log('[Service Worker] Notification click Received. event:%s', event);
            event.notification.close();
            if (clients.openWindow && event.notification.data.url) {
                event.waitUntil(clients.openWindow(event.notification.data.url));
            }
        });

Вы можете ввести приведенный выше код там, где вы можете найти эту строку внутри файла

this.scope.addEventListener('notificationclick', (event) => ..

И вам нужно снова построить dist, чтобы это сработало. И в бэкэнде вам нужно будет использовать этот формат:

{"notification":{"body":"This is a message.","title":"PUSH MESSAGE","vibrate":[300,100,400,100,400,100,400],"icon":"https://upload.wikimedia.org/wikipedia/en/thumb/3/34/AlthepalHappyface.svg/256px-AlthepalHappyface.svg.png","tag":"push demo","requireInteraction":true,"renotify":true,"data":{"url":"https://maps.google.com"}}}

Внутри URL-адреса вы можете ввести свой URL-адрес, и при нажатии на уведомление ваше push-уведомление откроет данную ссылку и сфокусирует ее в браузере.

person cyperpunk    schedule 25.02.2019