Реализуем пуш-уведомления на фронтенде и бэкенде
В предыдущей статье об iss-observer.com я обещал рассказать о технической стороне реализации пуш-уведомлений. Изначально я планировал сконцентрироваться на проблемах, с которыми пришлось иметь дело в процессе работы над iss-observer.com. Теперь я думаю, будет полезнее посвятить материал базовым вопросам, и уточнять детали, где это необходимо. Обращаю ваше внимание, что фронтенд частично опирается на этот урок.
Если вы хотите углубиться в исходный код, то смотрите в GitHub-репозиторий и на пример , демонстрирующий его работу.
Фронтенд
Начнем с клиентской части. Первое, что нужно сделать — убедиться, что браузер поддерживает пуш-уведомления. Если да, загружаем наш JavaScript.
Прежде чем писать код, выполним ряд требований. Нам потребуются Application Server Keys (VAPID Key). Получаем их здесь, либо с помощью библиотеки web-push. Кстати, она нам еще потребуется для бэкенд-части. Устанавливаем библиотеку: npm install -g web-push , генерируем ключи: web-push generate-vapid-keys . В независимости от способа в результате у вас должны быть закрытый ключ (private key) и открытый ключ (public key). Сохраните их в надежном месте.
До появления спецификации Application server key/VAPID первые браузеры (Chrome, Opera) реализовали функциональность пуш-уведомлений с помощью Google Cloud Messaging . Все современные браузеры, за исключением Samsung Internet , поддерживают VAPID. Поэтому в этой статье я не буду касаться GCM. Как добавить поддержку для Samsung Internet и старых версий Chrome и Opera — читайте здесь .
Посмотрим на push.js. Здесь мы регистрируем сервис-воркер и подписываемся на уведомления:
В первую очередь создаем константу addServiceKey : ей присваиваем значение с открытым ключ VAPID (о нем мы говорили выше). Также создаем несколько элементов и переменных. Записываем функцию urlB64ToUint8Array() : она понадобится для конвертации ключа из base64 в Uint8Array.
Затем декларируем функцию updatePushButton() . Мы будем вызывать её каждый раз при изменении статуса уведомлений, чтобы обновить отвечающие за него элементы интерфейса.
Далее видим функцию регистрации подписки subscribeUser() . Как вы наверно заметили, в начале скрипта была объявлена переменная let serviceWorkerRegistration . Она содержит результат регистрации сервис-воркера: посмотрите в конец файла, мы записываем его в переменную в момент регистрации.
Метод subscribe() возвращает промис, а в качестве аргумента принимает объект с двумя свойствами:
- userVisibilityOnly : булево значение. Параметр сообщает, что подписка будет использоваться только для сообщений, эффект которых виден для пользователя. Устанавливаем значение true .
- applicationServiceKey : номер открытого ключа, он используется сервером для отправки уведомлений. Так как ключ должен быть в формате UInt8Attay, используем уже знакомую нам функцию.
Теперь отправляем данные подписки на сервер. Смело используем Fetch API, так как все браузеры, которые поддерживают пуш-уведомления, поддерживают и Fetch. После получения ответа выводим результат — завершена ли подписка успешно.
Этот этап прекрасно подходит для уточнения нужных параметров у пользователя. Например, на iss-observer.com он может выбрать время получения уведомлений (утро и/или вечер). Я также отправляю на сервер данные о стране, регионе и городе, по которому пользователь хочет получать уведомления; данные сохраняются и могут потребоваться при отправке уведомлений.
После этого, создаем функцию отписки unsubscribeUser() . Используем метод getSubscription() объекта PushManager , с его помощью получаем детали подписки, которые отправляем на сервер (снова Fetch API). На этот раз, чтобы удалить её базы.
Записываем функцию initPush() . В ней — событие для кнопки pushButton, которое вызывает функцию подписки или отписки в зависимости от текущего состояния. После, не забываем обновить это состояние. Использованный в примере код можно найти на GitHub.
Последний шаг — регистрация сервис-воркера.
Сервис-воркер
В этой части мы разберем два необходимых для реализации пуш-уведомлений события: push и notificationonclick .
Начнем с push . Проверяем содержимое объекта notificationData (свойства title , body и icon ), и, если не находим их, присваиваем дефолтные значения. После вызываем метод showNotification , он покажет уведомление пользователю.
В дополнение к трём перечисленным свойствам могут использоваться и другие, например, badge , tag , vibrate . На момент написания этой статьи (февраль 2017) многие из них поддерживались только некоторыми браузерами. title , body и icon , доступных во всех браузерах, поэтому ограничимся ими.
Событие notificationOnClick срабатывает в момент клика по уведомлению. Сначала закрываем уведомление. Затем проверяем, открыт ли наш сайт в текущей вкладке браузера, если нет, то открываем его с помощью openWindow() .
Бэкенд
Переходим к серверной части, в которой мы используем web-push library. В нашем случае это реализация библиотеки для Node.js, но версии для PHP, Java и C# также доступны.
Я предполагаю, что у вас есть базовые знания Node.js и опыт использования Express. В ином случае, я рекомендую вам ознакомиться с ними прежде чем продолжить.
Итак, в первую очередь:
- устанавливаем библиотеку командой npm install web-push —save ,
- получаем доступ к ней с помощью require : const webPush = require(‘web-push’);
Теперь передаем данные VAPID. Помимо сгенерированной в начале пары ключей, нужно указать адрес электронной почты (с префиксом mailto: ) либо URL сайта. Контактные данные могут потребоваться сервису для связи с вами. Обратите внимание на комментарии: я предпочел сохранить ключи в переменную окружения. Вы можете поступить так же или выбрать свой метод, но главное помните, закрытый ключ должен быть всегда защищен от обращений извне. Собственно поэтому он так и назван.
Переходим к функции подписки:
В функции отправки подписки на сервер, получаем доступ к объекту subscription . В нем — значение endpoint и ключи доступа. Здесь я не буду останавливаться на вопросах работы с базой данных. Для примера укажу только, что для демо использована Mongo DB.
Прим. переводчика: endpoint — это уникальный URI, создаваемый для каждого пользователя индивидуально в соответствии с паттерном : p256dh — открытый ключ, auth — закрытый ключ.
Затем получаем наше первое уведомление — то, которое приветствует подписавшегося пользователя. Метод sendNotification() принимает три аргумента:
- данные подписки, получаемые от браузера;
- информацию для пользователя (заголовок, сообщение, иконка — свойства title , body , icon соответственно);
- объект options , см. подробнее.
TTL (Time To Live) — срок жизни уведомления —по умолчанию четыре недели. Это значит, что оно будет ожидать появления пользователя онлайн в течение этого срока. Например, если вы отправили уведомление пользователю в оффлайне, и он подключится к сети только через две недели, сообщение все равно будет доставлено. В моем случае разумно изменить TTL на более короткий срок.
Если пользователь отменяет подписку, удаляем информацию о ней из базы.
Дополнительно
Вероятно, каждый из вас столкнется со своим случаем применения пуш-уведомлений, и просто скопировать код не получится. Однако я надеюсь, что этот урок поможет вам реализовать искомую функциональность как на стороне клиента, так и на стороне сервера.
Демо проекта, исходный код опубликован на GitHub.
Для более глубокого погружения в тему рекомендую бесплатную книгу Web Push Book и примеры на servicewore.rs.
Если вам есть что спросить, или есть что добавить, пишите в Twitter или по электронной почте.
Источник
Сервис push-уведомлений Pushover для Android и iOS в связке с PHP
Пример задачи
Предположим, что раз в день мы хотим знать что-либо о количестве заказов на сайте за день и их стоимости.
Сайт крутится на некоторой CMS на PHP и mySQL, принимающая сторона имеет стильные iPhone и Android-телефоны.
Срочность доставки сообщения не относится к жизненно-важным показателям.
Надо найти условно безгеморройное решение.
Pushover
Pushover — это скромный сервис уведомлений, а также приложения для iOS и Android, планируются поделки и для BlackBerry и OS X Mountain Lion. Сервис имеет свой API, позволяет отправлять бесплатно до 7.5 тысяч сообщений в месяц.
Сообщение, помимо основного текста сообщения длиной 512 символов, может содержать крупный заголовок, URL (тогда длина сообщения увеличивается до 500) и его тайтл (все отображается отдельными сформированными блоками, потому такое разграничение). Сообщение можно доставить под неким выбранным указанным приоритетом. Пользователь может указать «тихие» часы, когда его не стоить будить уведомления, а также подключать и отключать устройства, на которые будут приходить уведомления.
Уведомление может быть доставлено пользователям, предоставившим свой код, всем устройствам этого пользователя или по выбору. Для приема сообщения пользователю необходимо быть зарегистрированным в сервисе и обладать хотя бы одним рабочим устройством.
Добавление пользователя
После прохождения регистрации, каждый пользователь попадает в свой кабинет, где он сразу видит свой хэш-токен. Это уникальный идентификатор пользователя, на который в последствии и отправляются уведомления.
Пользователю, желающему принимать сообщения, необходимо поставить на свой телефон/планшет/абы что приложение из соответствующего магазина.
Добавление сервиса
Добавление сервиса ничуть не сложнее. Из личного кабинета надо перейти на страницу создания приложения, где предлагается описать продукт:
После заполнения соответствующих полей, нам становится известен токен приложения. В принципе, это все, что необходимо для отправки сообщения.
На странице приложения в последующем будет красивый график успешно отправленных сообщений.
Связывание приложений и получателей
… не выполняется никак. Любое приложение может отправить любому пользователю уведомление, если знает его токен. Прием токенов от населения остается на совести приложения. Также как и отписка от рассылок.
Небольшое, емкое и понятное. Для отправки сообщения в POST-запросе к api.pushover.net/1/messages.json или api.pushover.net/1/messages.xml минимально необходимо указать:
- token — хэш-токен вашего приложения или сервиса.
- user — хэш-токен пользователя, которому вы отправляете уведомление.
- message — текстовая часть сообщения.
Дополнительно к этому можно добавить:
- device — идентификатор устройства пользователя, дабы не отсылать уведомления сразу на все его устройства
- title — заголовок сообщения, если не указан, будет показано название сервиса
- url — ссылка на web-страницу, если в этом есть необходимость
- url_title — заголовок к ссылке
- priority — приоритет сообщения, ставится в 1 для высокого приоритета, обходящего все «тихие» часы и -1 для тихого уведомления.
- timestamp — UNIX метка времени, когда это уведомлениебыло создано. Расписания доставки сообщений сервисом не предусмотрено.
Ответ сервера
Ответ сервера будет представлен в json или xml формате (в зависимости от расширения вызываемого скрипта).
Если все прошло удачно будет отдан объект содержанием поля status, равном 1.
Иначе, поле status будет содержать нечто иное, а поле errors — массив описания ошибок. Вот примеры ответов удачной и неудачной отправок в формате XML:
и
На главной странице и в факе в разделах «смотрите, как легко!» приводятся коды простейшего скрипта на различных языках для отправки и есть ссылка на 3rd-party php-класс от Chris Schalenborgh.
Везде используется сURL, что впрочем, понятно.
Зафигарим свой класс
Минимальное сообщение теперь довольно просто отправить, ошибки можно разбирать:
Источник
Push рассылки на PHP (Android и IOS). Минимальное готовое решение
О рассылке Push уведомлений уже много раз писали на Хабре, например тут и тут, но прямого руководства к действию до сих пор нет. Итак, если интересно, прошу под кат.
Регистрация токенов устройств
В первую очередь разработчик приложения творит магию, в которой указывает адрес регистрации, он может быть таким: htpp://test.ru/secret/android?token=value и htpp://test.ru/secret/ios?token=value.
Самое примечательное что защиты от левых регистраций просто нет, хотя может магия подвела либо была не совсем качественной, если все таки защита есть, отпишите в комментариях, я обязательно дополню статью полезным советом.
На входе получаем значение токена который приходит при установке приложения, могут быть небольшие задержки, но буквально 10-20 секунд. Токены уникальны, но можно сделать и проверку на уникальность при записи в базу данных.
Пример токена для android:
На этом шаге с регистрацией устройств мы закончили.
Рассылка уведомлений
Apple использует сервис APNS, а Google GCM (C2DM считается устаревшим, учитывайте это) и после прочтения документации можно перейти к любимому делу, а именно к велосипедостроению, но бюджет был ограничен и я начал поиски готовых решений. Самое годное что встретилось это ApnsPHP и GCMMessage, работают как на 5.3+ так и на 5.4+.
При использовании библиотек самое главное получить правильные сертификаты и секретную фразу в случае с APNS и секретный токен для работы с GCM.
Пример готового кода для отправки уведомлений для GCM, токены советуют отправлять пачкой, работает даже при больших количествах довольно таки быстро, сервис возвращает недействительные токены (пользователи удалили приложение), их сразу стоит удалить.
Везде пишут что APNS весьма прост в использовании, в принципе это соответствует действительности, если учитывать что есть сертификаты для теста и продакшена, стоит обратить внимание, нужен сертификат, секретная фраза и корневой сертификат, все это получается в личном кабинете разработчика.
Пользователи имеют свойство удалять особо назойливые приложения, так что перед отправкой стоит удалить мертвые токены.
Затем сама отсылка:
Если Вы не напутали с сертификатами, то рассылка пройдет успешно.
Источник