在 Google Apps 脚本中获取数据后构建卡片并更新它
Building a card and updating it after fetching data in Google Apps Script
我正在尝试构建一个包含 2 个外部 API 调用的 Gmail 插件。第一个很快(~200ms),第二个很慢(~5s)。因此,我想先用第一次获取的结果构建卡片,然后在第二次调用完成后更新卡片。
是否可以:
- 每次请求完成时调用
fetchAll
并构建和呈现卡片
- 在初始渲染完成后触发一个函数(在
return card.build()
之后)
- 更新root卡不返回(我试了
CardService.newNavigation().popToRoot().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);
答案:
很遗憾,这是不可能的。
更多信息:
这有点棘手,所以我将把这个答案分成三点:
[Is it possible to] call fetchAll
and build and render the card each time a request finishes?
可以使用 fetchAll
函数来获取所有 API 响应,但您仍然需要等待 API 2 响应,然后才能更新卡.
问题是为了显示渲染的卡片,您需要制作某种 return。一旦您 return 第一个 API 的响应,您的第二个 API 将根本不会被执行,因为该函数已经执行。这导致第二点:
[Is it possible to] trigger a function after the initial rendering is done (after return card.build()
)
我用这个做了一个测试,而不是直接 returning API 1 的响应我将它的值存储在脚本 属性 中并在 200 毫秒后使用呼叫 API 2:
function onGmailMessage(e) {
// previous code
var response_1 = UrlFetchApp.fetch('http://API_1/', options);
ScriptApp.newTrigger("getSecondResponse").timeBased().after(200).create();
PropertiesService.getScriptProperties().setProperty('response1', response_1);
return createCard(response_1);
}
function getSecondResponse() {
// options 2 definition here;
var response_1 = PropertiesService.getScriptProperties().getProperty("response1");
var response_2 = UrlFetchApp.fetch('http://API_2/', options);
return createCard(response_1 + '/n' + response_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 作业从某个地方执行,而不是附加组件本身,所以第二张卡片 return 在 UI.[=27= 中从未出现过]
[Is it possible to] update the root card without returning it (I tried CardService.newNavigation().popToRoot().updateCard(card.build())
without success)
updateCard()
是 Navigation class. There's a whole page in the documentation which details the uses of Card navigation 的一种方法,但这里要去掉的重要部分是导航方法用于响应 用户交互 .来自文档:
If a user interaction or event should result in re-rendering cards in the same context, use Navigation.pushCard(), Navigation.popCard(), and Navigation.updateCard() methods to replace the existing cards.
The following are navigation examples:
- If an interaction or event changes the state of the current card (for example, adding a task to a task list), use updateCard().
- If an interaction or event provides further detail or prompts the user for further action (for example, clicking an item's title to see more details, or pressing a button to create a new Calendar event), use pushCard() to show the new page while allowing the user to exit the new page using the back-button.
- If an interaction or event updates state in a previous card (for example, updating an item's title from with the detail view), use something like popCard(), popCard(), pushCard(previous), and pushCard(current) to update previous card and the current card.
您可以创建多张具有不同内容的卡片 - 例如一张包含 response_1
和一张包含 response_1 + "\n" + response_2
,但仍需要用户进行某种交互才能在两者之间切换两个视图,并且它不会绕过您需要从 API 获得响应的等待时间 2.
功能请求:
但是,您可以让 Google 知道这是一项重要的功能,并且您希望请求他们实现它。 Google 的 Issue Tracker is a place for developers to report issues and make feature requests for their development services. I would suggest using the feature request template for G Suite Add-ons 为此,而不是直接使用 Apps 脚本。
参考文献:
我正在尝试构建一个包含 2 个外部 API 调用的 Gmail 插件。第一个很快(~200ms),第二个很慢(~5s)。因此,我想先用第一次获取的结果构建卡片,然后在第二次调用完成后更新卡片。
是否可以:
- 每次请求完成时调用
fetchAll
并构建和呈现卡片 - 在初始渲染完成后触发一个函数(在
return card.build()
之后) - 更新root卡不返回(我试了
CardService.newNavigation().popToRoot().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);
答案:
很遗憾,这是不可能的。
更多信息:
这有点棘手,所以我将把这个答案分成三点:
[Is it possible to] call
fetchAll
and build and render the card each time a request finishes?
可以使用 fetchAll
函数来获取所有 API 响应,但您仍然需要等待 API 2 响应,然后才能更新卡.
问题是为了显示渲染的卡片,您需要制作某种 return。一旦您 return 第一个 API 的响应,您的第二个 API 将根本不会被执行,因为该函数已经执行。这导致第二点:
[Is it possible to] trigger a function after the initial rendering is done (after
return card.build()
)
我用这个做了一个测试,而不是直接 returning API 1 的响应我将它的值存储在脚本 属性 中并在 200 毫秒后使用呼叫 API 2:
function onGmailMessage(e) {
// previous code
var response_1 = UrlFetchApp.fetch('http://API_1/', options);
ScriptApp.newTrigger("getSecondResponse").timeBased().after(200).create();
PropertiesService.getScriptProperties().setProperty('response1', response_1);
return createCard(response_1);
}
function getSecondResponse() {
// options 2 definition here;
var response_1 = PropertiesService.getScriptProperties().getProperty("response1");
var response_2 = UrlFetchApp.fetch('http://API_2/', options);
return createCard(response_1 + '/n' + response_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 作业从某个地方执行,而不是附加组件本身,所以第二张卡片 return 在 UI.[=27= 中从未出现过]
[Is it possible to] update the root card without returning it (I tried
CardService.newNavigation().popToRoot().updateCard(card.build())
without success)
updateCard()
是 Navigation class. There's a whole page in the documentation which details the uses of Card navigation 的一种方法,但这里要去掉的重要部分是导航方法用于响应 用户交互 .来自文档:
If a user interaction or event should result in re-rendering cards in the same context, use Navigation.pushCard(), Navigation.popCard(), and Navigation.updateCard() methods to replace the existing cards.
The following are navigation examples:
- If an interaction or event changes the state of the current card (for example, adding a task to a task list), use updateCard().
- If an interaction or event provides further detail or prompts the user for further action (for example, clicking an item's title to see more details, or pressing a button to create a new Calendar event), use pushCard() to show the new page while allowing the user to exit the new page using the back-button.
- If an interaction or event updates state in a previous card (for example, updating an item's title from with the detail view), use something like popCard(), popCard(), pushCard(previous), and pushCard(current) to update previous card and the current card.
您可以创建多张具有不同内容的卡片 - 例如一张包含 response_1
和一张包含 response_1 + "\n" + response_2
,但仍需要用户进行某种交互才能在两者之间切换两个视图,并且它不会绕过您需要从 API 获得响应的等待时间 2.
功能请求:
但是,您可以让 Google 知道这是一项重要的功能,并且您希望请求他们实现它。 Google 的 Issue Tracker is a place for developers to report issues and make feature requests for their development services. I would suggest using the feature request template for G Suite Add-ons 为此,而不是直接使用 Apps 脚本。