Como estender a IU do Compose com ações de escrita

Mantenha tudo organizado com as coleções Salve e categorize o conteúdo com base nas suas preferências.

Além de fornecer uma interface baseada em cartão quando um usuário está lendo uma mensagem do Gmail, Google Workspace os complementos que estendem o Gmail podem fornecer outra interface quando o usuário está escrevendo novas mensagens ou respondendo a mensagens existentes. Isso permite que Google Workspace os complementos automatizem a tarefa de escrever e-mails para o usuário.

Acessar a IU do complemento

Existem duas maneiras de visualizar a IU de escrita de um complemento. A primeira é começar a escrever um novo rascunho ou resposta enquanto o complemento já estiver aberto. A segunda maneira é iniciar o complemento ao escrever um rascunho.

Os dois casos fazem com que o complemento execute a função de gatilho do Compose correspondente, definida no manifesto do complemento. A função de gatilho do Compose cria a IU para essa ação de composição, que o Gmail exibe ao usuário.

Criar um complemento do Compose

Para adicionar a funcionalidade do Compose a um complemento, siga estas etapas gerais:

  1. Adicione o campo gmail.composeTrigger ao manifesto do projeto de script de complementos e atualize os escopos do manifesto para incluir os necessários para ações do Compose.
  2. Implemente uma função de gatilho do Compose que crie uma IU de composição quando o acionador for disparado. As funções de gatilho do Compose retornam um único objeto Card ou uma matriz de objetos Card que compõem a IU para a ação do Compose.
  3. Implemente funções de callback associadas necessárias para reagir às interações da IU do Compose do usuário. Essas funções não são a ação de composição em si (o que só faz com que a IU do Compose seja exibida). Na verdade, essas são as funções individuais que controlam o que acontece quando diferentes elementos da IU de composição são selecionados. Por exemplo, um cartão de IU contendo um botão geralmente tem uma função de callback associada que é executada quando um usuário clica nesse botão. A função de callback para widgets que atualizam o conteúdo da mensagem de rascunho precisa retornar um objeto UpdateDraftActionResponse.

Função gatilho do Compose

Uma IU de composição de complementos é criada da mesma forma que a IU de mensagens de complementos, usando o serviço de cards do Apps Script para criar cards e preenchê-los com widgets.

Implemente o gmail.composeTrigger.selectActions[].runFunction definido no manifesto. A função de gatilho do Compose precisa retornar um único objeto Card ou uma matriz de objetos Card que compõem a IU do Compose para essa ação. Essas funções são muito semelhantes às funções de gatilho contextuais e precisam criar cards da mesma forma.

Objetos de evento de gatilho do Compose

Quando uma ação de composição é selecionada, ela executa a função de gatilho de composição correspondente e transmite à função um objeto de evento como parâmetro. O objeto de evento pode carregar informações sobre o contexto do complemento e o rascunho que está sendo composto para a função de gatilho.

Consulte Estrutura do objeto de eventos para mais detalhes sobre como as informações são organizadas no objeto de evento. As informações contidas no objeto de evento são parcialmente controladas pelo valor do campo de manifesto gmail.composeTrigger.draftAccess:

  • Se o campo de manifesto gmail.composeTrigger.draftAccess for NONE ou não for incluído, o objeto de evento terá apenas informações mínimas.

  • Se gmail.composeTrigger.draftAccess for definido como METADATA, o objeto de evento transmitido para a função de gatilho do Compose será preenchido com listas de destinatários do e-mail que está sendo composto.

Inserir conteúdo em rascunhos ativos

Normalmente, uma IU Google Workspace de composição adicional oferece opções e controle de usuário que ajudam a escrever uma mensagem. Para esses casos de uso, depois que o usuário fizer seleções na IU, o complemento interpretará as seleções e atualizará o rascunho do e-mail atual de trabalho.

Para facilitar a atualização do e-mail atual do rascunho, o serviço de cartão foi ampliado com as seguintes classes:

Normalmente, uma IU de composição de complemento inclui um widget 'Save' ou 'Insert' em que um usuário pode clicar para indicar que concluiu as seleções na IU e quer que suas opções sejam adicionadas ao e-mail que ele está escrevendo. Para adicionar essa interatividade, o widget precisa ter um objeto Action associado que instrua o complemento a executar uma função de callback específica quando o widget for clicado. Você precisa implementar essas funções de callback. Cada função de callback precisa retornar um objeto UpdateDraftActionResponse criado que detalha as mudanças que precisam ser feitas no e-mail de rascunho atual.

Exemplo 1

