Обзор

Отправка push-сообщений обеспечивает простой и эффективный способ повторно взаимодействовать с вашими пользователями, и в этой лаборатории кода вы узнаете, как добавить push-уведомления в свое веб-приложение.

Форма руководства по содержанию developers.google.com

Что вы узнаете

  • Как подписаться и отказаться от подписки пользователя на рассылку push-сообщений
  • Как обрабатывать входящие push-сообщения
  • Как вывести уведомление
  • Как реагировать на щелчки уведомлений

Что вам понадобится

  • Chrome 52 или выше
  • Веб-сервер для Chrome или ваш собственный веб-сервер на выбор
  • Текстовый редактор
  • Базовые знания HTML, CSS, JavaScript и Chrome DevTools.
  • Пример кода см. В разделе "Настройка".

Получить настройку

Загрузите образец кода

Вы можете получить образец кода для этого кода, загрузив zip здесь:

Скачать исходный код

или путем клонирования этого репозитория git:

git clone https://github.com/GoogleChrome/push-notifications.git

Если вы загрузили исходный код в виде zip-архива, при его распаковке вы получите корневую папку push-notifications-master.

Проверьте интерактивную демонстрацию веб-приложения с помощью push-уведомлений.



Установите и проверьте веб-сервер

Хотя вы можете использовать собственный веб-сервер, эта лаборатория кода разработана для совместной работы с веб-сервером Chrome. Если у вас еще не установлено это приложение, вы можете установить его из Интернет-магазина Chrome.

Установить веб-сервер для Chrome

После установки приложения «Веб-сервер для Chrome» щелкните ярлык «Приложения» на панели закладок:

В открывшемся окне щелкните значок веб-сервера:

Далее вы увидите это диалоговое окно, в котором можно настроить локальный веб-сервер:

Нажмите кнопку выбрать папку и выберите папку приложения. Это позволит вам обслуживать текущую работу через URL-адрес, выделенный в диалоговом окне веб-сервера (в разделе URL-адреса веб-сервера).

В разделе «Параметры» установите флажок «Автоматически показывать index.html», как показано ниже:

Затем остановите и перезапустите сервер, сдвинув переключатель с надписью «Web Server: STARTED» влево, а затем обратно вправо.

Теперь посетите свой сайт в своем веб-браузере (щелкнув выделенный URL-адрес веб-сервера), и вы должны увидеть страницу, которая выглядит следующим образом:

Всегда обновляйте сервис-воркер

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

Чтобы настроить это в Chrome, откройте DevTools (щелкните правой кнопкой мыши ›Проверить) и перейдите на панель Приложение, перейдите на вкладку Сервисные работники и установите флажок Обновление при перезагрузке флажок. Когда этот флажок установлен, сервис-воркер принудительно обновляется каждый раз при перезагрузке страницы.

Зарегистрировать сервис-воркера

Обратите внимание, что в вашем каталоге app есть пустой файл с именем sw.js. Этот файл будет вашим работником службы, пока он может оставаться пустым, и мы добавим в него код позже.

Сначала нам нужно зарегистрировать этот файл как нашего Service Worker.

Наша app/index.html страница загружает scripts/main.js, и именно в этом файле JavaScript мы зарегистрируем нашего сервис-воркера.

Добавьте следующий код в scripts/main.js:

if ('serviceWorker' in navigator && 'PushManager' in window) {
  console.log('Service Worker and Push is supported');
  navigator.serviceWorker.register('sw.js')
  .then(function(swReg) {
    console.log('Service Worker is registered', swReg);
    swRegistration = swReg;
  })
  .catch(function(error) {
    console.error('Service Worker Error', error);
  });
} else {
  console.warn('Push messaging is not supported');
  pushButton.textContent = 'Push Not Supported';
}

Этот код проверяет, поддерживаются ли сервис-воркеры и push-сообщения текущим браузером, и если это так, он регистрирует наш sw.js файл.

Попробуй это

Проверьте свои изменения, обновив приложение в браузере.

Проверьте консоль в Chrome DevTools на предмет Service Worker is registered, например:

Получить ключи сервера приложений

Для работы с этой лабораторией кода вам необходимо сгенерировать некоторые ключи сервера приложений, которые мы можем сделать с помощью этого сопутствующего сайта: https://web-push-codelab.glitch.me/

Здесь вы можете сгенерировать пару открытого и закрытого ключей.

Скопируйте свой открытый ключ в scripts/main.js, заменив значение <Your Public Key>:

