Google apps script 在谷歌应用程序脚本中获取数据后构建卡并更新

Google apps script 在谷歌应用程序脚本中获取数据后构建卡并更新,google-apps-script,gmail-addons,Google Apps Script,Gmail Addons,我正在尝试构建一个包含2个外部API调用的Gmail插件。第一个速度快(~200ms),第二个速度慢(~5s)。因此,我希望首先使用第一次获取的结果构建卡,然后在第二次调用完成后更新卡 是否可以: 调用fetchAll并在每次请求完成时生成和呈现卡 在完成初始渲染后触发函数(在返回card.build()之后) 更新根卡而不返回它(我尝试了CardService.newNavigation().poptroot().updateCard(card.build())但没有成功) 如果您愿意以任

我正在尝试构建一个包含2个外部API调用的Gmail插件。第一个速度快(~200ms),第二个速度慢(~5s)。因此,我希望首先使用第一次获取的结果构建卡,然后在第二次调用完成后更新卡

是否可以:

  • 调用
    fetchAll
    并在每次请求完成时生成和呈现卡
  • 在完成初始渲染后触发函数(在
    返回card.build()之后)
  • 更新根卡而不返回它(我尝试了
    CardService.newNavigation().poptroot().updateCard(card.build())
    但没有成功)
如果您愿意以任何方式呈现卡片,并在获取数据后进行更新,我们将不胜感激

下面是一个示例函数(如果有用)

function onGmailMessage(e) {
  // Fetching email
  var messageId = e.gmail.messageId;
  var accessToken = e.gmail.accessToken;
  GmailApp.setCurrentMessageAccessToken(accessToken);
  var message = GmailApp.getMessageById(messageId);

  // Preparing requests
  var data = {
    'text': message.getPlainBody(),
  };
  var options = {
    'method' : 'post',
    'contentType': 'application/json',
    'payload' : JSON.stringify(data)
  };

  // Fetching responses. Here I would love to first display
  // createCard(response_1) and then when the second call finishes
  // return createCard(response_1 + '/n' + response_2)
  var response_1 = UrlFetchApp.fetch('http://API_1/', options);
  var response_2 = UrlFetchApp.fetch('http://API_2/', options);
  return createCard(response_1 + '/n' + response_2);
  
答复: 不幸的是,这是不可能做到的

更多信息: 这有点棘手,所以我将把这个答案分为三点:

[是否可以]在每次请求完成时调用
fetchAll
并生成和呈现卡

可以使用
fetchAll
函数获取所有API响应,但在更新卡中显示的内容之前,您仍将等待API 2响应

这样做的问题是,为了显示渲染的卡,需要进行某种返回。一旦返回第一个API的响应,就不会生成第二个API,因为函数已经执行了。这引出了第二点:

[是否可以]在完成初始渲染后(在
返回card.build()之后)触发函数

我用它做了一个测试,没有直接返回API 1的响应,而是将其值存储在脚本属性中,并在200毫秒后通过调用API 2执行触发器:

功能邮件(e){
//先前代码
var response_1=UrlFetchApp.fetch('http://API_1/",选择),;
ScriptApp.newTrigger(“getSecondResponse”).timeBased().after(200.create();
PropertiesService.getScriptProperties().setProperty('response1',response_1);
返回createCard(响应_1);
}
函数getSecondResponse(){
//选择2此处的定义;
var response_1=PropertiesService.getScriptProperties().getProperty(“response1”);
var response_2=UrlFetchApp.fetch('http://API_2/",选择),;
返回createCard(响应_1+/n'+响应_2);
}
并在清单中添加正确的作用域:

{
  "oauthScopes": [
    "https://www.googleapis.com/auth/script.external_request",
    "https://www.googleapis.com/auth/script.locale",
    "https://www.googleapis.com/auth/gmail.addons.current.action.compose",
    "https://www.googleapis.com/auth/gmail.addons.execute",
    "https://mail.google.com/",
    "https://www.googleapis.com/auth/script.scriptapp"
  ]
}
它调用了第一个API,在卡中显示响应并触发,卡没有更新。我认为这是因为触发器充当了一个cron作业,它是从非插件本身的某个地方执行的,因此在UI中从未看到第二个卡片返回

[是否可以]更新根卡而不返回它(我尝试了
CardService.newNavigation().poptroot().updateCard(card.build())
,但没有成功)

updateCard()
是一种方法。文档中有一整页详细介绍了导航方法的使用,但这里需要注意的重要部分是导航方法是用于响应用户交互的。从文件中:

如果用户交互或事件应导致在相同上下文中重新呈现卡,请使用和方法替换现有卡

以下是导航示例:

  • 如果交互或事件更改了当前卡的状态(例如,将任务添加到任务列表),请使用
  • 如果交互或事件提供了进一步的详细信息或提示用户采取进一步的行动(例如,单击项目标题以查看更多详细信息,或按下按钮以创建新的日历事件),则使用显示新页面,同时允许用户使用“上一步”按钮退出新页面
  • 如果交互或事件更新了前一张卡中的状态(例如,使用“详细信息”视图从更新项目标题),请使用、和之类的方式更新前一张卡和当前卡
您可以创建具有不同内容的多张卡-例如,一张包含
response\u 1
,另一张包含
response\u 1+“\n”+response\u 2
,但仍需要用户进行某种交互才能在两个视图之间切换,而且它不会绕过从API 2获得响应所需的等待时间

功能要求: 不过,你可以让谷歌知道这是一个重要的功能,你想要求他们实现它。谷歌是开发者报告问题和为其开发服务提出功能请求的地方。我建议使用功能请求模板,而不是直接使用应用程序脚本

我知道这通常是个坏消息,但我希望这对你有帮助

参考资料: