As ações universais são elementos de itens de menu que permitem que um usuário abra uma nova página da Web, mostre novos cards da interface ou execute uma função específica do Apps Script quando selecionada. Na operação, elas são muito semelhantes às ações de card, exceto que as ações universais são sempre colocadas em todos os cards do complemento, independentemente do contexto atual.
Ao usar ações universais, você garante que o usuário sempre tenha acesso a determinadas funcionalidades, não importa com qual parte do complemento ele interaja. Confira alguns exemplos de casos de uso para ações universais:
- Abra uma página da Web de configurações ou mostre um card de configurações.
- Mostrar informações de ajuda ao usuário.
- Inicie um novo fluxo de trabalho, como "Adicionar novo cliente".
- Mostrar um card que permite que um usuário envie feedback sobre o complemento.
Sempre que você tiver uma ação que não dependa do contexto atual, considere torná-la uma ação universal.
Como usar ações universais
As ações universais são configuradas no manifesto do projeto do complemento. Depois de configurar uma ação universal, ela sempre estará disponível para os usuários do seu complemento. Se o usuário estiver visualizando um card, o conjunto de ações universais definidas sempre vai aparecer no menu do card, depois de qualquer ação do card definida para ele. As ações universais aparecem nos menus de card na mesma ordem em que são definidas no manifesto do complemento.
Como configurar ações universais
Você configura ações universais no manifesto do complemento. Consulte Manifestos para mais detalhes.
Para cada ação, especifique o texto que deve aparecer no menu. Em seguida, especifique um campo openLink indicando que a ação
deve abrir diretamente uma página da Web em uma nova guia. Outra opção é especificar
um campo runFunction que especifica uma função de callback do Apps Script a ser
executada quando a ação universal for selecionada.
Quando runFunction é usado, a função de callback especificada geralmente faz uma
das seguintes ações:
- Cria cards da interface para exibição imediata retornando um objeto
UniversalActionResponsecriado. - Abre um URL, talvez depois de realizar outras tarefas, retornando um objeto
UniversalActionResponsecriado. - Realiza tarefas em segundo plano que não mudam para um novo card nem abrem um URL. Nesse caso, a função de callback não retorna nada.
Quando chamada, a função de callback recebe um objeto de evento com informações sobre o card aberto e o contexto do complemento.
Exemplo
O snippet de código a seguir mostra um exemplo de trecho de manifesto para um complemento do Google Workspace que usa ações universais ao estender o Gmail. O código define explicitamente um escopo de metadados para que o complemento possa determinar quem enviou a mensagem aberta.
"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"
}
]
},
...
},
...
As três ações universais definidas no exemplo anterior fazem o seguinte:
- Abrir google.com abre https://www.google.com em uma nova guia.
- Abrir URL de contato executa uma função que determina qual URL abrir e o abre em uma nova guia usando um objeto
OpenLink. O código cria o URL usando o endereço de e-mail do remetente. - Abrir configurações executa a função
createSettingsCards()definida no projeto de script do complemento. Essa função retorna um objetoUniversalActionResponseválido que contém um conjunto de cards com configurações de complemento e outras informações. Depois que a função terminar de criar esse objeto, a interface vai mostrar a lista de cards (consulte Retornar vários cards). - Executar sincronização em segundo plano executa a função
runBackgroundSync()definida no projeto de script do complemento. Essa função não cria cards. Em vez disso, ela realiza outras tarefas em segundo plano que não mudam a interface. Como a função não retorna umUniversalActionResponse, a interface não mostra um novo card quando a função termina. Em vez disso, a UI mostra um ícone giratório de indicador de carregamento enquanto a função está em execução.
Confira um exemplo de como construir as funções openContactURL(), createSettingsResponse() e 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.
}