Pull to refresh

Comments 89

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

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

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

Адрес сайта приводить не буду, так как там присутствует гугло-реклама (сервер и домен нужно на что-то содержать) и хабрапользователи могут счесть за рекламу )) Да и сервер выдержит ли )). Если есть желание посмотреть, пишите в личку.
Лично для меня этот рассказ интереса не представляет, но можете оформить свою «историю успеха» как пост, кое-кто точно оценит.
Проверил только что: код, за которым слежу в данный момент не находит: «В почтовых системах нет данных об этом трек-коде», да мой вариант бесплатен. Да и в любом случае, удовлетворение какое-то, что ли, от проделанной работы. Самодельным пользоваться приятней.
Там нет чешской почты, что для меня крайне критично (живу в Чехии). Отправлял им данные для добавления данной почты — пока молчат.
С моим, судя по всему, аналогично: 17track утверждает, что данных с нашей стороны (России) нет, выдает то, что сообщает японская сторона, а с EMS японским post-tracker не дружит.
Я только что попробовал 17track — работает отлично с чешской почтой.
Этот трекер я узнал из оповещения об отправке посылки одним китайским интернет-магазином, который вряд ли будет делить пользователей по странам и использовать разные шаблоны. Не думал, что он сможет пригодиться когда-нибудь таким образом.
Аппарат с Android и постоянно включенная передача данных — вещи, которые я совмещать не имею возможности. Но приложение не находил, возможно, им и стал бы пользоваться, не найдя других вариантов.
Да, приложение отличное, но китайские треки видит только когда они приходят в мою страну.
Отлично видит Китайские треки. Может неправильно настраиваете? Для того чтобы видеть треки в пути по Китаю, попробуйте добавить для трека почтовый сервис «SAO (cn)»
Ему бы ещё синхронизацию треков между устройствами.
Использую эту и RPTracker (последний умеет треки хранить в гугл-аккаунте)
Осталось получить настоящий API доступ на 17track и можно делать сервис уведомлений по SMS, по посылкам (шлюз имеется с копеечным тарифом).
API (по крайней мере алгоритмы генерации хеша) выдернуть легко, я пытался, проблема в том, что Google Apps Script отказался переваривать вырванный JS, хотя в браузере (вставлял на страницу хабра) он отрабатывал нормально. Сейчас выдерну еще раз, скину на pastebin.
странное у них хеширование, да еще и на клиентской стороне
Иначе как бы хеш можно было получить просто функцией на JS в браузере? Еще, если вы заметили, в адресе запроса JSON есть параметр lo=www.17track.net , который по идее заполняется из домена страницы (не помню имя самой переменной). Если убрать этот параметр, придет JSON с ошибкой, вроде что-то типа «NotAllowed». Однако если подставить нужный вариант, никаких проверок даже по реферреру не будет произведено.
Восток — дело тонкое. Нам понять этого не дано.
Можно получать хеш Ajax'ом, если это вообще необходимо делать на JS стороне или заранее генерировать на серверной стороне в шаблоне и вбивать в переменную в коде JS. Я если честно не особо улавливаю суть, почему это дело переложили на клиентскую сторону.
Ajax'ом они запрашивают результаты трекинга, используя хеш, сгенерированный у клиента. Выглядит как мелочь для отпугивания не шибко настоичивых повадившихся использовать их ресурсы без просмотра рекламы (там ведь реклама, да, за теми анимациями загрузки?). А сильно настойчивым мешать бессмысленно.
А у меня AdBlock и hosts на уровне смарта, работающего хотспотом. Потому и спрашиваю.
маньяки сделали это, чтобы запутать «роботов»…
Я одно время разбирался, как у них (17трек) устроено получение «хэша» по треку.
Они там прикрутили 3des шифрование на клиентской стороне (если ничего не путаю). обфусцировали конечно «слегка» код, занимающийся шифрованием…
К сожалению повторить процесс получения хэша на делфе мне за разумное время не удалось, и я забросил это занятие.
Если обфускация — это «упаковка», то она хорошо вскрывается Dragonfly'ем Opera'ы. Смотрите ссылку на pastebin выше. Как домой попаду, надо будет переписать на чем другом попробовать.
Смотрел. Там все еще немного обфусцированный (изменены имена функций и переменных) алгоритм шифрования (3des) из какого-то попадающегося в инете js-модуля. Который мне тоже попадался, когда я с этим 17треком разбирался.
В итоге плюнул, написал им, что мол нет ли у них апи и как они с почтой Китая работают…
Ответили, что апи нет, может будет когда-нибудь, и что с почтой китая у них договор есть…
Если переписывать, например, на PHP, надо всего лишь подправить мелочи синтаксиса на местные и подобрать альтернативы стандартным функциям. У Си (с которым я, к сожалению, плохо дружу) тоже синтаксис похож.
А если делать сервис (не понимаю, что мешает для себя один раз сгенерить хеш на странице для каждого номера и сидеть, ждать вместо того, чтобы постоянно смотреть на страницу трекинга), то подключить скрипт прямо с их сайта и не надо изобретать ничего.
Хочу обрадовать вас. Разобрался с шифрованием этим. Его реализация на 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 задачу усложнили.
А у меня не заработало( не пойму в чем может быть дело, написал автору в личку, прошу помочь.
gdeposylka.ru/
Вот этот сервис довольно универсальный кстати. Кормится практически любыми кодами.
На 17track отдается JSON, который куда проще парсить, чем HTML. Или в качестве замены моему велосипеду с СМС его предлагаете?
Да, я именно как полную замену, в т.ч. смс. просто всегда удивляли люди, которые тратят кучу времени и делают велосипед не погуглив сначало.

Нет, конечно если все задумано в целях самообразования то вопросов тут нет :)
в целях смообразования очень даже неплохо.
а гдепосылка денег за смс уведомление требует, или я ошибаюсь?
Ничего себе, я отправляю в 30 раз дешевле, можно и еще дешевле. Только вот не знаю какой сервис пока замутить, если только предлагать api для использования рассылки.
ну они скорее не за смс берут, а вообще за сервис… но 2р за сообщение, согласен, многовато…
В сторону посмотрите: bytehand.com
0,40 р за смс — начальный, после внесения 10К — 0,20 р. за смс
Зачем мне в его сторону смотреть, если дешевле этого сервиса отправляю?
API и упрощение рассылок. Или вы не этого хотели?
Наверное, я не так выразился, у меня есть возможность отправлять смски по smpp протоколу, на основе этого я мог бы сделать API если это кому-то интересно. Мне ни к чему чужое API и шлюз для рассылок.
А тут бесплатно. И таки да, самообразование тоже имеет место.
кстати, альтернатива 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] = проверяемый трек-номер. Возможно можно обойтись и без других параметров.
сервис, конечно, не идеальный, но так же берет инфу с почты китая без капчи…
Опять же, мой трек-номер пролетел в режиме авто (EMS Japan). При ручном выборе страны отправления находит, но опять же лишняя возня.
А еще смс-ки можно отправлять средствами календаря Google (описание тут).
Лишние костыли, которых здесь и так уже многовато.
И из того поста я как раз и подчерпнул идею.
у меня почемуто приходит [Opject] [Opject]

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

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

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

