В последнее время я стал делать много покупок в интернет-магазинах, и нередко ловлю себя на том, что очень часто проверяю статус своих посылок (с нашей почтой не беспокоиться не получится).
Поиск готовых решений приводил только к платным сервисам. В результате было принято решение сообразить что-нибудь свое.
Под катом список используемых сервисов и подробная инструкция.
Следующий шаг поисков был посвящен сервисам, предоставляющим возможность периодического выполнения различных скриптов за неимением (ах, какая досада) личного сервера. Выбор пал на Google Apps Script. В качестве ЯП используется модификация хорошо знакомого мне Javascript.
В качестве SMS-гейта был выбран SMS.ru, предоставляющий возможность отправки неограниченного количества бесплатных SMS стандартной длины (180 символов латиницы, 60 юникода) на личный номер телефона.
Функцию трекинга было решено позаимствовать у [не знаю, насколько] универсального китайского сервиса 17track.
Если у вашего оператора есть email2sms-гейт, то все упоминания SMS.ru можно пропускать.
До того, как приступить к написанию… кода, нам нужны:
Подробно расписывать процесс регистрации, надеюсь, не нужно.
API ID для SMS.ru можно получить здесь: online.sms.ru/?panel=settings&subpanel=api
Для создания скрипта в Google Apps Script требуется, как ни странно, пройти на сайт этого сервиса.
Там нас встретит следующее окно (если оно не было отключено ранее):
Нам нужен «Пустой проект».
Хеш для 17track не придется получать, генерация теперь производится силами Google Apps Script. Готовый код для вставки в скрипт можно получить здесь.
Все нужные ингредиенты получены, можно приступать к коду.
Также можно не возиться с sms.ru, если у вашего оператора есть email2sms-гейт. Например, инструкции для Мегафон Удмуртия. Если есть, обнаружить на сайте оператора можно поиском по слову «e-mail». Убрана транслитерация (если у кого-то гейт не умеет клеить сообщения, сообщите, сделаю версию с транслитерацией). Название кода складывается в тему сообщения.
Оговорюсь только о том, что в качестве флага, было оповещение по этому статусу или нет, используется дата последнего статуса, которая сохраняется в User Properties и сравнивается каждый раз.
В код остается подставить API ID, номер телефона и пары трекинг-номер/хеш. Теперь нужно настроить периодическое выполнение этого скрипта. Для этого идем в «Ресурсы->Триггеры текущего проекта», нажимаем «Добавить триггер» и настраиваем по образу и подобию (промежуток можно выбрать свой):
Результатом будут такие сообщения на мобильный телефон при обнаружении изменений в статусе:
Вопросы и предложения с альтернативами, исправлениями и оптимизациями принимаются.
P.S.: благодарю неизвестного (или это я просто не нашел?) хабраюзера за предоставленный инвайт.
UPD:
Если изменить параметр 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 за указание.
Поиск готовых решений приводил только к платным сервисам. В результате было принято решение сообразить что-нибудь свое.
Под катом список используемых сервисов и подробная инструкция.
Выбор вспомогательных сервисов
Следующий шаг поисков был посвящен сервисам, предоставляющим возможность периодического выполнения различных скриптов за неимением (ах, какая досада) личного сервера. Выбор пал на 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:
- Функциональные изменения: добавлено присвоение своих имен посылкам (отображаются вместо трек-кодов) и отлов ошибок (известны только две ошибки, если ошибка неизвестна, ее код придет в SMS, сообщите его здесь, мне в личку или через skype/twitter, ID в профиле).
- «Внутренние» изменения: обработка ответа сервиса сделана как нормальный JSON, а не костыльными RegExp.
Оказалось, при генерации хеша еще и домен используется.
UPD2:
У меня сломался скрипт, потому что
UPD3:
Теперь у нас есть страничка генерации готового кода для вставки в скрипт. Все благодарности z0rg.
UPD4:
Генерация хеша производится скриптом
UPD5:
Если статус латиницей, Google Translate отдавал пустую строку с транслитерацией. fix.
UPD6:
Если трек-код не существует или еще не зарегистрирован, скрипт падал с ошибкой и сообщения не приходило. fix.
Спасибо за сообщение об ошибке -=INFINITY=- с 4pda.ru
UPD7:
Более изящная проверка кода на существование, проверка на новизну статуса по его тексту (иногда дата не отдается, спасибо Dudka), исправление проблем с транслитерацией (при наличии в тексте статуса нескольких предложений получалось забирать только первое, спасибо почте Беларуси и kakawajazz).
UPD8:
Версия для оповещения на E-Mail (включая email@sms-гейты)
UPD9:
Починил скрипт для работы с обновленным 17track, спасибо rocket за указание.