Ações universais

As ações universais são elementos de itens de menu que permitem ao usuário abrir uma nova página da Web, exibir novos cards de IU ou executar uma função específica do Apps Script quando selecionada. Em operação, elas são muito semelhantes às ações do card, exceto pelo fato de que as ações universais são sempre colocadas em todos os cards no seu complemento, independentemente do contexto atual do complemento.

Ao usar as ações universais, você garante que o usuário sempre tenha acesso a determinadas funcionalidades, independentemente da parte do complemento com que ele interagir. Confira alguns exemplos de casos de uso para ações universais:

  • Abra uma página da Web de configurações (ou exiba um card de configurações).
  • Mostre informações de ajuda ao usuário.
  • Inicie um novo fluxo de trabalho, como "Adicionar novo cliente".
  • Mostre 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 estará sempre disponível para os usuários do seu complemento. Se o usuário estiver visualizando um cartão, o conjunto de ações universais que você definiu sempre será exibido no menu do cartão, após qualquer ação do cartão definida para esse cartão. As ações universais aparecem nos menus do card na mesma ordem em que são definidas no manifesto do complemento.

Como configurar ações universais

Configure ações universais no manifesto do complemento. Consulte Manifestos para mais detalhes.

Para cada ação, especifique o texto que aparecerá no menu dela. Em seguida, especifique um campo openLink indicando que a ação deve abrir diretamente uma página da Web em uma nova guia. Como alternativa, você pode especificar um campo runFunction que especifica uma função de callback do Apps Script a ser executada quando a ação universal é selecionada.

Quando runFunction é usado, a função de callback especificada geralmente realiza uma das seguintes ações:

  • Cria cards de interface para serem mostrados imediatamente retornando um objeto UniversalActionResponse criado.
  • Abre um URL, talvez depois de realizar outras tarefas, retornando um objeto UniversalActionResponse criado.
  • Executa 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 cartão 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 enquanto estende 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.br abre https://www.google.com em uma nova guia.
  • Abrir URL do contato executa uma função que determina qual URL abrir e, em seguida, 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.
  • Open Settings executa a função createSettingsCards() definida no projeto de script de complemento. Essa função retorna um objeto UniversalActionResponse válido contendo um conjunto de cards com configurações de complementos e outras informações. Depois que a função termina de criar esse objeto, a interface exibe a lista de cards. Consulte Como retornar vários cards.
  • Executar a sincronização em segundo plano executa a função runBackgroundSync() definida no projeto de script de complemento. Essa função não cria cards. Em vez disso, ela executa algumas outras tarefas em segundo plano que não alteram a interface. Como a função não retorna um UniversalActionResponse, a interface não mostra um novo card quando a função é concluída. Em vez disso, a interface mostra um ícone de carregamento enquanto a função está em execução.

Veja um exemplo de como criar 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.
}