Ukr post

Tracking notifier для Укрпошта

Как уже было упомянуто, статья посвящена решению задачи интеграции веб-приложения с веб-сервисом отслеживания посылок УДППЗ «Укрпошта». Если у Вас однажды вдруг возникнет необходимость реализовать нечто подобное, думаю эти полевые записки могут Вам пригодиться.

Итак, начнём с самого начала: предположим, Вы ожидаете посылку, и у Вас имеется международный трек-номер для отслеживания, вида CA123456789UA. Если Вам не часто приходится отслеживать посылки, то, думаю, предлагаемая форма для отслеживания на официальном сайте почтовой службы Вас вполне устроит. Однако же если задача состоит в том, чтобы, например, прикрутить некий сервис на своём сайте, который позволяет автоматически отслеживать список отправлений по трек-номерам и информировать пользователя о статусе посылки, то тут уже необходим другой подход.

Для подобных задач у УДППЗ «Укрпошта» предусмотрен веб-сервис http://services.ukrposhta.ua/barcodestatistic/barcodestatistic.asmx с одной единственной (по крайней мере единственной задокументированной) функцией - GetBarcodeInfo, которой, впрочем, вполне достаточно для наших нужд.

Документация по использованию сервиса в природе также существует, и скачать её можно здесь, однако, в документе рассматривается лишь скудненький пример реализации на C#, да и вообще "документация" эта составлена как-то на отъ*бись. Хотя всё же кое-какая информация может оказаться полезной.

Рассмотрим простенький примерчик работы с сервисом на PHP. Для начала работы с сервисом в PHP-скрипте подключаемся к нему по сокету:

...    
// Подключаемся к веб-сервису:
$client = new SoapClient('http://services.ukrposhta.ua/barcodestatistic/barcodestatistic.asmx?WSDL');
...    

Далее, для того, чтобы воспользоваться функцией сервиса GetBarcodeInfo, нужно передать ей в качестве параметра объект, который содержит некоторые обязательные поля. Эти поля описаны и прокомментированы во фрагменте кода ниже:

 ...
$params = new stdClass(); // Создаём объект
$params->guid = 'fcc8d9e1-b6f9-438f-9ac8-b67ab44391dd'; // guid - своего рода API-key
$params->culture = 'uk'; // Указание, на каком языке сервис будет отдавать нам информацию
$params->barcode = 'CA123456789UA'; // Трек номер отправления, по которому хотим получить информацию
...

А теперь, собственно, вызываем функцию GetBarcodeInfo, передав ей вышеописанный объект в качестве параметра, и получаем результат в переменную $result:

...
// Производим запрос и получаем результат:
$result = $client->GetBarcodeInfo($params)->GetBarcodeInfoResult;
...

Если мы после этого распечатаем объект $result, то увидим нечто подобное:

...
stdClass Object
(
    [barcode] => CA123456789UA
   	[code] =>  
    [lastofficeindex] =>  
    [lastoffice] => 
    [eventdescription] => Дані про відправлення за номером CA123456789UA на даний час відсутні, тому що не зареєстровані в системі.
)
...

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

Параметры на вход GetBarcodeInfo:
guid По всей видимости, это нечто вроде API-key или user ID, по поводу ключа в документации написано: "для тестов берите этот: ...". Прбовал получить ответ у поддержки по поводу этого guid - мол, где взять "постоянный" или "легальный" guid, но на моё письмо мне так никто и не ответил... Ну норм, чё, пользую тот, который указан в документации. Он вполне рабочий...
culture Тут вроде как, всё понятно: указываем язык, на котором нам будет возвращена текстовая информация. Доступно для использования только 2 варианта: uk - Українська и en - English
barcode Думаю, здесь вопросов тоже нет. Указываем наш код отслеживания в международном формате.
Параметры на выходе. Свойства GetBarcodeInfoResult:
barcode Возвращён наш код отслеживания. Можно пользовать для сверки.
code Код статуса посылки. Почти полный перечень статусов с примерами можно просмотреть в документации здесь.
lastofficeindex Почтовый индекс последнего почтового отделения, в котором посылка была зарегистрирована и выполнена указанная операция.
lastoffice Название последнего почтового отделения, в котором посылка была зарегистрирована и выполнена указанная операция. Например: КИЇВ 1.
eventdescription Текстовое описание события. Например: Відправлення за номером XXXXXXXXXXXXX знаходиться в процесі оброблення. Востаннє воно зареєстроване DD.MM.YYY в об’єкті поштового зв’язку XXXXX з індексом XXXXX.

Ну а теперь можно и написать скрипт, который будет извлекать из базы поочерёдно номера и получать по ним информацию.

В примере ниже приведён фрагмент кода, который я использовал для решения МОЕЙ задачи. Вы же можете оптимизировать и модифицировать его с учётом специфики своей задачи. Для облегчения понимания код здесь максимально упрощён.

// Опустим такие тривиальные вещи, как подключение к базе и пр...
...
// Подключаемся:
$client = new SoapClient('http://services.ukrposhta.ua/barcodestatistic/barcodestatistic.asmx?WSDL');

// Формируем объект для создания запроса к сервису:
$params = new stdClass();
$params->guid = 'fcc8d9e1-b6f9-438f-9ac8-b67ab44391dd';
$params->culture = 'uk';

// Подключаем класс для работы с СМС-ками:
include( "NexmoMessage.php" );

// Извлекаем все коды, находящиеся в таблице:
$query = mysql_query('SELECT * FROM `tracks`', $connect);
while($row = mysql_fetch_object($query))
{
 $params->barcode = $row->barcode;
 $result = $client->GetBarcodeInfo($params)->GetBarcodeInfoResult;

 // Если хранимый в базе lastofficeindex изменился, значит эта посылка уже продвинулась дальше...
 if((int)$result->lastofficeindex != (int)$row->lastcode){
      if($row->match=='*' || ((int)$row->match==(int)$result->lastofficeindex)){
      // Обновим данные в нашей таблице:
      $upd_query = mysql_query("UPDATE `tracks` SET `lastcode`=".(int)$result->lastofficeindex." WHERE `barcode`='".mysql_real_escape_string($row->barcode)."'");

      // И шлём уведомление на соотв. номер телефона:
      $sms = new NexmoMessage(/* Ваши API credentials*/);
      $sms->sendText($row->phone , 'Tracking Bot', 'Посылка ['.utf8_encode($row->name).'] прибыла в '.$result->lastoffice.' ('.(int)$result->lastofficeindex.')', true );
      }
 }
}
...

Для отправки СМС я использовал сервис nexmo.com, потому как он максимально прост в использовании. Сервис вообщем-то платный, но предоставляет новым пользователям "халяву" в размере €2, чего вполне хватит для отправки ~40 СМС на украинские операторы. Если интересно, - более детальную информацию по использованию, Вы можете найти здесь.

Если вам не нужен СМС сервис, Вы вполне можете вставить вместо него e-mail рассылку и т.д.

И последний штрих - повесить всю задачу на крон (Cron job). В моём случае я использовал периодичность запуска - каждый час. Хотя, вообщем, это достаточно часто. Вполне приемлемая периодичность, скажем, 4 часа.

UPD: Возможно, Вас также заинтересует связанный по тематике материал: "Telegram Bot для отслеживания посылок через API Укрпошта"
Google Plus