Сервис push-уведомлений Pushover для Android и iOS в связке с PHP

от автора


Вкратце, 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

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

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/


Комментарии

Добавить комментарий

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