const applicationServerPublicKey = '<Your Public Key>';

Примечание. Никогда не помещайте свой закрытый ключ в веб-приложение!

Состояние инициализации

В настоящий момент кнопка веб-приложения отключена и не может быть нажата. Это связано с тем, что рекомендуется отключать кнопку по умолчанию и включать ее, если вы знаете, что push поддерживается и можете узнать, подписан ли пользователь в настоящее время или нет.

Давайте создадим две функции в scripts/main.js, одну с именем initializeUI, которая будет проверять, подписан ли пользователь в данный момент, и одну с именем updateBtn, которая активирует нашу кнопку и изменяет текст, если пользователь подписан или нет.

Мы хотим, чтобы наша initializeUI функция выглядела так:

function initializeUI() {
  // Set the initial subscription value
  swRegistration.pushManager.getSubscription()
  .then(function(subscription) {
    isSubscribed = !(subscription === null);
    if (isSubscribed) {
      console.log('User IS subscribed.');
    } else {
      console.log('User is NOT subscribed.');
    }
    updateBtn();
  });
}

Наш новый метод использует swRegistration из предыдущего шага и вызывает getSubscription() для него pushManager. getSubscription() - это метод, который возвращает обещание, которое разрешается с текущей подпиской, если она есть, в противном случае возвращается null. С его помощью мы можем проверить, подписан ли пользователь уже или нет, установить какое-то состояние, а затем вызвать updateBtn(), чтобы кнопку можно было активировать с помощью некоторого полезного текста.

Добавьте следующий код для реализации функции updateBtn().

function updateBtn() {
  if (isSubscribed) {
    pushButton.textContent = 'Disable Push Messaging';
  } else {
    pushButton.textContent = 'Enable Push Messaging';
  }
  pushButton.disabled = false;
}

Эта функция просто изменяет текст в зависимости от того, подписан пользователь или нет, а затем включает кнопку.

Последнее, что нужно сделать, это позвонить initializeUI(), когда наш сервисный работник будет зарегистрирован.

navigator.serviceWorker.register('sw.js')
.then(function(swReg) {
  console.log('Service Worker is registered', swReg);
  swRegistration = swReg;
  initializeUI();
})

Попробуй это

Обновите свое веб-приложение, и вы должны увидеть, что кнопка «Включить push-сообщения» теперь включена (вы можете нажать на нее), и вы должны увидеть «Пользователь НЕ подписан» в консоли.

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

Подпишитесь на пользователя

На данный момент наша кнопка «Включить push-сообщения» не работает, так что давайте это исправим.

Добавьте прослушиватель кликов к нашей кнопке в функции initializeUI(), например:

function initializeUI() {
  pushButton.addEventListener('click', function() {
    pushButton.disabled = true;
    if (isSubscribed) {
      // TODO: Unsubscribe user
    } else {
      subscribeUser();
    }
  });
  // Set the initial subscription value
  swRegistration.pushManager.getSubscription()
  .then(function(subscription) {
    isSubscribed = !(subscription === null);
    updateSubscriptionOnServer(subscription);
    if (isSubscribed) {
      console.log('User IS subscribed.');
    } else {
      console.log('User is NOT subscribed.');
    }
    updateBtn();
  });
}

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

Затем мы вызываем subscribeUser(), когда знаем, что пользователь в настоящее время не подписан, поэтому скопируйте и вставьте следующий код в scripts/main.js.

function subscribeUser() {
  const applicationServerKey = urlB64ToUint8Array(applicationServerPublicKey);
  swRegistration.pushManager.subscribe({
    userVisibleOnly: true,
    applicationServerKey: applicationServerKey
  })
  .then(function(subscription) {
    console.log('User is subscribed.');
    updateSubscriptionOnServer(subscription);
    isSubscribed = true;
    updateBtn();
  })
  .catch(function(err) {
    console.log('Failed to subscribe the user: ', err);
    updateBtn();
  });
}

Давайте рассмотрим, что делает этот код и как он подписывает пользователя на рассылку push-сообщений.

Сначала мы берем открытый ключ сервера приложений, который является безопасным для URL-адресов base 64, и преобразуем его в UInt8Array, поскольку это ожидаемый ввод вызова подписки. Мы уже дали вам функцию urlB64ToUint8Array в верхней части scripts/main.js.

После преобразования значения мы вызываем метод subscribe() в pushManager нашего сервис-воркера, передавая открытый ключ нашего сервера приложений и значение userVisibleOnly: true.

