Push-уведомления#
Предположим, у Вас есть приложение, созданное с помощью Clickable и размещенное в OpenStore. Но теперь Вы хотите отправлять Push-уведомления своим пользователям. Прежде всего, нужно понять, как это работает:
Каждое приложение, которое использует push-уведомления, имеет уникальный токен. Этот токен идентифицирует пользователя, устройство и само приложение. Маркер генерируется службой UBports Push.
Для отправки push-уведомления потребуется токен. Таким образом, приложение отправляет свой токен на сервер разработчика приложения.
С помощью токена можно отправить HTTP-запрос на UBports Push Server, а он перенаправит уведомление на устройство пользователя.
Давайте попробуем повторить этот алгоритм шаг за шагом.
Примечание
В следующем примере мы не будем заниматься настройками сервера. Связь между приложением и сервером зависит от вас. Пожалуйста, сообщите пользователю о соединении с сервером и попросите у него согласие с политикой конфиденциальности!
Подготовьте приложение к работе с push-уведомлениями#
Настройка PushClient#
Сначала нам нужно добавить группу политик «push-messages-client». Ваш файл для apparmor может выглядеть так:
{
"policy_groups": [
"networking",
"push-notification-client"
],
"policy_version": 16.04
}
Далее нам нужно внести изменения в Qml. Добавляем компонент pushclient:
//...
import Ubuntu.PushNotifications 0.1
//...
PushClient {
id: pushClient
appId: "myapp.yourname_hookname"
onTokenChanged: console.log("👍", pushClient.token)
}
Необходимо указать правильный appId! Если имя приложения в файле манифеста - myapp.yourname, а имя основного обработчика (которое обрабатывает файл .desktop) - это имя_хука, тогда appId будет такой: myapp.yourname_hookname. Когда мы запустим приложение, оно получит токен и запишет его в лог-файл. Из лог-файлов для clickable можно скопировать этот токен в терминале. Но приложение еще не готово для получения push-уведомления. Для этого нам понадобится pushhelper!
Реализация pushhelper#
Pushhelper - это часть приложения, которая будет получать все push-уведомления и обрабатывать их перед отправкой в центр системных уведомлений. Pushhelper получит json-файл и должен вывести другой json-файл в правильном формате. Pushhelper отделен от приложения. Итак, нам нужен новый hook в файле manifest. Это может выглядеть так:
{
//...
"title": "myapp",
"hooks": {
"myapp": {
"apparmor": "myapp.apparmor",
"desktop": "myapp.desktop"
},
"push": {
"apparmor": "push-apparmor.json",
"push-helper": "push.json"
}
},
//...
}
Должно быть понятно, что теперь нужен другой файл apparmor и другой исполняемый файл. Файл ** push-apparmor.json ** должен содержать только группу политик push-messages-client и должен выглядеть следующим образом:
{
"template": "ubuntu-push-helper",
"policy_groups": [
"push-notification-client"
],
"policy_version": 16.04
}
Файл ** push.json ** предназначен для перенаправления в исполняемый файл:
{
"exec": "pushexec"
}
В нашем уроке используется python для создания исполняемого файла ** pushexec **. Файл будет пересылать уведомление без каких-либо изменений:
#!/usr/bin/python3
import sys
f1, f2 = sys.argv[1:3]
open(f2, "w").write(open(f1).read())
Нам также нужно добавить новые файлы в ** CMakeLists.txt ** и сделать исполняемый файл pushexec:
[…]
install(FILES pushexec PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ DESTINATION ${DATA_DIR})
install(FILES push.json DESTINATION ${DATA_DIR})
install(FILES push-apparmor.json DESTINATION ${DATA_DIR})
[…]
Теперь приложение готово для получения и обработки push-уведомлений!
Использование API сервиса Push#
Теперь у нас есть токен, и приложение готово для получения и обработки push-уведомлений. Чтобы отправить уведомление, нужно отправить HTTP-запрос по этому адресу: https://push.ubports.com/notify. Тип содержимого должен быть application/json в соответствующем формате. Пример в javascript может выглядеть так:
var req = new XMLHttpRequest();
req.open("post", "https://push.ubports.com/notify", true);
req.setRequestHeader("Content-type", "application/json");
req.onreadystatechange = function() {
if ( req.readyState === XMLHttpRequest.DONE ) {
console.log("✍ Answer:", req.responseText);
}
}
var approxExpire = new Date ();
approxExpire.setUTCMinutes(approxExpire.getUTCMinutes()+10);
req.send(JSON.stringify({
"appid" : "appname.yourname_hookname",
"expire_on": approxExpire.toISOString(),
"token": "aAnqwiFn§DF%2",
"data": {
"notification": {
"card": {
"icon": "notification",
"summary": "Push Notification",
"body": "Hello world",
"popup": true,
"persist": true
},
"vibrate": true,
"sound": true
}
}
}));
Объект Push Notification#
Параметр |
Тип |
Описание |
---|---|---|
appid (идентификатор приложения) |
строка |
Обязательный параметр. ID приложения, которое получит уведомление,
как это описано в документации для клиентской части.
|
expire_on (истечение срока действия) |
строка |
Обязательный параметр. Срок (время и дата) истечения для этого сообщения, в
формате ISO8601 Extendendformat.
|
токен |
строка |
Обязательный параметр. Токен, идентифицирующий пользователя и устройство, которому предназначено сообщение
как это описано в клиентской части документации.
|
clear_pending (очистка незавершенного) |
bool |
Отменяет все предыдущие ожидающие уведомления. Обычно в ответ на
ошибку «too-many-pending». По умолчанию отключена.
|
replace_tag (заменить тэг) |
строка |
Если есть ожидающее уведомление с тем же тегом, удалите его
в очереди появится это новое сообщение.
|
данные |
Данные |
Объект JSON. Содержимое поля данных является произвольным. Мы можем использовать
его для отправки любых данных в приложение.
|
Данные#
Параметр |
Тип |
Описание |
---|---|---|
уведомление |
Уведомление |
Объект JSON, который определяет, как будет представлено это уведомление. |
сообщение |
объект |
Объект JSON, который передается приложению в состоянии «как есть» через PopAll. |
Уведомление#
Параметр |
Тип |
Описание |
---|---|---|
tag (тэг) |
строка |
Тэг push-уведомления.
|
звук |
логическая опция или путь к объекту |
Эта опция или задается логически (воспроизведение предустановленной мелодии), или
путь к звуковому файлу. Пользователь может выключить опцию, поэтому не доверяйте
этой опции полностью. По умолчанию отключена (звука нет). Путь
относительный, и будет задаваться (a) в разделе настроек приложения
.local/share/<pkgname> , и (b) в стандартных директориях xdg. |
вибрация |
bool или Вибрация |
В уведомлении может содержаться поле для вибрации, вызывающей тактильную
обратную связь, опция может быть логической (если активирована, идет вибрация
в заранее заданном режиме) или может быть выбран готовый объект.
|
еmblem-счетчика |
Еmblem-счетчика |
Объект JSON, который определяет, как отображать эмблему
счетчика.
|
карточка |
Карточка |
Объект JSON с информацией о карточке уведомления.
|
Карточка#
Параметр |
Тип |
Описание |
---|---|---|
краткое резюме |
строка |
Обязательно к заполнению. Карточка не будет видна, если это поле
не заполнено.
|
содержание |
строка |
Более длинный текст, пустой по умолчаниюю.
|
действия |
массив |
Если пустое (по умолчанию), нажатие на bubble notification
не даёт ничего. Если Вы добавите адрес URL, то bubble notifications
становятся активными и позволяют открыть этот URL. Один из способов это использовать -
настроить URL как``appid://com.ubuntu.developer.ralsina.hello``,
это позволит переключиться на приложение или запустит его.
|
иконка |
строка |
Иконка относится к событию, к которому относится уведомление. По умолчанию,
значение пустое (иконка отсутствует); дополнительная иконка относится к приложению
будет также отображаться, независимо от настроек этого поля.
|
Метка времени (timestamp) |
integer - целое число |
Секунды, прошедшие с начала эпохи Unix, пока используются только для сохранения.
Если значение не задано или нулевое, то используется текущая временная отметка.
|
сохраняться |
bool |
показывать ли в центре уведомлений; по умолчанию отключено.
|
всплывающее окно |
bool |
Показывать ли в bubble notification. Пользователи могут отключить это, и могут
легко отключить их, поэтому не нужно полагаться на эту опцию. Значения по умолчанию -
опция отключена.
|
Вибрация#
Параметр |
Тип |
Описание |
---|---|---|
модель |
массив |
Список переменных, описывающих схемы вибрации (длительность периодов
вибраций или её отсутствие - время в милисекундах).
|
повторения |
integer - целое число |
Сколько раз будет повторяться выбранняя модель (по умолчанию установлен 1 раз, 0 -
тоже самое, что и 1).
|
Emblem-счетчика#
Параметр |
Тип |
Описание |
---|---|---|
число |
integer - целое число |
Число, отображаемое над значком приложения в панели запуска (launcher). |
видимо |
bool |
Установите значение true, чтобы показать счетчик, или false, чтобы скрыть его. |