Ранее мы уже писали о наших плагинах redmine_chat_telegram и redmine_intouch, предназначенных
для того, чтобы ваша работа с Redmine и Telegram была продуктивнее. А сегодня мы хотели бы рассказать о том, как избавились от TelegramCLI. Это большой апдейт, призванный упростить работу с нашими telegram-плагинами.
В процессе эксплуатации у нас неоднократно возникали проблемы с настройкой TelegramCLI, поэтому мы решили упростить работу наших плагинов. Для этого мы сочли необходимым избавиться от зависимости TelegramCLI, добавили вместо него Webogram и модифицировали под свои нужды. Это позволило больше не запускать на сервере сервис TelegramCLI.
Webogram
Webogram — официальный веб-клиент к Telegram, написанный на AngularJS. Поэтому, чтобы работать с Webogram через скрипты, приходится использовать headless browser, в нашем случае это PhantomJS.
Мы модифицировали код Webogram, чтобы отдавать ему запросы на нужные действия без необходимости работать с интерфейсом. В форме специального запроса плагин отправляет на URL модифицированного Webogram инструкцию сделать некую операцию в Telegram.
Принцип работы
Сначала плагин дает команду произвести какую-то операцию в Telegram.
telegram = TelegramCommon::Telegram.new
result = telegram.execute('Test')
Далее формируется строка запуска PhantomJS.
module TelegramCommon
class Telegram
...
def make_request
@api_result = `#{cli_command}`
debug(api_result)
api_result
end
def cli_command
cmd = "#{phantomjs} #{config_path} \"#{api_url}\""
debug(cmd)
cmd
end
end
end
Затем PhantomJS выполняет запрос и ожидает 10 секунд, чтобы элемент #api-status
получил класс ready, который свидетельствовал бы о том, что Webogram завершил обработку.
// plugins/redmine_telegram_common/config/phantom-proxy.js
...
page.open(url, function() {
waitFor(
function () {
return page.evaluate(function () {
return $('#api-status').hasClass('ready');
});
},
function () {
exit()
}, 10000);
});
AngularJS-контроллер AppApiController занимается обработкой запросов, и когда он заканчивает работу, то на странице у блока #api-status меняется класс на "ready", тем самым уведомляя PhantomJS о завершении операции.
// plugins/redmine_telegram_common/app/webogram/app/js/controllers.js
$scope.promiseStatus = false;
var args = {};
if (typeof $routeParams.args !== 'undefined') {
args = JSON.parse($routeParams.args)
}
$scope.handle = function () {
var command = $routeParams.command;
var handlerName = $scope['api' + command];
if (typeof handlerName === 'function') {
handlerName(args)
} else {
console.error('There is no ' + handlerName + ' api function.')
}
};
$scope.apiTest = function () {
$scope.successApi('api test')
};
...
$scope.successApi = function (msg) {
console.log('success: ' + msg);
$scope.resolveApi()
};
$scope.failedApi = function (msg) {
console.log('failed: ' + msg);
$scope.resolveApi()
};
$scope.resolveApi = function () {
$scope.promiseStatus = true
};
Вскоре запрос выполняется, и плагин получает ответ, с которым можно работать.
Заключение
В итоге, чтобы начать работать с нашими плагинами, которые ранее зависели от TelegramCLI, теперь достаточно установить новые зависимости, перейти на страницу настройки плагина redmine_telegram_common и пройти простенькую процедуру авторизации, в процессе которой PhantomJS запомнит, под каким логином отправлять запросы на Telegram.
Telegram-боты в наших плагинах redmine_chat_telegram и redmine_intouch научились работать не только через getUpdates (как ранее фоновые процессы через rake), но и через WebHooks (достаточно инициализировать ботов в настройках соответствующих плагинов, однако необходим HTTPS на Redmine). Таким образом, мы избавились от дополнительных фоновых процессов, которые раньше могли быть преградой для установки плагина неопытными пользователями.
Если вы встретили какие-то ошибки, у вас есть предложения по улучшению плагина или вы желаете принять участие в развитии плагинов, мы будем рады вашим откликам. Наши репозитории перечислены ниже.