const applicationServerKey = urlB64ToUint8Array(applicationServerPublicKey);
swRegistration.pushManager.subscribe({
  userVisibleOnly: true,
  applicationServerKey: applicationServerKey
})

Параметр userVisibleOnly - это в основном подтверждение того, что вы будете показывать уведомление каждый раз, когда отправляется push. На момент написания это значение является обязательным и должно быть истинным.

Вызов subscribe() возвращает обещание, которое разрешится после следующих шагов:

  1. Пользователь предоставил разрешение на отображение уведомлений.
  2. Браузер отправил сетевой запрос в службу push-уведомлений, чтобы получить сведения для создания PushSubscription.

Обещание subscribe() разрешится с PushSubscription, если эти шаги были успешными. Если пользователь не предоставляет разрешение или если есть какие-либо проблемы с подпиской пользователя, обещание будет отклонено с ошибкой. Это дает нам следующую цепочку обещаний в нашей кодовой таблице:

swRegistration.pushManager.subscribe({
  userVisibleOnly: true,
  applicationServerKey: applicationServerKey
})
.then(function(subscription) {
  console.log('User is subscribed.');
  updateSubscriptionOnServer(subscription);
  isSubscribed = true;
  updateBtn();
})
.catch(function(err) {
  console.log('Failed to subscribe the user: ', err);
  updateBtn();
});

Таким образом, мы получаем подписку и рассматриваем пользователя как подписавшегося или перехватываем ошибку и выводим ее на консоль. В обоих сценариях мы вызываем updateBtn(), чтобы убедиться, что кнопка снова активирована и имеет соответствующий текст.

Метод updateSubscriptionOnServer - это метод, при котором в реальном приложении мы отправляем нашу подписку на бэкэнд, но для нашей codelab мы собираемся распечатать подписку в нашем пользовательском интерфейсе, что поможет нам в дальнейшем. Добавьте этот метод в scripts/main.js:

function updateSubscriptionOnServer(subscription) {
  // TODO: Send subscription to application server
  const subscriptionJson = document.querySelector('.js-subscription-json');
  const subscriptionDetails =
    document.querySelector('.js-subscription-details');
  if (subscription) {
    subscriptionJson.textContent = JSON.stringify(subscription);
    subscriptionDetails.classList.remove('is-invisible');
  } else {
    subscriptionDetails.classList.add('is-invisible');
  }
}

Попробуй это

Если вы вернетесь в свое веб-приложение и попытаетесь нажать кнопку, вы должны увидеть запрос разрешения, подобный этому:

Если вы предоставите разрешение, вы должны увидеть на консоли сообщение «Пользователь подписан», текст кнопки изменится на «Отключить push-сообщения», и вы сможете просмотреть подписку в формате JSON внизу страницы.

Отказано в разрешении на обработку

Одна вещь, которую мы еще не рассмотрели, - это то, что произойдет, если пользователь заблокирует запрос на разрешение. Это требует особого рассмотрения, потому что, если пользователь блокирует разрешение, наше веб-приложение не сможет повторно показать запрос разрешения и не сможет подписаться на пользователя, поэтому нам нужно, по крайней мере, отключить кнопку, чтобы пользователь знает, что его нельзя использовать.

Очевидное место для нас, чтобы справиться с этим сценарием, - это функция updateBtn(). Все, что нам нужно сделать, это проверить значение Notification.permission, например:

function updateBtn() {
  if (Notification.permission === 'denied') {
    pushButton.textContent = 'Push Messaging Blocked.';
    pushButton.disabled = true;
    updateSubscriptionOnServer(null);
    return;
  }
  if (isSubscribed) {
    pushButton.textContent = 'Disable Push Messaging';
  } else {
    pushButton.textContent = 'Enable Push Messaging';
  }
  pushButton.disabled = false;
}

Мы знаем, что если разрешение denied, то пользователь не может быть подписан, и мы больше ничего не можем сделать, поэтому отключение кнопки навсегда - лучший подход.

Попробуй это

Поскольку мы уже предоставили разрешение для нашего веб-приложения на предыдущем шаге, нам нужно щелкнуть i в кружке в строке URL-адреса и изменить разрешение уведомлений на Использовать глобальное значение по умолчанию (Спросить). .

После изменения этого параметра обновите страницу и нажмите кнопку Включить push-сообщения и на этот раз выберите Блокировать в диалоговом окне разрешений. Текст кнопки теперь будет Push-сообщения заблокированы и будет отключен.

