通用動作是選單項目元素,可讓使用者開啟新網頁、顯示新的 UI 資訊卡,或在選取時執行特定 Apps Script 函式。運作方式與資訊卡動作非常類似,不過,無論目前的外掛程式內容為何,通用操作一律會放置於外掛程式中的每張資訊卡。
透過通用動作,您可以確保使用者一律可存取特定功能,無論他們與外掛程式中的哪個部分互動。以下是通用動作的用途範例:
- 開啟設定頁面 (或顯示設定資訊卡)。
- 向使用者顯示說明資訊。
- 請發起新的工作流程,例如「加入新客戶」。
- 顯示可讓使用者針對外掛程式提供意見的資訊卡。
每當您有不依賴目前情境的動作時,應考慮將其設為通用動作。
使用通用動作
通用動作是在外掛程式的專案資訊清單中設定。通用動作設定完成後,外掛程式的使用者就能隨時存取該動作。如果使用者正在查看資訊卡,您定義的通用動作組合一律會在您為該資訊卡定義的任何資訊卡動作之後顯示,位於資訊卡選單中。通用動作會按照外掛程式資訊清單中的定義順序,顯示在資訊卡選單中。
設定通用動作
您可以在外掛程式的資訊清單中設定通用動作,詳情請參閱資訊清單一文。
您需要為每個動作指定應出現在該動作選單中的文字。接著,您可以指定 openLink
欄位,表示動作應在新分頁中開啟網頁。或者,您可以指定 runFunction
欄位,指定在已選取通用動作時,要執行的 Apps Script 回呼函式。
使用 runFunction
時,指定的回呼函式通常會執行下列其中一項操作:
- 透過傳回建構的
UniversalActionResponse
物件,建構 UI 資訊卡以立即顯示。 - 開啟網址,例如在完成其他工作後,傳回已建構的
UniversalActionResponse
物件。 - 執行不會切換至新卡片或開啟網址的背景工作。 在此情況下,回呼函式不會傳回任何內容。
呼叫回呼函式時,系統會傳遞事件物件,其中包含開啟資訊卡和外掛程式內容的相關資訊。
範例
下列程式碼片段是 Google Workspace 外掛程式範例,其中摘錄一段使用 Gmail 的通用動作。程式碼會明確設定中繼資料範圍,以便外掛程式判斷誰是已開啟訊息的傳送者。
"oauthScopes": [
"https://www.googleapis.com/auth/gmail.addons.current.message.metadata"
],
"addOns": {
"common": {
"name": "Universal Actions Only Addon",
"logoUrl": "https://www.example.com/hosted/images/2x/my-icon.png",
"openLinkUrlPrefixes": [
"https://www.google.com",
"https://www.example.com/urlbase"
],
"universalActions": [{
"label": "Open google.com",
"openLink": "https://www.google.com"
}, {
"label": "Open contact URL",
"runFunction": "openContactURL"
}, {
"label": "Open settings",
"runFunction": "createSettingsResponse"
}, {
"label": "Run background sync",
"runFunction": "runBackgroundSync"
}],
...
},
"gmail": {
"contextualTriggers": [
{
"unconditional": {},
"onTriggerFunction": "getContextualAddOn"
}
]
},
...
},
...
上述範例定義的三個通用動作如下:
- 開啟 google.com 在新分頁中開啟 https://www.google.com。
- 「Open contact URL」(開啟聯絡人網址) 會執行函式以判斷要開啟哪個網址,然後使用
OpenLink
物件在新分頁中開啟該網址。程式碼會使用傳送者的電子郵件地址來建立網址。 - 「Open settings」會執行外掛程式指令碼專案中定義的
createSettingsCards()
函式。這個函式會傳回有效的UniversalActionResponse
物件,其中包含一組具有外掛程式設定和其他資訊的資訊卡。函式完成建構這個物件後,UI 會顯示資訊卡清單 (請參閱「傳回多張資訊卡」)。 - 執行背景同步處理會執行外掛程式指令碼專案中定義的
runBackgroundSync()
函式。這個函式不會建構資訊卡,而是執行其他不會變更 UI 的背景工作。由於函式不會傳回UniversalActionResponse
,因此 UI 不會在函式完成時顯示新的資訊卡。相反地,UI 會在函式執行時顯示載入指標提示。
以下範例說明如何建構 openContactURL()
、createSettingsResponse()
和 runBackgroundSync()
函式:
/**
* Open a contact URL.
* @param {Object} e an event object
* @return {UniversalActionResponse}
*/
function openContactURL(e) {
// Activate temporary Gmail scopes, in this case so that the
// open message metadata can be read.
var accessToken = e.gmail.accessToken;
GmailApp.setCurrentMessageAccessToken(accessToken);
// Build URL to open based on a base URL and the sender's email.
// This URL must be included in the openLinkUrlPrefixes whitelist.
var messageId = e.gmail.messageId;
var message = GmailApp.getMessageById(messageId);
var sender = message.getFrom();
var url = "https://www.example.com/urlbase/" + sender;
return CardService.newUniversalActionResponseBuilder()
.setOpenLink(CardService.newOpenLink()
.setUrl(url))
.build();
}
/**
* Create a collection of cards to control the add-on settings and
* present other information. These cards are displayed in a list when
* the user selects the associated "Open settings" universal action.
*
* @param {Object} e an event object
* @return {UniversalActionResponse}
*/
function createSettingsResponse(e) {
return CardService.newUniversalActionResponseBuilder()
.displayAddOnCards(
[createSettingCard(), createAboutCard()])
.build();
}
/**
* Create and return a built settings card.
* @return {Card}
*/
function createSettingCard() {
return CardService.newCardBuilder()
.setHeader(CardService.newCardHeader().setTitle('Settings'))
.addSection(CardService.newCardSection()
.addWidget(CardService.newSelectionInput()
.setType(CardService.SelectionInputType.CHECK_BOX)
.addItem("Ask before deleting contact", "contact", false)
.addItem("Ask before deleting cache", "cache", false)
.addItem("Preserve contact ID after deletion", "contactId", false))
// ... continue adding widgets or other sections here ...
).build(); // Don't forget to build the card!
}
/**
* Create and return a built 'About' informational card.
* @return {Card}
*/
function createAboutCard() {
return CardService.newCardBuilder()
.setHeader(CardService.newCardHeader().setTitle('About'))
.addSection(CardService.newCardSection()
.addWidget(CardService.newTextParagraph()
.setText('This add-on manages contact information. For more '
+ 'details see the <a href="https://www.example.com/help">'
+ 'help page</a>.'))
// ... add other information widgets or sections here ...
).build(); // Don't forget to build the card!
}
/**
* Run background tasks, none of which should alter the UI.
* Also records the time of sync in the script properties.
*
* @param {Object} e an event object
*/
function runBackgroundSync(e) {
var props = PropertiesService.getUserProperties();
props.setProperty("syncTime", new Date().toString());
syncWithContacts(); // Not shown.
updateCache(); // Not shown.
validate(); // Not shown.
// no return value tells the UI to keep showing the current card.
}