我做了很多使用 Apps 脚本的场景,但没有任何效果!我有一个函数,它使
GET
请求返回一组卡片。现在,有时我需要再次刷新此卡片以获取新内容。
function listTemplatesCards(){
var getAllTemplates = getTemplates();
var allTemplates = getAllTemplates.templates;
var theUserSlug = getAllTemplates.user_slug;
var templateCards = [];
//There are templates
if(allTemplates.length > 0){
allTemplates.forEach(function(template){
templateCards.push(templateCard(template, theUserSlug).build());
});
return templateCards;
}
}
这个函数在
onTriggerFunction
被调用。现在,如果我移动到另一张卡并且我想再次回到根目录但以干净清晰的方式,我使用它但它不起作用:
//Move the user to the root card again
var refreshNav = CardService.newNavigation().popToRoot();
return CardService.newActionResponseBuilder().setStateChanged(true).setNavigation(refreshNav).build();
简单地说,我想要的是一旦用户点击
Refresh
按钮,卡片就会刷新/更新自身以再次拨打电话并获取新数据。
我发现这样做的唯一方法是始终使用一张卡作为根。在main函数中(命名为
appscript.json
onTriggerFunction
),只返回一张卡片,而不是卡片数组。然后你可以使用 popToRoot().updateCard(...)
并且它有效。
我为此苦苦挣扎了一天多,改进了 Glen Little 的回答,使其更加清晰。
我有一个要刷新的根卡定义在一个名为:
onHomepage
.
我更新
appscript.json
清单以设置 homepageTrigger
和 onTriggerFunction
返回构建我的根卡的功能。
"gmail": {
"homepageTrigger": {
"enabled": true,
"runFunction":"onHomepage"
},
"contextualTriggers":[
{
"unconditional":{},
"onTriggerFunction": "onHomepage"
}
]
}
然后就像构建一个
gotoRoot
导航按钮功能一样简单,它将始终刷新根页面。
function gotoRootCard() {
var nav = CardService.newNavigation()
.popToRoot()
.updateCard(onHomepage());
return CardService.newActionResponseBuilder()
.setNavigation(nav)
.build();
}
就 gmail 插件而言,卡片不会刷新,但会更新为新卡片。而且非常简单。
//lets assume you need a form to be updated
function updateProfile() {
//ajax calls
//...
//recreate the card again.
var card = CardService.newCardBuilder();
//fill it with widgets
//....
//replace the current outdated card with the newly created card.
return CardService.newNavigation().updateCard(card.build());
}
适用于我的 Gmail 插件的糟糕技巧:
return CardService.newActionResponseBuilder()
.setStateChanged(true) // this doesn't seem to do much. Wish it would reload the add-on
.setNotification(CardService.newNotification()
.setText('Created calendar event')
)
// HACK! Open a URL which closes itself in order to activate the RELOAD_ADD_ON side-effect
.setOpenLink(CardService.newOpenLink()
.setUrl("https://some_site.com/close_yoself.html")
.setOnClose(CardService.OnClose.RELOAD_ADD_ON))
.build();
close_yoself.html的内容就是:
<!DOCTYPE html>
<html><body onload="self.close()"></body></html>
所以,看起来 Google 已经考虑并解决了使用 OpenLink 的 ActionResponse 的这个问题,但没有为使用导航或通知的 ActionResponse 解决这个问题。上面的 hack 绝对不是很好,因为它会短暂地打开和关闭浏览器窗口,但至少它刷新了附加组件,而无需用户手动操作。
感谢所有这些其他答案,不感谢谷歌文档 :D.
这是一个完整的工作示例,在单击按钮后使用随机数显示更新:
appscript.json
{
"timeZone": "Etc/GMT",
"exceptionLogging": "STACKDRIVER",
"oauthScopes": [
"https://www.googleapis.com/auth/gmail.addons.execute"
],
"gmail": {
"name": "Demo Card Refresh",
"logoUrl": "https://www.gstatic.com/images/icons/material/system/1x/receipt_black_24dp.png",
"homepageTrigger": {
"runFunction": "myFunction"
}
},
"runtimeVersion": "V8"
}
代码.gs
function myFunction(e) {
return myCard().build();
}
function myCard() {
return CardService
.newCardBuilder()
.setHeader(
CardService.newCardHeader().setTitle('Refresh ID: ' + Math.random(9999999999))
)
.addSection(
CardService.newCardSection()
.setHeader('Section')
.addWidget(
CardService.newTextButton()
.setText('Refresh')
.setOnClickAction(
CardService.newAction()
.setFunctionName('myAction')
)
)
)
}
function myAction() {
return CardService.newNavigation().updateCard(myCard().build());
}