В северном полушарии нынче зима, а это значит что пора на лыжи! Мы с друзьями поддались этому течению и приступили к подготовке нашего совместного зимнего отдыха. Детали всего процесса планирования раскрывать не буду, скажу лишь только, что мне выпала ответственная роль сбора магазинных чеков наших совместных трат.
Так как песочницей для наших планов выступили Google Docs, а конкретнее Таблицы, то мне захотелось разместить фото всех чеков на отдельном листе. Первая попытка вставить картинку в таблицу через привычный пункт меню «Вставка -> Изображение» привела к тому что чек оказался поверх ячеек таблицы и моим друзьям IT-шникам такое оформление точно бы не приглянулось:
«Должен же быть способ вставить картинку в ячейку...», — подумал я. Google нашел этот способ с первого запроса: функция IMAGE(URL), как значение ячейки. Ну что ж, дело сделано:
Можно дальше идти смотреть лыжные уроки. Хотя…
...Google моментально среагировал на мой запрос «Online FineReader API» и выдал несколько статей с хабра о ABBYY Cloud OCR SDK. Быстрый просмотр доступных методов платформы подтвердил мои надежды и желанный ocrsdk.com/documentation/apireference/processReceipt был найден. Для осуществления задуманного недоставало понимания как вставить в ячейку таблицы пользовательскую функцию, которая будет вызывать методы обработки чека. Но и тут поиск меня не подвел и был найден Редактор скриптов Google.
Теперь дело за малым. Первым делом необходимо создать приложение ocrsdk. Делается это в процессе регистрации нового пользователя, так что с этим проблем не возникло. Письмо с паролем приложения, который необходим для аутентификации запросов, было отправлено сразу после завершения регистрации.
Далее в нашей Таблице выбираем пункт меню «Инструменты -> Редактор скриптов» и создаем функцию processReceipt(imageUrl):
function processReceipt(imageUrl) {
// Загружаем картинку чека
var image = UrlFetchApp.fetch(imageUrl);
// Формируем заголовок авторизации, который состоит из имени приложения и пароля
var pass = "GoogleDriveTest" + ":" + "********************"
// Формируем POST запрос на обработку чека
var url = "http://cloud.ocrsdk.com/processReceipt";
var headers = {
"Content-Type":"image/png",
"Authorization" : "Basic " + Utilities.base64Encode(pass)
};
var options = {
"method":"POST",
"headers": headers,
"payload" : image.getContent()
};
var response = UrlFetchApp.fetch(url, options);
// Парсим XML ответа и находим в нем ID задачи по обработке нашего чека (больше деталей тут http://ocrsdk.com/documentation/apireference/processReceipt/)
var document = XmlService.parse(response.getContentText())
var id = document.getRootElement().getChildren()[0].getAttribute('id').getValue()
var resultUrl
// Ждем успешного завершения задачи и получаем url по которому можно получить результат обработки чека
do {
Utilities.sleep(3000)
url = "http://cloud.ocrsdk.com/getTaskStatus" + "?taskId=" + id;
headers = {
"Authorization" : "Basic " + Utilities.base64Encode(pass)
};
options = {
"method":"GET",
"headers": headers,
};
response = UrlFetchApp.fetch(url, options);
document = XmlService.parse(response.getContentText());
if (document.getRootElement().getChildren()[0].getAttribute('status').getValue() == 'Completed') {
resultUrl = document.getRootElement().getChildren()[0].getAttribute('resultUrl').getValue()
break
}
} while(true)
// Получаем результат обработки чека
options = {
"method":"GET",
};
response = UrlFetchApp.fetch(resultUrl, options);
document = XmlService.parse(response.getContentText());
// document содаржит XML нашего чека. Из-за моральных принципов реализацию функции findTotalPriceInReceiptXML я скрыл :)
result = findTotalPriceInReceiptXML(document)
return result
}
Всё сохраняем и идем обратно в таблицу. Чтоб сие чудо заработало, пришлось вынести в отдельную ячейку таблицы URL картинки чека. Наша функция теперь доступна как =processReceipt(ячейка с URL).
Всем хорошей зимней погоды и удачи на лыжных склонах!
Автор: vlad_br