O snippet de código a seguir mostra como criar uma IU do Compose que atualiza o assunto e os destinatários "Para", "Cc" e "Cco" do rascunho de e-mail atual.

    /**
     * Compose trigger function that fires when the compose UI is
     * requested. Builds and returns a compose UI for inserting images.
     *
     * @param {event} e The compose trigger event object. Not used in
     *         this example.
     * @return {Card[]}
     */
    function getComposeUI(e) {
      return [buildComposeCard()];
    }

    /**
     * Build a card to display interactive buttons to allow the user to
     * update the subject, and To, Cc, Bcc recipients.
     *
     * @return {Card}
     */
    function buildComposeCard() {

      var card = CardService.newCardBuilder();
      var cardSection = CardService.newCardSection().setHeader('Update email');
      cardSection.addWidget(
          CardService.newTextButton()
              .setText('Update subject')
              .setOnClickAction(CardService.newAction()
                  .setFunctionName('applyUpdateSubjectAction')));
      cardSection.addWidget(
          CardService.newTextButton()
              .setText('Update To recipients')
              .setOnClickAction(CardService.newAction()
                  .setFunctionName('updateToRecipients')));
      cardSection.addWidget(
          CardService.newTextButton()
              .setText('Update Cc recipients')
              .setOnClickAction(CardService.newAction()
                  .setFunctionName('updateCcRecipients')));
      cardSection.addWidget(
          CardService.newTextButton()
              .setText('Update Bcc recipients')
              .setOnClickAction(CardService.newAction()
                  .setFunctionName('updateBccRecipients')));
      return card.addSection(cardSection).build();
    }

    /**
     * Updates the subject field of the current email when the user clicks
     * on "Update subject" in the compose UI.
     *
     * Note: This is not the compose action that builds a compose UI, but
     * rather an action taken when the user interacts with the compose UI.
     *
     * @return {UpdateDraftActionResponse}
     */
    function applyUpdateSubjectAction() {
      // Get the new subject field of the email.
      // This function is not shown in this example.
      var subject = getSubject();
      var response = CardService.newUpdateDraftActionResponseBuilder()
          .setUpdateDraftSubjectAction(CardService.newUpdateDraftSubjectAction()
              .addUpdateSubject(subject))
          .build();
      return response;
    }

    /**
     * Updates the To recipients of the current email when the user clicks
     * on "Update To recipients" in the compose UI.
     *
     * Note: This is not the compose action that builds a compose UI, but
     * rather an action taken when the user interacts with the compose UI.
     *
     * @return {UpdateDraftActionResponse}
     */
    function applyUpdateToRecipientsAction() {
      // Get the new To recipients of the email.
      // This function is not shown in this example.
      var toRecipients = getToRecipients();
      var response = CardService.newUpdateDraftActionResponseBuilder()
          .setUpdateDraftToRecipientsAction(CardService.newUpdateDraftToRecipientsAction()
              .addUpdateToRecipients(toRecipients))
          .build();
      return response;
    }

    /**
     * Updates the Cc recipients  of the current email when the user clicks
     * on "Update Cc recipients" in the compose UI.
     *
     * Note: This is not the compose action that builds a compose UI, but
     * rather an action taken when the user interacts with the compose UI.
     *
     * @return {UpdateDraftActionResponse}
     */
    function applyUpdateCcRecipientsAction() {
      // Get the new Cc recipients of the email.
      // This function is not shown in this example.
      var ccRecipients = getCcRecipients();
      var response = CardService.newUpdateDraftActionResponseBuilder()
          .setUpdateDraftCcRecipientsAction(CardService.newUpdateDraftCcRecipientsAction()
              .addUpdateToRecipients(ccRecipients))
          .build();
      return response;
    }

    /**
     * Updates the Bcc recipients  of the current email when the user clicks
     * on "Update Bcc recipients" in the compose UI.
     *
     * Note: This is not the compose action that builds a compose UI, but
     * rather an action taken when the user interacts with the compose UI.
     *
     * @return {UpdateDraftActionResponse}
     */
    function applyUpdateBccRecipientsAction() {
      // Get the new Bcc recipients of the email.
      // This function is not shown in this example.
      var bccRecipients = getBccRecipients();
      var response = CardService.newUpdateDraftActionResponseBuilder()
          .setUpdateDraftBccRecipientsAction(CardService.newUpdateDraftBccRecipientsAction()
              .addUpdateToRecipients(bccRecipients))
          .build();
      return response;
    }

Exemplo 2

O snippet de código a seguir mostra como criar uma IU do Compose que insere imagens no e-mail de rascunho atual.

    /**
     * Compose trigger function that fires when the compose UI is
     * requested. Builds and returns a compose UI for inserting images.
     *
     * @param {event} e The compose trigger event object. Not used in
     *         this example.
     * @return {Card[]}
     */
    function getInsertImageComposeUI(e) {
      return [buildImageComposeCard()];
    }

    /**
     * Build a card to display images from a third-party source.
     *
     * @return {Card}
     */
    function buildImageComposeCard() {
      // Get a short list of image URLs to display in the UI.
      // This function is not shown in this example.
      var imageUrls = getImageUrls();

      var card = CardService.newCardBuilder();
      var cardSection = CardService.newCardSection().setHeader('My Images');
      for (var i = 0; i < imageUrls.length; i++) {
        var imageUrl = imageUrls[i];
        cardSection.addWidget(
            CardService.newImage()
                .setImageUrl(imageUrl)
                .setOnClickAction(CardService.newAction()
                      .setFunctionName('applyInsertImageAction')
                      .setParameters({'url' : imageUrl})));
      }
      return card.addSection(cardSection).build();
    }

    /**
     * Adds an image to the current draft email when the image is clicked
     * in the compose UI. The image is inserted at the current cursor
     * location. If any content of the email draft is currently selected,
     * it is deleted and replaced with the image.
     *
     * Note: This is not the compose action that builds a compose UI, but
     * rather an action taken when the user interacts with the compose UI.
     *
     * @param {event} e The incoming event object.
     * @return {UpdateDraftActionResponse}
     */
    function applyInsertImageAction(e) {
      var imageUrl = e.parameters.url;
      var imageHtmlContent = '<img style=\"display: block\" src=\"'
           + imageUrl + '\"/>';
      var response = CardService.newUpdateDraftActionResponseBuilder()
          .setUpdateDraftBodyAction(CardService.newUpdateDraftBodyAction()
              .addUpdateContent(
                  imageHtmlContent,
                  CardService.ContentType.MUTABLE_HTML)
              .setUpdateType(
                  CardService.UpdateDraftBodyType.IN_PLACE_INSERT))
          .build();
      return response;
    }