Google apps script 在服务器端执行Google Apps脚本异步函数

Google apps script 在服务器端执行Google Apps脚本异步函数,google-apps-script,gmail-addons,Google Apps Script,Gmail Addons,我有一个GMail插件,它使用CardService作为UI。卡操作的一些回调函数占用30秒以上。因此,我得到以下错误 Gmail无法执行此附加操作 是否有任何方法可以在服务器端异步运行Google Apps脚本功能,这样我就可以向用户返回一些通知并在幕后继续工作 我尝试过使用一些类似的库,但运气不好,我能够在语法上使用Promissions,但在功能上它仍然是同步的。到目前为止,Gmail插件没有异步执行。即使存在一些问题,也无法在没有用户操作的情况下刷新UI 但是,有一个黑客。您可以做的是,

我有一个GMail插件,它使用CardService作为UI。卡操作的一些回调函数占用30秒以上。因此,我得到以下错误

Gmail无法执行此附加操作

是否有任何方法可以在服务器端异步运行Google Apps脚本功能,这样我就可以向用户返回一些通知并在幕后继续工作


我尝试过使用一些类似的库,但运气不好,我能够在语法上使用Promissions,但在功能上它仍然是同步的。

到目前为止,Gmail插件没有异步执行。即使存在一些问题,也无法在没有用户操作的情况下刷新UI

但是,有一个黑客。您可以做的是,如果有一个长时间运行的进程,只需创建一个“openlink”操作(setlink),它应该打开一个带有html响应的url()。这个html可以有jQueryAjax调用,可以等待一段时间。在html窗口中获得响应后,将页面重定向到通过传递响应数据传递的重定向uri。因此,我们的插件将获得一个回调函数,该函数的参数为json对象,所有查询参数都指向重定向uri。获得预期响应后,使用缓存响应。返回一些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");
}
函数generateNewStateToken(回调名称、用户信息){
返回ScriptApp.newStateToken()
.withMethod(callbackName)
.withArgument(“用户信息”,JSON.stringify(用户信息))
.withTimeout(3600)
.createToken();
}
函数getRedirectURI(){
返回“https://script.google.com/macros/d/“+ScriptApp.getScriptId()+”/usercallback”;
}
var htmlUrl=+“?redirect_uri=“+getRedirectURI()+”&state=“+generateNewStateToken”(“异步回调”),{};
CardService.newOpenLink().setUrl(htmlur).setOpenAs(CardService.OpenAs.OVERLAY).setOnClose(CardService.OnClose.RELOAD_ADD_ON);
函数异步回调(数据){
data.response;//可以从脚本传递的响应
CacheService.getUserCache().put(“long\u running\u process\u resp”,data.response);
data.user\u info;//在状态令牌创建期间传递的用户\u信息
//使用缓存服务缓存数据
返回HtmlService.createHtmlOutFromFile(“成功”);
}
success.html

长时间运行的进程已完成

setTimeout(函数(){ top.window.close(); }, 2000);
萨布的答案很好。但是,如果希望触发长时间运行的进程而不希望用户单击openlink,则可以使用以下方法渲染图像: CardService.newImage().setImageUrl('https://yourservice.com/pixel/action.png?name=value&_nocache=“+新日期().getTime())

在服务器端,您可以将路径“/pixel/action.png”映射到长时间运行的代码,该代码在完成时返回一个微小的透明像素(1x1):
数据:图像/png;base64,Ivborw0Kggoaaaansuhueugaaaaaaaabcayaaaaffcsjaaadulleqvr42mp8z8bqdwaehqgahkmiqaaabjru5erkjggg==

在没有看到您所做工作的示例的情况下,我们所能提供的只是您应该通过使用改进您的后端操作,并避免昂贵的计算。请注意,每次外接程序运行任何函数时,都会对库和全局函数进行求值,因此通常不鼓励使用外接程序。@鲁本感谢您的评论。我想最后我需要重新设计我的后端计算。然而,我的问题的目的是确保在服务器端无法异步执行某些操作,可能是最近从GAS端更改了某些操作或类似的操作。评论由@tehhowch:)@Rubén Sorry:)发表,但对编辑感到困惑