Проверил хеши по два раза, посылка у 17track отслеживается
Сдается мне, вы что-то напутали с объявлением объекта с трек-кодами. Покажите ваш код с объектом num (трек-коды можете заменить чем-нибудь).
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
Единственная идея — несоответствие хеша и кода (JSON приходит без соответствующего регулярке текста). Либо посылка пока нигде не отмечена. Попробуйте запросить через браузер JSON и покажите и их ( s1.17track.net/Rest/HandlerTrackPost.ashx?lo=www.17track.net&num=%TRACKNUM%&hs=%HASH% ).
А вообще, по хорошему и ошибки ловить надо.
телефон без восьмерки, 10 цифр.
Ох, у меня тоже скрипт сломался. Боюсь, китайцы приняли хабраэффект за DDoS и забанили Гугл. Придется к другим сервисам присасываться.
Ан нет, просто ошибками кидался, сейчас все хорошо. Сейчас попытаюсь ловлю ошибок прикрутить.
UPD2 (транслитерация статуса, подробней внизу поста)
Пользуясь случаем, передаю привет нашей почте, EMS-посылка за семь дней добралась из Японии до таможни в Москве.
UPD3 (Благодаря z0rg теперь получать хеши проще).
А я пойду все-таки спать.
UPD6 (Исправление падения скрипта при несуществующем коде)
У меня в дате последнего статуса 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;
      }
Чтоб не городить лишнего кода, сделал проверку по тексту статуса.
UPD7 Более изящная проверка кода на существование, проверка на новизну статуса по его тексту (иногда дата не отдается, спасибо Dudka), исправление проблем с транслитерацией (при наличии в тексте статуса нескольких предложений получалось забирать только первое, спасибо почте Беларуси и kakawajazz).
({"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, САМАРА МСЦ УОПО, Прибыло в сортировочный центр"}}})
Что не отдает?
Все ок, увидел у себя проблему
Код RB631253292CN — Please leave comment on HabraHabr.
Оставляю.
Если ошибка — «abN», то я сам ничего не могу с этим сделать.
Победил так:
...
if(UserProperties.getProperty("'"+num[i][0]+"'") != result[«dat»][«z»][«b»]){
...
UserProperties.setProperty("'"+num[i][0]+"'", result[«dat»][«z»][«b»]);
...
Хм… От этого abN пропасть не должна — она на стороне сервера. Причина явно какая-то другая. Причём в последнее время эта ошибка приходит только от трек-кода, посылка с которым с конца августа уже получена.
Да, верно. Но как работает без кавычек — не представляю.
Без кавычек у меня вообще статус не приходил. С ними — пришел, но ошибки abN все равно периодически прилетают.
Поспешил, буду дальше смотреть.
Индекс элемента в массиве в моем случае — RB631253292CN, а в вашем — 'RB631253292CN'. Чему тут не работать, не представляю.
Мне это понятно, но факт остается фактом — без кавычек у меня не работал.
В общем я остановился на варианте с фильтрацией 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);
      }
    }
  }
}

Проблемы при первом запуске
1) пришло всего 2 уведомления из 6 посылок…
2) если в 17track destination посылки стоит unknown, то статус посылки приходит неактуальный. На сайте 17track можно вручную выставить destination. Можно ли как-то в вашем скрипте принудительно указывать страну destination?
В техподдержке sms.ru ответили, что sms бесплатно отправляется самому себе если оно укладывается в 160 символов (без склейки). Как-то странно, что никто в комментах выше не отписался о таком нюансе, мешающем полноценно использовать сервис отслеживания посылок. У меня в посылках 4 из 6 статус длиннее 160 символов в транслите.
Насчет кол-ва символов в посте приведен способ с 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]);
Спустя неделю работы сервиса напоролся на ошибку «abN». Возвращает такое для всех трэков. Причем, если реквестить s1.17track.net/Rest/HandlerTrackPost.ashx через другой IP, то статусы возвращаются нормально. Походу, у них настроен автоматический бан по IP. Нужно прикручивать динамический прокси.
Походу сломался сервис 17track.net — там у них на сайте недавно случился мощный редизайн. Ждём новых поделок API.
Поправил под себя, у меня версия из топика не работала. Кому интересно проверяйте.
Нужен еще апи ключ из яндекс транслейт

pastie.org/9795905

Sign up to leave a comment.

Articles