Благодаря этому изменению теперь мы можем подписаться на пользователя и позаботимся о возможных сценариях разрешения.

Обработка события push

Прежде чем мы рассмотрим, как отправить push-сообщение из вашего бэкэнда, нам нужно подумать, что на самом деле произойдет, когда подписанный пользователь получит push-сообщение.

Когда мы запускаем push-сообщение, браузер получает push-сообщение, выясняет, для какого сервис-воркера используется push, прежде чем разбудить этого сервис-воркера и отправить событие push. Нам нужно прослушать это событие и в результате показать уведомление.

Добавьте следующий код в свой sw.js файл:

self.addEventListener('push', function(event) {
  console.log('[Service Worker] Push Received.');
  console.log(`[Service Worker] Push had this data: "${event.data.text()}"`);
  const title = 'Push Codelab';
  const options = {
    body: 'Yay it works.',
    icon: 'images/icon.png',
    badge: 'images/badge.png'
  };
  event.waitUntil(self.registration.showNotification(title, options));
});

Давайте пройдемся по этому коду. Мы отслеживаем push-события в нашем сервис-воркере, добавляя прослушиватель событий в наш сервис-воркер, который представляет собой этот фрагмент кода:

self.addEventListener('push', ...... );

Если вы раньше не играли с Web Workers, self, вероятно, новинка. self ссылается на самого сервис-воркера, поэтому мы добавляем прослушиватель событий в наш сервис-воркер.

Когда получено push-сообщение, наш прослушиватель событий запускается, и мы создаем уведомление, вызывая showNotification() при регистрации. showNotification() ожидает title, и мы можем дать ему options объект. Здесь мы собираемся установить текстовое сообщение, значок и значок в параметрах (на момент написания этот значок используется только на Android).

const title = 'Push Codelab';
const options = {
  body: 'Yay it works.',
  icon: 'images/icon.png',
  badge: 'images/badge.png'
};
self.registration.showNotification(title, options);

Последнее, о чем мы расскажем в нашем push-событии, - это event.waitUntil(). Этот метод принимает обещание, и браузер будет поддерживать работоспособность вашего сервис-воркера до тех пор, пока переданное обещание не будет выполнено.

Чтобы упростить понимание приведенного выше кода, мы можем переписать его так:

const notificationPromise = self.registration.showNotification(title, options);
event.waitUntil(notificationPromise);

Теперь, когда мы прошли через событие push, давайте протестируем событие push.

Попробуй это

С нашим событием push в сервис-воркере мы можем проверить, что происходит при получении сообщения, запустив поддельное событие push с помощью DevTools.

В своем веб-приложении подпишитесь на push-обмен сообщениями, убедившись, что у вас есть User IS подписан в консоли, затем перейдите на панель Application в DevTools и в разделе Service На вкладке «Рабочие» щелкните ссылку Push под своим работником службы.

После того, как вы нажмете на нее, вы должны увидеть такое уведомление:

Примечание. Если этот шаг не сработает, попробуйте отменить регистрацию работы службы с помощью ссылки Отменить регистрацию на панели приложений DevTools, дождаться остановки работника службы и затем перезагрузите страницу.

Уведомление нажмите

Если вы нажмете на одно из этих уведомлений, вы не заметите, что ничего не происходит. Мы можем обрабатывать щелчки уведомлений, отслеживая notificationclick события в вашем сервис-воркере.

Начните с добавления слушателя notificationclick в sw.js следующим образом:

self.addEventListener('notificationclick', function(event) {
  console.log('[Service Worker] Notification click Received.');
  event.notification.close();
  event.waitUntil(
    clients.openWindow('https://developers.google.com/web/')
  );
});

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

В этой лаборатории кода мы сначала закрываем уведомление, на которое щелкнули:

event.notification.close();

Затем мы открываем новое окно / вкладку, загружая URL-адрес «https://developers.google.com/web/», не стесняйтесь менять это :)

clients.openWindow('https://developers.google.com/web/')

Мы снова вызываем event.waitUntil(), чтобы убедиться, что браузер не завершает работу нашего сервис-воркера до отображения нашего нового окна.

Попробуй это

Попробуйте снова запустить push-сообщение в DevTools и щелкните уведомление. Теперь вы увидите, что уведомление закроется, и откроется новая вкладка.

Отправка push-сообщений

Мы увидели, что наше веб-приложение способно отображать уведомление с помощью DevTools, и рассмотрели, как закрыть уведомление о клике. Следующим шагом является отправка фактического push-сообщения.

Обычно процесс для этого заключается в отправке подписки с веб-страницы на серверную часть, а затем серверная часть запускает push-сообщение, выполняя вызов API к конечной точке в подписке.

Это выходит за рамки данной лаборатории кода, но вы можете использовать сопутствующий сайт (https://web-push-codelab.glitch.me/) для этой лаборатории кода, чтобы вызвать фактическое push-сообщение. Скопируйте и вставьте подписку внизу своей страницы:

Затем вставьте это на сопутствующий сайт в текстовую область Подписка на отправку:

Затем в разделе Текст для отправки вы можете добавить любую строку, которую хотите отправить с push-сообщением, и, наконец, нажать кнопку Отправить push-сообщение.

Затем вы должны получить push-сообщение, и введенный вами текст будет распечатан на консоли.

Это должно дать вам возможность протестировать отправку и получение данных и в результате управлять уведомлениями.

Сопутствующее приложение на самом деле является просто сервером узла, который использует библиотеку web-push для отправки сообщений. Стоит заглянуть в web-push-libs org на Github, чтобы узнать, какие библиотеки доступны для отправки push-сообщений для вас (это обрабатывает множество мельчайших деталей для запуска push-сообщений).

Вы можете увидеть весь код для сопутствующего сайта здесь.

Отписаться от пользователя

Единственное, чего нам не хватает, так это возможности отписать пользователя от push. Для этого нам нужно позвонить unsubscribe() на PushSubscription.

Вернувшись в наш scripts/main.js файл, измените прослушиватель кликов pushButton в initializeUI() на следующее:

pushButton.addEventListener('click', function() {
  pushButton.disabled = true;
  if (isSubscribed) {
    unsubscribeUser();
  } else {
    subscribeUser();
  }
});

Обратите внимание, что теперь мы собираемся вызвать новую функцию unsubscribeUser(). В этом методе мы получаем текущую подписку и вызываем от нее отказ от подписки. Добавьте следующий код в scripts/main.js:

function unsubscribeUser() {
  swRegistration.pushManager.getSubscription()
  .then(function(subscription) {
    if (subscription) {
      return subscription.unsubscribe();
    }
  })
  .catch(function(error) {
    console.log('Error unsubscribing', error);
  })
  .then(function() {
    updateSubscriptionOnServer(null);
    console.log('User is unsubscribed.');
    isSubscribed = false;
    updateBtn();
  });
}

Давайте рассмотрим эту функцию.

Сначала мы получаем текущую подписку, позвонив по номеру getSubscription():

swRegistration.pushManager.getSubscription()

Это возвращает обещание, которое разрешается с PushSubscription, если оно существует, в противном случае оно возвращает null. Если есть подписка, мы вызываем ее unsubscribe(), что делает PushSubscription недействительным.

swRegistration.pushManager.getSubscription()
.then(function(subscription) {
  if (subscription) {
    // TODO: Tell application server to delete subscription
    return subscription.unsubscribe();
  }
})
.catch(function(error) {
  console.log('Error unsubscribing', error);
})

Вызов unsubscribe() возвращает обещание, так как это может занять некоторое время, поэтому мы возвращаем это обещание, чтобы следующий then() в цепочке ждал завершения unsubscribe(). Мы также добавляем обработчик catch на случай, если вызов unsubscribe() приведет к ошибке. После этого мы можем обновить наш пользовательский интерфейс.

.then(function() {
  updateSubscriptionOnServer(null);
  console.log('User is unsubscribed.');
  isSubscribed = false;
  updateBtn();
})

Попробуй это

Вы должны иметь возможность нажимать Включить push-сообщения / Отключить Push-сообщения в своем веб-приложении, и журналы покажут, что пользователь подписан и отписался.

Законченный

Поздравляем с завершением этой лабораторной работы!

Эта лаборатория кода показала вам, как приступить к работе с добавлением push-уведомлений в ваше веб-приложение. Если вы хотите узнать больше о том, что могут делать веб-уведомления, ознакомьтесь с этой документацией.

Если вы хотите развернуть push на своем сайте, вы можете быть заинтересованы в добавлении поддержки старых / нестандартных браузеров, которые используют GCM, подробнее здесь.

Ознакомьтесь с дополнительным содержанием и подробностями https://developers.google.com/web/fundamentals/codelabs/push-notifications/

Оставайтесь на связи, приложение Ionic Firebase, чтобы быть в курсе последних новостей.