» » » Пара способов отправить уведомления на смартфон со своего сервера

 

Пара способов отправить уведомления на смартфон со своего сервера

Автор: admin от 1-01-2018, 17:40, посмотрело: 216

В этом туториале я рассмотрю пошагово, как отправлять со своего сервера уведомления на свой (или не свой) смартфон, какие средства для этого понадобятся. Эти способы универсальны и подойдут для любого языка программирования, т.к. напрямую используют API гугла, без использования библиотек. Отправить можно на смартфоны с Android, iOS и в браузеры с поддержкой Push API (на сегодня это Chrome, Firefox и их производные).



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

GCM (Google cloud messaging).



В настоящее время используется универсальная платформа Firebase, которая помимо доставки уведомлений имеет ещё много всяких других возможностей. Firebase тоже успела эволюционировать и протокол первого поколения уже считается устаревшим и для доставки сообщений рекомендуется использовать протокол второго поколения.



Технически, уведомления отправляются с сервера не напрямую в смартфон, а на некий промежуточный сервер, на котором при необходимости хранятся до 4-х недель (настраиваемо), и по возможности отправляются получателю. Т.е. если смартфон находится оффлайн, сервер ждёт. Как только появляется возможность — отправляет.



1. Регистрируемся в Firebase



Для регистрации в Firebase понадобится учётка гугла.



Пара способов отправить уведомления на смартфон со своего сервера


Жмём «Перейти к консоли».



Пара способов отправить уведомления на смартфон со своего сервера


Затем «Добавить проект».



Пара способов отправить уведомления на смартфон со своего сервера


Вводим название проекта. Рекомендую в диапазоне 8-16 символов.

Выбираем страну. Жмём «Создать проект».



2. Настраиваем Firebase



Пара способов отправить уведомления на смартфон со своего сервера


Прокручиваем до блока «Notifications», жмём «Начать».



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



Пара способов отправить уведомления на смартфон со своего сервера


Шаги для Andriod-приложения:



Пара способов отправить уведомления на смартфон со своего сервера


Шаг 1 — Вводим название проекта на Andriod.

Жмём «Зарегистрировать приложение».



Пара способов отправить уведомления на смартфон со своего сервера


Шаг 2 — Жмём «Скачать google-services.com».

Добавляем скачанный файл конфигурации в проект, рядом с файлом build.gradle (тем, который персональный для приложения).

Жмём «Продолжить».



Пара способов отправить уведомления на смартфон со своего сервера


Шаг 3 — Добавляем в проект зависимости.

в файл /build.gradle строчку

classpath 'com.google.gms:google-services:3.1.0'

в файл /developers.google.com/identity/protocols/OAuth2ServiceAccount)

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

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



<?php
  // ------------------------ test fcm send. modern ------------------------ //

  // -- шаг 1. вычисляем JWT -- //
$JWT_header = base64_encode('{"alg":"RS256","typ":"JWT"}');

$issue_time = time();

$JWT_claim_set = base64_encode(
'{"iss":"firebase-adminsdk-mvxyi@<your-project>.iam.gserviceaccount.com",'.
 '"scope":"https://www.googleapis.com/auth/firebase.messaging",'.
 '"aud":"https://www.googleapis.com/oauth2/v4/token",'.
 '"exp":'.($issue_time + 3600).','.
 '"iat":'.$issue_time.'}');
  // см. примечание

$private_key = '
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCwR1biSUCv4J4W
****************************************************************
****************************************************************
...
****************************************************************
teTJImCT6sg7go7toh2ODfaPmeI0nA/LwSjzWs0b8gdIYPT5fAsvfQiND0vu/M3V
7C/z/SmIKeIcfOYrcbWQwTs=
-----END PRIVATE KEY-----
';

$data = $JWT_header.'.'.$JWT_claim_set;
$binary_signature = '';

openssl_sign($data, $binary_signature, $private_key, 'SHA256');

$JWT_signature = base64_encode($binary_signature);


$JWT = $JWT_header.'.'.$JWT_claim_set.'.'.$JWT_signature;



  // -- шаг 2. авторизируемся и получаем токен -- //

$socket = @fsockopen('ssl://www.googleapis.com', 443, $errno, $errstr, 10);

if (!$socket)  die('error: remote host is unreachable.');


$payload = 'grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion='.rawurlencode($JWT);

$send  = '';
$send .= 'POST /oauth2/v4/token HTTP/1.1'."rn";
$send .= 'Host: www.googleapis.com'."rn";
$send .= 'Connection: close'."rn";
$send .= 'Content-Type: application/x-www-form-urlencoded'."rn";
$send .= 'Content-Length: '.strlen($payload)."rn";
$send .= "rn";

$send .= $payload;


$result = fwrite($socket, $send);

$receive = '';
while (!feof($socket))  $receive .= fread($socket, 8192);

