Выполнение асинхронной функции скрипта Google Apps на стороне сервера
У меня есть надстройка GMail, которая использует CardService для пользовательского интерфейса. Некоторые функции обратного вызова для действий с картой занимают более 30 секунд. Таким образом, я получаю следующую ошибку.
Gmail не может выполнить это действие надстройки.
Есть ли какой-нибудь способ запуска функций скрипта Google Apps на стороне сервера асинхронным способом, чтобы я мог вернуть пользователю некоторое уведомление и продолжить работу за кулисами.
Я пытался использовать некоторые библиотеки, подобные этой, но без удачи, я могу использовать синтаксически Обещания, но функционально это все еще синхронно.
1 ответ
На данный момент асинхронное выполнение надстройки Gmail отсутствует. Даже если что-то есть, невозможно обновить пользовательский интерфейс без действий пользователя.
Но есть взлом. Что вы можете сделать, если существует длительный процесс, просто создайте действие "openlink" (установить ссылку), которое должно открыть URL ( https://yourhtmlpageurl/?redirect_uri=) с ответом html. Этот HTML может иметь вызов jquery ajax, который может подождать некоторое время. Как только вы получите ответ в html-окне, перенаправьте страницу на redirect_uri, который передается путем передачи данных ответа. Итак, наше дополнение получит обратный вызов функции с параметром в качестве объекта json со всеми параметрами запроса к redirect_uri. Как только вы получите ожидаемый ответ, кэшируйте ответ с помощью CacheService. верните HTML-шаблон успеха, который автоматически закроет окно.
Для создания действия openlink:
Для создания URI сценария перенаправления с токеном состояния:
function generateNewStateToken(callbackName, user_info) {
return ScriptApp.newStateToken()
.withMethod(callbackName)
.withArgument("user_info", JSON.stringify(user_info))
.withTimeout(3600)
.createToken();
}
function getRedirectURI() {
return "https://script.google.com/macros/d/" + ScriptApp.getScriptId() + "/usercallback";
}
var htmlUrl = <your_html_url> + "?redirect_uri="+ getRedirectURI() + "&state=" + generateNewStateToken("asyncCallback", {});
CardService.newOpenLink().setUrl(htmlUrl).setOpenAs(CardService.OpenAs.OVERLAY).setOnClose(CardService.OnClose.RELOAD_ADD_ON);
function asyncCallback(data) {
data.response; // response which you can pass from script
CacheService.getUserCache().put("long_running_process_resp", data.response);
data.user_info; // user_info passed during state token creation
// cache the data using cache service
return HtmlService.createHtmlOutputFromFile("success");
}
success.html:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons1.css">
</head>
<body>
<div class="sidebar">
<p>Long running Process completed.</p>
</div>
</body>
<script>
setTimeout(function() {
top.window.close();
}, 2000);
</script>
</html>
Как только файл success.html будет закрыт, произойдет обновление дополнения gmail. Таким образом, вы можете искать долгосрочные данные ответа от CacheService.
Дайте мне знать, если у вас есть еще вопросы по этому процессу.
Ответ Саббу довольно хорош. Но если вы хотите запустить длительный процесс, не ожидая, что пользователь щелкнет открытую ссылку, вы можете визуализировать изображение, используя: CardService.newImage().setImageUrl('https://yourservice.com/pixel/action.png? имя = значение &_nocache='+ новая дата ().getTime())
На стороне сервера вы можете сопоставить путь '/pixel/action.png' с продолжительным кодом, который после завершения возвращает крошечный прозрачный пиксель (1x1): data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEz8