Пользователь
0,0
рейтинг
14 июля 2013 в 17:52

Разработка → Автоматическое оповещение об изменениях статуса почтовых посылок через SMS из песочницы tutorial

В последнее время я стал делать много покупок в интернет-магазинах, и нередко ловлю себя на том, что очень часто проверяю статус своих посылок (с нашей почтой не беспокоиться не получится).
Поиск готовых решений приводил только к платным сервисам. В результате было принято решение сообразить что-нибудь свое.
Под катом список используемых сервисов и подробная инструкция.

Выбор вспомогательных сервисов


Следующий шаг поисков был посвящен сервисам, предоставляющим возможность периодического выполнения различных скриптов за неимением (ах, какая досада) личного сервера. Выбор пал на Google Apps Script. В качестве ЯП используется модификация хорошо знакомого мне Javascript.
В качестве SMS-гейта был выбран SMS.ru, предоставляющий возможность отправки неограниченного количества бесплатных SMS стандартной длины (180 символов латиницы, 60 юникода) на личный номер телефона.
Функцию трекинга было решено позаимствовать у [не знаю, насколько] универсального китайского сервиса 17track.

Если у вашего оператора есть email2sms-гейт, то все упоминания SMS.ru можно пропускать.

Приготовления


До того, как приступить к написанию… кода, нам нужны:
  • аккаунты на Google (вдруг у кого нет) и SMS.ru
  • API ID от SMS.ru
  • созданный пустой проект на Google Apps Script
  • хеш, без которого 17track откажется нам выдавать статус, для каждого трек-номера


Подробно расписывать процесс регистрации, надеюсь, не нужно.

API ID для SMS.ru можно получить здесь: online.sms.ru/?panel=settings&subpanel=api


Для создания скрипта в Google Apps Script требуется, как ни странно, пройти на сайт этого сервиса.
Там нас встретит следующее окно (если оно не было отключено ранее):

Нам нужен «Пустой проект».

Хеш для 17track не придется получать, генерация теперь производится силами Google Apps Script. Готовый код для вставки в скрипт можно получить здесь.

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

Код


var user = ["%API ID%", "%TELNO%"];

var num = [
  ["%TRACKCODE1%", "%NAME1%"],
  ["%TRACKCODE2%", "%NAME2%"],
  ...
  ["%TRACKCODEn%", "%NAMEn%"],
];

var errors = {
  "hsErr": "Wrong hash",
  "unAllow": "You've changed parameter \"lo\" in query URL. Set it to \"www.17track.net\"",
  "hsNon": "There's no hash"
}
var success = false;

function sendSMS(text){
  UrlFetchApp.fetch("http://sms.ru/sms/send?api_id="+user[0]+"&to="+user[1]+"&text="+encodeURI(text));
}

function digest2str(digest){
  var str = '';
  var i = 0;
  for (i=0; i<digest.length; i++) {
    byte = digest[i];
    if (byte < 0)
      byte += 256;
    byteStr = byte.toString(16);
    // Ensure we have 2 chars in our byte, pad with 0
    if (byteStr.length == 1) byteStr = '0'+byteStr;
    str += byteStr;
  }   
  return str;
}

function checkStatus(){
  var i = 0;
  for(i=0; i<num.length; i++){
    var response = UrlFetchApp.fetch("http://www.17track.net/r/handlertrack.ashx?callback=&num="+num[i][0]+"&pt=0&cm=0&cc=0&_="+Math.random());
    UserProperties.setProperty("q", response.getContentText());
    var result = Utilities.jsonParse(response.getContentText());
    var sendstring = num[i][1]+": ";
    if(result["ret"] == 1){
      if(result["dat"]["f"] == "0"){
        sendstring += "Track code not found";
      }else{
        success = true;
      }
    }else{
      sendstring += errors[result["msg"]] ? errors[result["msg"]] : "Please, leave comment on habrahabr, error message: "+result["msg"];
    }
    if(success){
      if(UserProperties.getProperty(num[i][0]) != result["dat"]["z"]["b"]){
        translit = UrlFetchApp.fetch("http://translate.google.com/translate_a/t?client=t&q="+encodeURI(result["dat"]["z"]["b"]));
        translitobj = Utilities.jsonParse(translit.getContentText());
        if(translitobj[0][0][3]){
          for(z in translitobj[0]){
            sendstring += translitobj[0][z][3]+" ";
          }
        }else{
          sendstring += result["dat"]["z"]["b"];
        }
        sendSMS(sendstring);
        UserProperties.setProperty(num[i][0], result["dat"]["z"]["b"]);
        success = false;
      }
    }else{
      sendSMS(sendstring);
    }
  }
}