fclose($socket);

echo '<pre>'.$receive.'</pre>';



  // -- parse answer JSON (lame) -- //

$line = explode("rn", $receive);
if ($line[0] != 'HTTP/1.1 200 OK')  die($line[0]);

$pos = FALSE;
if (($pos = strpos($receive, "rnrn", 0)) !== FALSE ) {
  if (($pos = strpos($receive, "{", $pos+4)) !== FALSE ) {
    if (($pose = strpos($receive, "}", $pos+1)) !== FALSE ) {
      $post = substr($receive, $pos, ($pose - $pos+1) );
      $aw = json_decode($post, TRUE);
      $access_token = $aw['access_token'];
      }
    else die('} not found.');
    }
  else die('{ not found.');
  }
else die('rnrn not found.');



    // -- шаг 3. отправляем запрос на Firebase сервер -- //

$socket = @fsockopen('ssl://fcm.googleapis.com', 443, $errno, $errstr, 10);

if (!$socket)  die('error: remote host is unreachable.');


$payload = '{
  "message":{
    "token" : "cGAFgPJGf-s:APA91bF**...**aEVM17c9peqZ",
    "notification" : {
      "title" : "Заголовок сообщения",
      "body" : "(Modern API) Моё первое сообщение через Firebase!"
      }
   }
}';
// или
  $payload = '{
"message": {
  "token" : "cGAFgPJGf-s:APA91bF**...**aEVM17c9peqZ",
  "data":{
    "val1" : "Заголовок сообщения",
    "val2" : "(Modern API) Моё первое сообщение через Firebase!",
    "val3" : "дополнительные данные"
    }
  }
}';


$send  = '';
$send .= 'POST /v1/projects/pyur-test-id/messages:send HTTP/1.1'."rn";
$send .= 'Host: fcm.googleapis.com'."rn";
$send .= 'Connection: close'."rn";
$send .= 'Content-Type: application/json'."rn";
$send .= 'Authorization: Bearer '.$access_token."rn";
$send .= 'Content-Length: '.strlen($payload)."rn";
$send .= "rn";

$send .=$payload;


$result = fwrite($socket, $send);

$receive = '';
while (!feof($socket))  $receive .= fread($socket, 8192);

fclose($socket);


echo '<pre>'.$receive.'</pre>';

?>




Пара способов отправить уведомления на смартфон со своего сервера


по адресу console.firebase.google.com/project/poject-id/settings/serviceaccounts/adminsdk надо скопировать «Сервисный аккаунт Firebase» и подставить в переменную "$JWT_claim_set", в поле «iss».



Жмём «Создание закрытого ключа»



Пара способов отправить уведомления на смартфон со своего сервера


Создаём ключ, сохраняем, никому не показываем. В скачанном файле будет содержаться «Закрытый ключ», его подставляем в переменную "$private_key".



Хинт: токен, полученный в шагах 1 и 2 можно и нужно кешировать в локальном временном хранилище, например файле, или базе данных. И только по истечении времени (по умолчанию один час), запрашивать у сервера авторизации следующий токен.



Пара способов отправить уведомления на смартфон со своего сервера


Важно! Перед использованием Modern Http API необходимо явно разрешить его использование здесь: console.developers.google.com/apis/library/fcm.googleapis.com/?project=your-project



Бонус, дополнительные параметры для уведомлений:



sound — либо «default», либо имя ресурса в приложении. Должен располагаться в "/res/raw/". Формат MP3, AAC или ещё чего подходящее.

icon — меняет иконку уведомления. Должна храниться в «drawable» приложения. Если отсутствует, FCM будет использовать иконку приложения (указанную как «launcher icon» в манифесте приложения).

tag — Следует использовать для группировки однотипных уведомлений. Новые уведомления будут выводиться поверх уже имеющихся с таким же тегом.

color — цвет иконки, задаётся как "#rrggbb" (у меня в MIUI не заработало)

click_action — запускаемое активити, при нажатии пользователем на уведомлении.



Заключение



В будущем API вероятно будет изменяться, объявляться depricated и т.п. Поэтому сегодня думаю стоит делать сразу на протоколе HTTP v1.



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



Да, я в курсе, что существует Zabbix и т.п., но тема статьи — домашние сервера, и прочие умные дома. Считаю системы корпоративного класса перебором в любительских поделках.

Источник: Хабрахабр

Категория: Операционные системы » Android

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

Добавление комментария

Имя:*
E-Mail:
Комментарий:
Полужирный Наклонный текст Подчеркнутый текст Зачеркнутый текст | Выравнивание по левому краю По центру Выравнивание по правому краю | Вставка смайликов Выбор цвета | Скрытый текст Вставка цитаты Преобразовать выбранный текст из транслитерации в кириллицу Вставка спойлера
Введите два слова, показанных на изображении: *