Вкратце, push-уведомления — это небольшие по объему важные сообщения от программы или сервиса, отображаемые операционной системой тогда, когда вы непосредственно не работаете с указанным приложением или сервисом. Преимущество таких уведомлений в отсутствии необходимости держать программу вечно в памяти, тратя на нее процессорные мощности и память.
Не буду здесь расписывать всю технологию доставки удаленного уведомления, ибо это уже сделано до меня. Выглядит примерно так: периодически демон опрашивает сервер и в случае появления сообщения, показывает его нам.
Для iOS придумали APNS, для Android-а — C2DM-GCM, я же хочу рассказать про кроссплатформенный (громко) сервис Pushover и связке его с php-сайтом.
Пример задачи
Предположим, что раз в день мы хотим знать что-либо о количестве заказов на сайте за день и их стоимости.
Сайт крутится на некоторой CMS на PHP и mySQL, принимающая сторона имеет стильные iPhone и Android-телефоны.
Срочность доставки сообщения не относится к жизненно-важным показателям.
Надо найти условно безгеморройное решение.
Pushover
Pushover — это скромный сервис уведомлений, а также приложения для iOS и Android, планируются поделки и для BlackBerry и OS X Mountain Lion. Сервис имеет свой API, позволяет отправлять бесплатно до 7.5 тысяч сообщений в месяц.
Сообщение, помимо основного текста сообщения длиной 512 символов, может содержать крупный заголовок, URL (тогда длина сообщения увеличивается до 500) и его тайтл (все отображается отдельными сформированными блоками, потому такое разграничение). Сообщение можно доставить под неким выбранным указанным приоритетом. Пользователь может указать «тихие» часы, когда его не стоить будить уведомления, а также подключать и отключать устройства, на которые будут приходить уведомления.
Уведомление может быть доставлено пользователям, предоставившим свой код, всем устройствам этого пользователя или по выбору. Для приема сообщения пользователю необходимо быть зарегистрированным в сервисе и обладать хотя бы одним рабочим устройством.
Добавление пользователя
После прохождения регистрации, каждый пользователь попадает в свой кабинет, где он сразу видит свой хэш-токен. Это уникальный идентификатор пользователя, на который в последствии и отправляются уведомления.
Пользователю, желающему принимать сообщения, необходимо поставить на свой телефон/планшет/абы что приложение из соответствующего магазина.
Добавление сервиса
Добавление сервиса ничуть не сложнее. Из личного кабинета надо перейти на страницу создания приложения, где предлагается описать продукт:
После заполнения соответствующих полей, нам становится известен токен приложения. В принципе, это все, что необходимо для отправки сообщения.
На странице приложения в последующем будет красивый график успешно отправленных сообщений.
Связывание приложений и получателей
… не выполняется никак. Любое приложение может отправить любому пользователю уведомление, если знает его токен. Прием токенов от населения остается на совести приложения. Также как и отписка от рассылок.
API
Небольшое, емкое и понятное. Для отправки сообщения в 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:
<?xml version="1.0" encoding="UTF-8"?> <hash> <status type="integer">1</status> </hash>
и
<?xml version="1.0" encoding="UTF-8"?> <hash> <token>invalid</token> <errors type="array"> <error>application token is invalid</error> </errors> <status type="integer">0</status> </hash>
PHP
На главной странице и в факе в разделах «смотрите, как легко!» приводятся коды простейшего скрипта на различных языках для отправки и есть ссылка на 3rd-party php-класс от Chris Schalenborgh.
Везде используется сURL, что впрочем, понятно.
Зафигарим свой класс
Куда ж нынче без велосипедов?
На самом деле, мне не слишком понравилось, что успех отправки уведомления определяется либо как true/false, либо выводится сразу вся простыня ответа сервера. Да вообще обработки ошибок нет. Считаю, что если посетителю сайта не обязательно, то разработчику надо знать, почему не отправлено то или иное сообщение.
В общем, существенно меняем все, классы уехали на GitHub.
class PushoverException extends Exception { /** * Messages array * @var array */ private $fMessages; /** * Exception constructor * @param array $aMessages An array of messages */ public function __construct(array $aMessages) { parent::__construct('PushoverException exception'); $this->fMessages = $aMessages; } /** * Get messages array * @return array */ public function getMessages() { return empty($this->fMessages) ? array() : $this->fMessages; } }
class Pushover { /* * Pushover json api service url */ const C_API_URL = 'https://api.pushover.net/1/messages.json'; /** * Properties storage array * @var array */ private $fProperties; /** * cURL instance */ private $fCurl; //--------------------------------------------------------------------------// /** * Properties getter * @param string $aPropertyName Property name * @return mixed */ public function __get($aPropertyName) { if(array_key_exists($aPropertyName, $this->fProperties)) return $this->fProperties[$aPropertyName]; return null; } /** * Properties setter * @param string $aPropertyName Property name * @param mixed $aValue Property value */ public function __set($aPropertyName, $aValue) { $this->fProperties[$aPropertyName] = $aValue; } //--------------------------------------------------------------------------// /** * Class constructor * @param string $aApplicationToken Application token */ public function __construct($aApplicationToken = null) { if(!empty($aApplicationToken)) $this->applicationToken = $aApplicationToken; $this->fCurl = curl_init(); curl_setopt($this->fCurl, CURLOPT_URL, self::C_API_URL); curl_setopt($this->fCurl, CURLOPT_HEADER, false); curl_setopt($this->fCurl, CURLOPT_RETURNTRANSFER, true); curl_setopt($this->fCurl, CURLOPT_SSL_VERIFYPEER, false); } /** * Class destructor */ public function __destruct() { curl_close($this->fCurl); } //--------------------------------------------------------------------------// /** * Throws an exceprion with single message * @param mixed $aMessage * @throws PushoverException */ public function throwMessage($aMessage) { throw new PushoverException(array($aMessage)); } /** * Throws an exceprion with an array of messages * @param array $aMessages * @throws PushoverException */ public function throwMessages(array $aMessages) { throw new PushoverException($aMessages); } //--------------------------------------------------------------------------// /** * Send pushover notification */ public function send() { if(!strlen($this->applicationToken)) $this->throwMessage('Application token is empty'); if(!strlen($this->userToken)) $this->throwMessage('User token is empty'); if(!strlen($this->notificationMessage)) $this->throwMessage('Notification message is empty'); if(intval($this->notificationTimestamp) <= 0) $this->notificationTimestamp = time(); $lSendParams = array( 'token' => $this->applicationToken, 'user' => $this->userToken, 'device' => $this->userDevice, 'title' => $this->notificationTitle, 'message' => $this->notificationMessage, 'priority' => $this->notificationPriority, 'timestamp' => $this->notificationTimestamp, 'url' => $this->notificationUrl, 'url_title' => $this->notificationUrlTitle ); foreach($lSendParams as $lKey => $lParam) if(empty($lParam)) unset($lSendParams[$lKey]); curl_setopt($this->fCurl, CURLOPT_POSTFIELDS, $lSendParams); $lResponseJson = curl_exec($this->fCurl); if($lResponseJson === false) $this->throwMessage('API request error'); $lResponse = json_decode($lResponseJson, true); if(empty($lResponse) || !is_array($lResponse)) $this->throwMessage('Bad API response'); if(!empty($lResponse['errors'])) $this->throwMessages($lResponse['errors']); if(empty($lResponse['status']) || intval($lResponse['status']) != 1) $this->throwMessage('Unknown notification send error'); } }
Минимальное сообщение теперь довольно просто отправить, ошибки можно разбирать:
$lPushover = new Pushover('Write application token here'); $lPushover->userToken = 'scecify user token'; $lPushover->notificationMessage = 'Notification message'; try { $lPushover->send(); echo '<font color="green">Message sent</font>', PHP_EOL; } catch (PushoverException $aException) { echo '<font color="red">Error sending messages</font><br>', PHP_EOL; echo '<ul>', PHP_EOL; foreach($aException->getMessages() as $lMessage) echo '<li>', $lMessage, '</li>', PHP_EOL; echo '</ul>', PHP_EOL; }
Пользователь уже принял сообщение.
Итого
Знаем об удобном сервисе удаленных уведомлений, одинаково успешно передающий сообщения пользователям Android и iOS.
Имеем рабочий механизм отправки уведомлений с сайта на PHP.
ссылка на оригинал статьи http://habrahabr.ru/post/159649/
Добавить комментарий