Цели, задачи, оправдания безумства.
Все началось с того, что кто-то из хабравчан в комментариях поведал о использовании Google Translate в роли синонимайзера. Он предложил переводить текст с одного языка на другой и обратно и обещал достаточно хороший процент отличий и сохранение смысла текста.
Вопросы, на которые я решил получить ответ «да»
- Можно ли создать Telegram бота в Google Script?
- Можно ли бесплатно использовать API Google Translate
без регистрации и SMS? - Можно ли сделать онлайн инструмент без использования хостинга?
Как все это работает
Сначала я создал бота и получил API ключ. Я не буду писать о том, как это сделать, эта информация много раз публиковалась на хабре и легко гуглится.
Очень быстро стало понятно, что я смогу отправить http запрос на сервер Telegram. Ни о каком web hook я не думал. Не исключено, что его можно использовать через google sites, но я вообще не проверял эту мысль.
Потом я создал табличный документ с двумя листами. На первом листе хранится параметр offset, необходимый для получения сообщений боту, которые еще не были получены. На том же листе на второй строчке записывается дата последнего обновления. На втором листе расположился лог входящих сообщений с результатом работы перевода на болгарский язык и обратно.
Болгарский язык был выбран потому, что он близок к русскому, но, к сожалению, это не спасло от перевода незнакомых слов в транслит.
Через триггеры проекта в скрипте я поставил выполнение функции получения данных каждую минуту.
Функция получает последние сообщения боту, используя id последнего сообщения +1. Далее, все сообщения прогоняются через translate и отправляются обратно.
Недостатки и неприятные особенности
Естественно, выбранные «инструменты» реализации бота накладывают немало ограничений. Во-первых, бот будет отвечать на сообщения с большой задержкой (до минуты). Во-вторых, несмотря на то, что Google Translate используется внутри Google Script, ограничения по количеству запросов в секунду и общему их количеству в сутки все же есть. По понятным причинам возможность использования web hook отсутствует.
Говорить о качестве работы Google Translate в роли синонимайзера вообще не приходится. Этот способ совершенно не подходит. Возможно, имеет смысл разбивать текст на предложения, а предложения на слова.
/**
* Получает входящие сообщения и отвечает на них
*/
function getMessages()
{
var botId = 'TELEGRAM_BOT_API_KEY';
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheets();
var offset = sheets[0].setActiveSelection('B1').setNumberFormat('@STRING@').getValue();
var updates = UrlFetchApp.fetch("https://api.telegram.org/bot"+botId+"/getUpdates?offset="+ offset + '&limit=40&timeout=1');
var transferLanguage = 'bg'; // Язык для синонимайзера
var sourceLanguage = 'ru'; // Язык источника
updates = JSON.parse(updates);
Logger.log(updates);
if (updates.ok) {
for (var i in updates.result) {
var update = updates.result[i];
offset = update.update_id + 1;
sheets[0].setActiveSelection('B1').setValue(offset);
sheets[0].setActiveSelection('B2').setValue(new Date(update.message.date * 1000));
// Входящее сообщение получено
var text = update.message.text;
if (text.length >= 4096) {
text = 'Ваше сообщение слишком большое, попробуйте отправить его по частям';
} else {
if (text == '/start') {
text = 'Просто вставьте текст, который необходимо уникализировать. Через несколько минут вы получите обработанный текст.';
} else {
Utilities.sleep(1000);
text = LanguageApp.translate(LanguageApp.translate(text, sourceLanguage, transferLanguage), transferLanguage, sourceLanguage);
}
writeLog({
date: new Date(update.message.date * 1000),
inMessage: update.message.text,
outMessage: text,
userName: update.message.from.first_name + ' ' + update.message.from.last_name,
userId: update.message.from.id,
userUsername: update.message.from.username
});
}
UrlFetchApp.fetch("https://api.telegram.org/bot"+botId+"/sendMessage", {
'method' : 'post',
'payload' : {
chat_id: update.message.chat.id,
text: text
}
});
}
}
}
/**
* Пишет в документ входящие сообщения и результат "синонимайзера"
*/
function writeLog(data)
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[1];
var lastRow = sheet.getLastRow() + 1;
sheet.setActiveSelection('A' + lastRow).setNumberFormat('@STRING@').setValue(data.date);
sheet.setActiveSelection('B' + lastRow).setNumberFormat('@STRING@').setValue(data.userUsername);
sheet.setActiveSelection('C' + lastRow).setNumberFormat('@STRING@').setValue(data.userId);
sheet.setActiveSelection('D' + lastRow).setNumberFormat('@STRING@').setValue(data.userName);
sheet.setActiveSelection('E' + lastRow).setNumberFormat('@STRING@').setValue(data.inMessage);
sheet.setActiveSelection('F' + lastRow).setNumberFormat('@STRING@').setValue(data.outMessage);
}
Что в итоге?
Мой эксперимент показал, что можно без проблем связать сервисы Google с ботом Telegram в личных целях, автоматизировать сбор информации и получать ее весьма оперативно. Можно без проблем написать парсер какого-нибудь авито и отправлять новые объявления по интересующем запросу в телеграм. В этом случае даже скорость ответа бота на сообщения не играет никакой существенной роли.
Синонимайзер, конечно, получился так себе.
Вот такой лог можно наблюдать в документе:
UPD: Pylorama в своем комментарии рассказал о том, как сделать WebHook.