Также можно не возиться с sms.ru, если у вашего оператора есть email2sms-гейт. Например, инструкции для Мегафон Удмуртия. Если есть, обнаружить на сайте оператора можно поиском по слову «e-mail». Убрана транслитерация (если у кого-то гейт не умеет клеить сообщения, сообщите, сделаю версию с транслитерацией). Название кода складывается в тему сообщения.
Код
var user = [
  "%EMAIL1%",
  "%EMAIL2%",
  ...
  "%EMAILn%"
];
var num = [
  ["%TRACKCODE1%", "%NAME1%"],
  ["%TRACKCODE2%", "%NAME2%"],
  ...
  ["%TRACKCODEn%", "%NAMEn%"],
];
var errors = {
  "hsErr": "Wrong hash",
  "unAllow": "You've changed parameter \"lo\" in query URL. Set it to \"www.17track.net\"",
  "hsNon": "There's no hash"
}
var success = false;

function sendSMS(code, text){
  var i = 0;
  for(i=0; i<user.length; i++){
    MailApp.sendEmail(user[i],
                   code,
                   text);
  }
}

function digest2str(digest){
  var str = '';
  var i = 0;
  for (i=0; i<digest.length; i++) {
    byte = digest[i];
    if (byte < 0)
      byte += 256;
    byteStr = byte.toString(16);
    if (byteStr.length == 1) byteStr = '0'+byteStr;
    str += byteStr;
  }   
  return str;
}

function checkStatus(){
  var i = 0;
  for(i=0; i<num.length; i++){
    hashstr = num[i][0]+"{EDFCE98B-1CE6-4D87-8C4A-870D140B62BA}0{EDFCE98B-1CE6-4D87-8C4A-870D140B62BA}www.17track.net";
    dig = Utilities.computeDigest(Utilities.DigestAlgorithm.MD5, hashstr);
    hs = digest2str(dig);
    var response = UrlFetchApp.fetch("http://s1.17track.net/Rest/HandlerTrackPost.ashx?lo=www.17track.net&num="+num[i][0]+"&hs="+hs);
    UserProperties.setProperty("q", response.getContentText());
    var result = Utilities.jsonParse(response.getContentText().replace(/^\((.*)\)$/, "$1"));
    var code = num[i][1]
    var sendstring = "";
    if(result["ret"] == 1){
      if(result["dat"]["f"] == "0"){
        sendstring += "Track code not found";
      }else{
        success = true;
      }
    }else{
      sendstring += errors[result["msg"]] ? errors[result["msg"]] : "Please, leave comment on habrahabr, error message: "+result["msg"];
    }
    if(success){
      if(UserProperties.getProperty(num[i][0]) != result["dat"]["z"]["b"]){
        sendstring += result["dat"]["z"]["b"];
        sendSMS(code, sendstring);
        UserProperties.setProperty(num[i][0], result["dat"]["z"]["b"]);
        success = false;
      }
    }else{
      sendSMS(code, sendstring);
    }
  }
}


Оговорюсь только о том, что в качестве флага, было оповещение по этому статусу или нет, используется дата последнего статуса, которая сохраняется в User Properties и сравнивается каждый раз.

В код остается подставить API ID, номер телефона и пары трекинг-номер/хеш. Теперь нужно настроить периодическое выполнение этого скрипта. Для этого идем в «Ресурсы->Триггеры текущего проекта», нажимаем «Добавить триггер» и настраиваем по образу и подобию (промежуток можно выбрать свой):


Результатом будут такие сообщения на мобильный телефон при обнаружении изменений в статусе:


Вопросы и предложения с альтернативами, исправлениями и оптимизациями принимаются.

P.S.: благодарю неизвестного (или это я просто не нашел?) хабраюзера за предоставленный инвайт.

UPD:
  1. Функциональные изменения: добавлено присвоение своих имен посылкам (отображаются вместо трек-кодов) и отлов ошибок (известны только две ошибки, если ошибка неизвестна, ее код придет в SMS, сообщите его здесь, мне в личку или через skype/twitter, ID в профиле).
  2. «Внутренние» изменения: обработка ответа сервиса сделана как нормальный JSON, а не костыльными RegExp.

Если изменить параметр ol из запроса на «17track.net» (вместо «www.17track.net»), почему-то приходит ошибка по поводу хеша. Странные они, эти китайцы.
Оказалось, при генерации хеша еще и домен используется.

UPD2:
У меня сломался скрипт, потому что наша (российская) почта вдруг стала выдавать результаты на русском (недавно только на английском писала, EMS пишет статус по-русски (в результате не влазит в одно сообщение). Теперь идет транслитерация при помощи Google Translate (опять нелегально пользуем ресурсы)

UPD3:
Теперь у нас есть страничка генерации готового кода для вставки в скрипт. Все благодарности z0rg.

UPD4:
Генерация хеша производится скриптом

UPD5:
Если статус латиницей, Google Translate отдавал пустую строку с транслитерацией. fix.

UPD6:
Если трек-код не существует или еще не зарегистрирован, скрипт падал с ошибкой и сообщения не приходило. fix.
Спасибо за сообщение об ошибке -=INFINITY=- с 4pda.ru

UPD7:
Более изящная проверка кода на существование, проверка на новизну статуса по его тексту (иногда дата не отдается, спасибо Dudka), исправление проблем с транслитерацией (при наличии в тексте статуса нескольких предложений получалось забирать только первое, спасибо почте Беларуси и kakawajazz).

UPD8:
Версия для оповещения на E-Mail (включая email@sms-гейты)

UPD9:
Починил скрипт для работы с обновленным 17track, спасибо rocket за указание.
bakatrouble @bakatrouble
карма
15,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Спецпроект

Самое читаемое Разработка

Комментарии (89)

  • +1
    Хороший способ быть в курсе происходящего, вы молодец.
    И спасибо за оба ресурса. Они однозначно пригодятся не только мне.
    • +1
      За ресурсы нужно благодарить не меня, а корпорацию Google и некое ООО «Вектра».
      Да и делалось все, включая статью, исключительно ради себя.
      • 0
        Спасибо за статью. Я тоже just for fun сделал в конце прошлого года на своем сервере трекер посылок Укрпочты (Украина), так как много покупаю из-за границы (Китай и т.п.) и продаю на аукционе Aukro.ua. Попробую прикрутить ваши наработки + предложения в комментариях к своему трекингу. Только у меня немного другой способ оповещения — по email. Так, думаю, проще — пришел домой, посмотрел, что нового, или в мобилке настроить клиента при желании.

        Из проблем, с которыми столкнулся при написании, могу отметить следующие:
        1. Много времени ушло на опознание статусов посылки (нужно много посылок для тестирования).
        2. Попал на изменение адреса странички и технологии работы официального трекинга Укрпочты. В «новом» трекинге не написаны названия многих почтовых отделений, поэтому параллельно пользуюсь «старым», пока он жив.
        3. Абсолютный игнор писем с проблемами и предложениями Укрпочтой.

        Что получил в итоге (в построении сайтов «с нуля» был не силен, использовал до этого Drupal):
        1. Немного подучил PHP для быдло-кодинга ))). До этого использовал в основном готовые тексты скриптов с внесением небольшых изменений
        2. Познакомился с шаблонизатором Smarty
        3. Познакомился с Bootstrap
        4. Познакомился с многими людьми в соцсетях, получал обратную связь
        5. Около десяти новых посылок для отслеживания в день добавляются мной и знакомыми

        Адрес сайта приводить не буду, так как там присутствует гугло-реклама (сервер и домен нужно на что-то содержать) и хабрапользователи могут счесть за рекламу )) Да и сервер выдержит ли )). Если есть желание посмотреть, пишите в личку.
        • 0
          Лично для меня этот рассказ интереса не представляет, но можете оформить свою «историю успеха» как пост, кое-кто точно оценит.
  • 0
    Дело хорошее, но я как-то раз нашел ресурс post-tracker.ru и до сих пор пользуюсь.
    • 0
      Проверил только что: код, за которым слежу в данный момент не находит: «В почтовых системах нет данных об этом трек-коде», да мой вариант бесплатен. Да и в любом случае, удовлетворение какое-то, что ли, от проделанной работы. Самодельным пользоваться приятней.
    • 0
      Там нет чешской почты, что для меня крайне критично (живу в Чехии). Отправлял им данные для добавления данной почты — пока молчат.
      • 0
        С моим, судя по всему, аналогично: 17track утверждает, что данных с нашей стороны (России) нет, выдает то, что сообщает японская сторона, а с EMS японским post-tracker не дружит.
        • 0
          Я только что попробовал 17track — работает отлично с чешской почтой.
          • 0
            Этот трекер я узнал из оповещения об отправке посылки одним китайским интернет-магазином, который вряд ли будет делить пользователей по странам и использовать разные шаблоны. Не думал, что он сможет пригодиться когда-нибудь таким образом.
  • 0
    Если у вас андроид с постоянным подключением к интернет, то рекомендую Trackchecker
    • 0
      Аппарат с Android и постоянно включенная передача данных — вещи, которые я совмещать не имею возможности. Но приложение не находил, возможно, им и стал бы пользоваться, не найдя других вариантов.
    • 0
      Да, приложение отличное, но китайские треки видит только когда они приходят в мою страну.
      • 0
        Отлично видит Китайские треки. Может неправильно настраиваете? Для того чтобы видеть треки в пути по Китаю, попробуйте добавить для трека почтовый сервис «SAO (cn)»
    • 0
      Ему бы ещё синхронизацию треков между устройствами.
      Использую эту и RPTracker (последний умеет треки хранить в гугл-аккаунте)
  • 0
    Осталось получить настоящий API доступ на 17track и можно делать сервис уведомлений по SMS, по посылкам (шлюз имеется с копеечным тарифом).
    • 0
      API (по крайней мере алгоритмы генерации хеша) выдернуть легко, я пытался, проблема в том, что Google Apps Script отказался переваривать вырванный JS, хотя в браузере (вставлял на страницу хабра) он отрабатывал нормально. Сейчас выдерну еще раз, скину на pastebin.
      • 0
        pastebin.com/nAknzDgg
        Такие дела. А можно не париться и подключать 17track.net/scripts/hs.js (похоже, он нужен), тем более что так есть некоторая гарантия, что ничего не сломается при смене алгоритма генерации хеша.
        • 0
          странное у них хеширование, да еще и на клиентской стороне
          • 0
            Иначе как бы хеш можно было получить просто функцией на JS в браузере? Еще, если вы заметили, в адресе запроса JSON есть параметр lo=www.17track.net , который по идее заполняется из домена страницы (не помню имя самой переменной). Если убрать этот параметр, придет JSON с ошибкой, вроде что-то типа «NotAllowed». Однако если подставить нужный вариант, никаких проверок даже по реферреру не будет произведено.
            Восток — дело тонкое. Нам понять этого не дано.
            • 0
              Можно получать хеш Ajax'ом, если это вообще необходимо делать на JS стороне или заранее генерировать на серверной стороне в шаблоне и вбивать в переменную в коде JS. Я если честно не особо улавливаю суть, почему это дело переложили на клиентскую сторону.
              • 0
                Ajax'ом они запрашивают результаты трекинга, используя хеш, сгенерированный у клиента. Выглядит как мелочь для отпугивания не шибко настоичивых повадившихся использовать их ресурсы без просмотра рекламы (там ведь реклама, да, за теми анимациями загрузки?). А сильно настойчивым мешать бессмысленно.
                • 0
                  Я не вижу рекламу, у меня блочит Outpost скорее всего. Странные они, китайцы)
                  • 0
                    А у меня AdBlock и hosts на уровне смарта, работающего хотспотом. Потому и спрашиваю.
              • 0
                маньяки сделали это, чтобы запутать «роботов»…
                Я одно время разбирался, как у них (17трек) устроено получение «хэша» по треку.
                Они там прикрутили 3des шифрование на клиентской стороне (если ничего не путаю). обфусцировали конечно «слегка» код, занимающийся шифрованием…
                К сожалению повторить процесс получения хэша на делфе мне за разумное время не удалось, и я забросил это занятие.
                • 0
                  Если обфускация — это «упаковка», то она хорошо вскрывается Dragonfly'ем Opera'ы. Смотрите ссылку на pastebin выше. Как домой попаду, надо будет переписать на чем другом попробовать.
                  • 0
                    Смотрел. Там все еще немного обфусцированный (изменены имена функций и переменных) алгоритм шифрования (3des) из какого-то попадающегося в инете js-модуля. Который мне тоже попадался, когда я с этим 17треком разбирался.
                    В итоге плюнул, написал им, что мол нет ли у них апи и как они с почтой Китая работают…
                    Ответили, что апи нет, может будет когда-нибудь, и что с почтой китая у них договор есть…
                    • 0
                      Если переписывать, например, на PHP, надо всего лишь подправить мелочи синтаксиса на местные и подобрать альтернативы стандартным функциям. У Си (с которым я, к сожалению, плохо дружу) тоже синтаксис похож.
                    • 0
                      А если делать сервис (не понимаю, что мешает для себя один раз сгенерить хеш на странице для каждого номера и сидеть, ждать вместо того, чтобы постоянно смотреть на страницу трекинга), то подключить скрипт прямо с их сайта и не надо изобретать ничего.
                • 0
                  Хочу обрадовать вас. Разобрался с шифрованием этим. Его реализация на PHP:
                      $track = "EM*********JP";
                      $array = array($track, 0, "www.17track.net");
                      $string = join($array, "{EDFCE98B-1CE6-4D87-8C4A-870D140B62BA}");
                      echo hash('md5', $string);
                  

                  От правильных ботов (ну кто, кроме меня, бота на JS будет писать?) не спасет, а себе на JS задачу усложнили.
  • –2
    А у меня не заработало( не пойму в чем может быть дело, написал автору в личку, прошу помочь.
    • 0
      Ответил. Внимательней надо быть.
      • 0
        спасибо!
  • 0
    gdeposylka.ru/
    Вот этот сервис довольно универсальный кстати. Кормится практически любыми кодами.
    • 0
      На 17track отдается JSON, который куда проще парсить, чем HTML. Или в качестве замены моему велосипеду с СМС его предлагаете?
      • 0
        Да, я именно как полную замену, в т.ч. смс. просто всегда удивляли люди, которые тратят кучу времени и делают велосипед не погуглив сначало.

        Нет, конечно если все задумано в целях самообразования то вопросов тут нет :)
        • 0
          в целях смообразования очень даже неплохо.
          а гдепосылка денег за смс уведомление требует, или я ошибаюсь?
          • 0
            да, 2 рубля за 1 сообщение.
            • 0
              Ничего себе, я отправляю в 30 раз дешевле, можно и еще дешевле. Только вот не знаю какой сервис пока замутить, если только предлагать api для использования рассылки.
              • 0
                ну они скорее не за смс берут, а вообще за сервис… но 2р за сообщение, согласен, многовато…
              • 0
                В сторону посмотрите: bytehand.com
                0,40 р за смс — начальный, после внесения 10К — 0,20 р. за смс
                • 0
                  Зачем мне в его сторону смотреть, если дешевле этого сервиса отправляю?
                  • 0
                    API и упрощение рассылок. Или вы не этого хотели?
                    • 0
                      Наверное, я не так выразился, у меня есть возможность отправлять смски по smpp протоколу, на основе этого я мог бы сделать API если это кому-то интересно. Мне ни к чему чужое API и шлюз для рассылок.
            • +1
              А тут бесплатно. И таки да, самообразование тоже имеет место.
  • 0
    кстати, альтернатива 17track может послужить sao.cn.
    там так же ajax запрос шлется, получается json в ответе. И нет нужды со всякими хэшами морочиться.
    пример get запроса:
    sao.cn/track?id=[TRACKNO]&timeout=180&mailType=null&lang=EN&srcId=null&srcMode=null&dstId=null&dstMode=null&input=null
    где [TRACKNO] = проверяемый трек-номер. Возможно можно обойтись и без других параметров.
    сервис, конечно, не идеальный, но так же берет инфу с почты китая без капчи…
    • 0
      Опять же, мой трек-номер пролетел в режиме авто (EMS Japan). При ручном выборе страны отправления находит, но опять же лишняя возня.
  • 0
    А еще смс-ки можно отправлять средствами календаря Google (описание тут).
    • 0
      Лишние костыли, которых здесь и так уже многовато.
    • 0
      И из того поста я как раз и подчерпнул идею.
  • 0
    у меня почемуто приходит [Opject] [Opject]

    А при запуске ошибка:

    TypeError: Не удается прочитать свойство «1» объекта null. (строка 18, файл Код)

    18: if(UserProperties.getProperty(num[i][0]) != result[1]){

    Проверил хеши по два раза, посылка у 17track отслеживается
    • 0
      Сдается мне, вы что-то напутали с объявлением объекта с трек-кодами. Покажите ваш код с объектом num (трек-коды можете заменить чем-нибудь).
      • 0
        var apiID = «99af**************9bb8»;
        var phone = «89***********01»;
        var num = [
        [«RB**********CN», «21************************fe6»],
        [«RT**********HK», «e9************************3cd»]
        ];

        function sendSMS(text){
        UrlFetchApp.fetch(«sms.ru/sms/send?api_id=»+apiID+"&to="+phone+"&text="+encodeURI(text));
        }

        function checkStatus(){

        for(i=0; i
        • 0
          Странно обрезает, выложил на pastebin.com/UrXhieM6
          • 0
            Единственная идея — несоответствие хеша и кода (JSON приходит без соответствующего регулярке текста). Либо посылка пока нигде не отмечена. Попробуйте запросить через браузер JSON и покажите и их ( s1.17track.net/Rest/HandlerTrackPost.ashx?lo=www.17track.net&num=%TRACKNUM%&hs=%HASH% ).
            А вообще, по хорошему и ошибки ловить надо.
        • 0
          телефон без восьмерки, 10 цифр.
          • 0
            У меня стоит с семеркой (без плюса).
    • 0
      Ох, у меня тоже скрипт сломался. Боюсь, китайцы приняли хабраэффект за DDoS и забанили Гугл. Придется к другим сервисам присасываться.
      • 0
        Ан нет, просто ошибками кидался, сейчас все хорошо. Сейчас попытаюсь ловлю ошибок прикрутить.
  • 0
    UPD (подробности внизу поста)
  • 0
    UPD2 (транслитерация статуса, подробней внизу поста)
    Пользуясь случаем, передаю привет нашей почте, EMS-посылка за семь дней добралась из Японии до таможни в Москве.
  • 0
    UPD3 (Благодаря z0rg теперь получать хеши проще).
    А я пойду все-таки спать.
  • 0
    UPD4 (Хеш теперь генерируется скриптом)
  • 0
    UPD5
  • 0
    UPD6 (Исправление падения скрипта при несуществующем коде)
  • +1
    У меня в дате последнего статуса 17track.net возвращал null, из-за этого были проблемы.
    Поправил так
     if(success){
          var lasttdate=((result["dat"]["z"]["a"]==null)?"null":result["dat"]["z"]["a"]);
          if(UserProperties.getProperty(num[i][0]) != lasttdate){
            translit = UrlFetchApp.fetch("http://translate.google.com/translate_a/t?client=t&q="+encodeURI(result["dat"]["z"]["b"]));
            translitobj = Utilities.jsonParse(translit.getContentText());
            sendstring += translitobj[0][0][3] ? translitobj[0][0][3] : result["dat"]["z"]["b"];
            sendSMS(sendstring);        
            UserProperties.setProperty(num[i][0], lasttdate);
            success = false;
          }
    
    • 0
      Чтоб не городить лишнего кода, сделал проверку по тексту статуса.
  • 0
    UPD7 Более изящная проверка кода на существование, проверка на новизну статуса по его тексту (иногда дата не отдается, спасибо Dudka), исправление проблем с транслитерацией (при наличии в тексте статуса нескольких предложений получалось забирать только первое, спасибо почте Беларуси и kakawajazz).
  • 0
    UPD8 Версия для оповещения на E-Mail (включая email2sms-гейты)
    • 0
      Походу 17track поменял механизм выдачи — не отдает данные по всем трекам
      • 0
        ({"ret":1,"msg":"Ok","dat":{"c":"RB335828484HK","d":8011,"e":18031,"f":1,"g":1,"h":1,"i":-1,"j":998,"k":4899,"l":9,"m":29,"v":"9999-12-31T00:00:00","w":"9999-12-31T00:00:00","x":[{"a":"22-Aug-2013","b":"The item (RB335828484HK) was in transit within its destination country on 22-Aug-2013."}],"y":[{"a":"22 August 2013 06:08","b":"Обработка, 443962, САМАРА МСЦ УОПО, Прибыло в сортировочный центр"},{"a":"22 August 2013 03:26","b":"Обработка, 443982, САМАРА PI-2, Покинуло место международного обмена"},{"a":"21 August 2013 11:19","b":"Таможенное оформление завершено, 443982, САМАРА PI-2, Выпущено таможней"},{"a":"21 August 2013 09:11","b":"Передано таможне, 443982, САМАРА PI-2"},{"a":"20 August 2013 21:59","b":"Импорт, 443982, САМАРА PI-2, АФИПСИП, ТАХТАМУКАЙСКИЙ РАЙОН, АДЫГЕЯ РЕСПУБЛИКА"}],"z":{"a":"22 August 2013 06:08","b":"Обработка, 443962, САМАРА МСЦ УОПО, Прибыло в сортировочный центр"}}})
        Что не отдает?
        • 0
          У меня почему то так
          • 0
            Все ок, увидел у себя проблему
  • 0
    & у вас повылазили вместо амперсандов в ссылке
  • 0
    Код RB631253292CN — Please leave comment on HabraHabr.
    Оставляю.
    • 0
      Если ошибка — «abN», то я сам ничего не могу с этим сделать.
      • 0
        Победил так:
        ...
        if(UserProperties.getProperty("'"+num[i][0]+"'") != result[«dat»][«z»][«b»]){
        ...
        UserProperties.setProperty("'"+num[i][0]+"'", result[«dat»][«z»][«b»]);
        ...
        • 0
          Хм… От этого abN пропасть не должна — она на стороне сервера. Причина явно какая-то другая. Причём в последнее время эта ошибка приходит только от трек-кода, посылка с которым с конца августа уже получена.
          • 0
            Да, верно. Но как работает без кавычек — не представляю.
            Без кавычек у меня вообще статус не приходил. С ними — пришел, но ошибки abN все равно периодически прилетают.
            Поспешил, буду дальше смотреть.
            • 0
              Индекс элемента в массиве в моем случае — RB631253292CN, а в вашем — 'RB631253292CN'. Чему тут не работать, не представляю.
              • 0
                Мне это понятно, но факт остается фактом — без кавычек у меня не работал.
  • 0
    В общем я остановился на варианте с фильтрацией abN — сейчас сообщения приходят только по делу, при изменении статуса.

    Приложу весь код
    var user = ["...", "..."];
    
    var num = [
      ["...", "..."]
    ];
    
    var errors = {
      "hsErr": "Wrong hash",
      "unAllow": "You've changed parameter \"lo\" in query URL. Set it to \"www.17track.net\"",
      "hsNon": "There's no hash"
    }
    var success = false;
    
    function sendSMS(text){
      UrlFetchApp.fetch("http://sms.ru/sms/send?api_id="+user[0]+"&to="+user[1]+"&text="+encodeURI(text));
    }
    
    function digest2str(digest){
      var str = '';
      var i = 0;
      for (i=0; i<digest.length; i++) {
        byte = digest[i];
        if (byte < 0)
          byte += 256;
        byteStr = byte.toString(16);
        // Ensure we have 2 chars in our byte, pad with 0
        if (byteStr.length == 1) byteStr = '0'+byteStr;
        str += byteStr;
      }   
      return str;
    }
    
    function checkStatus(){
      var i = 0;
      for(i=0; i<num.length; i++){
        hashstr = num[i][0]+"{EDFCE98B-1CE6-4D87-8C4A-870D140B62BA}0{EDFCE98B-1CE6-4D87-8C4A-870D140B62BA}www.17track.net";
        dig = Utilities.computeDigest(Utilities.DigestAlgorithm.MD5, hashstr);
        hs = digest2str(dig);
        var response = UrlFetchApp.fetch("http://s1.17track.net/Rest/HandlerTrackPost.ashx?lo=www.17track.net&num="+num[i][0]+"&hs="+hs);    
        UserProperties.setProperty("q", response.getContentText());
        var result = Utilities.jsonParse(response.getContentText().replace(/^\((.*)\)$/, "$1"));
        var sendstring = num[i][1]+": ";
        if(result["msg"]!="abN"){
          if(result["ret"] == 1){
            if(result["dat"]["f"] == "0"){
              sendstring += "Track code not found";
            }else{
              success = true;
            }
          }else{
            sendstring += errors[result["msg"]] ? errors[result["msg"]] : "Please, leave comment on habrahabr, error message: "+result["msg"];
          }
        
          if(success){        
            if(result["dat"]["z"]!=null){
              if(UserProperties.getProperty("'"+num[i][0]+"'") != result["dat"]["z"]["b"]){
                //if(true){
                translit = UrlFetchApp.fetch("http://translate.google.com/translate_a/t?client=t&q="+encodeURI(result["dat"]["z"]["b"]));
                translitobj = Utilities.jsonParse(translit.getContentText());
                if(translitobj[0][0][3]){
                  for(z in translitobj[0]){
                    sendstring += translitobj[0][z][3]+" ";
                  }
                }else{
                  sendstring += result["dat"]["z"]["b"];
                }
                sendSMS(sendstring);
                UserProperties.setProperty("'"+num[i][0]+"'", result["dat"]["z"]["b"]);
                success = false;
              }
            }
          }else{
            sendSMS(sendstring);
          }
        }
      }
    }
    

  • 0
    Проблемы при первом запуске
    1) пришло всего 2 уведомления из 6 посылок…
    2) если в 17track destination посылки стоит unknown, то статус посылки приходит неактуальный. На сайте 17track можно вручную выставить destination. Можно ли как-то в вашем скрипте принудительно указывать страну destination?
    • 0
      В техподдержке sms.ru ответили, что sms бесплатно отправляется самому себе если оно укладывается в 160 символов (без склейки). Как-то странно, что никто в комментах выше не отписался о таком нюансе, мешающем полноценно использовать сервис отслеживания посылок. У меня в посылках 4 из 6 статус длиннее 160 символов в транслите.
      • 0
        Насчет кол-ва символов в посте приведен способ с email2sms
        По поводу страны:
        Шаблон для кода будет следующий:
        ["%TRACKCODE%", "%NAME%", "%COUNTRYID%"]

        где %COUNTRYID% — идентификатор страны у 17track, список здесь: pastebin.com/mrJxgvgt
        Плюс строку
        var response = UrlFetchApp.fetch("http://s1.17track.net/Rest/HandlerTrackPost.ashx?lo=www.17track.net&num="+num[i][0]+"&hs="+hs);

        заменить на
        var response = UrlFetchApp.fetch("http://s1.17track.net/Rest/HandlerTrackPost.ashx?lo=www.17track.net&num="+num[i][0]+"&hs="+hs+"&pt="+num[i][2]);
  • 0
    Спустя неделю работы сервиса напоролся на ошибку «abN». Возвращает такое для всех трэков. Причем, если реквестить s1.17track.net/Rest/HandlerTrackPost.ashx через другой IP, то статусы возвращаются нормально. Походу, у них настроен автоматический бан по IP. Нужно прикручивать динамический прокси.
  • 0
    Походу сломался сервис 17track.net — там у них на сайте недавно случился мощный редизайн. Ждём новых поделок API.
    • 0
      Поправил, пробуйте. Тестировать не на чем.
  • 0
    Поправил под себя, у меня версия из топика не работала. Кому интересно проверяйте.
    Нужен еще апи ключ из яндекс транслейт

    pastie.org/9795905

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