Estender a interface do Compose com ações de escrita

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

Acessar a interface de criação de complementos do Google Workspace

Há duas maneiras de acessar a interface de criação de um complemento. A primeira é começar a escrever um novo rascunho ou responder enquanto o complemento já está aberto. A segunda é iniciar o complemento ao escrever um rascunho.

Em ambos os casos, o complemento executa a função de gatilho de criaçãocorrespondente, definida em o manifesto do complemento. A função de gatilho de criação cria a interface de criação para essa ação, que o Gmail mostra ao usuário.

Criar um complemento de criação

Para adicionar a funcionalidade de criação a um complemento, siga estas etapas gerais:

  1. Adicione o gmail.composeTrigger campo ao projeto de script do complemento manifesto e atualize os escopos do manifesto para incluir aqueles necessários para ações de criação.
  2. Implemente uma função de gatilho de criação que crie uma interface de criação quando o gatilho for acionado. As funções de gatilho de criação retornam um único Card objeto ou uma matriz de Card objetos que formam a interface de criação para a ação de criação.
  3. Implemente as funções de callback associadas necessárias para reagir às interações da interface de criação do usuário. Essas funções não são a ação de criação em si (que só faz com que a interface de criação apareça). Em vez disso, são as funções individuais que regem o que acontece quando diferentes elementos da interface de criação são selecionados. Por exemplo, um card da interface que contém 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 de gatilho de criação

A interface de criação de um complemento é criada da mesma forma que a interface de mensagens do complemento: usando o Apps Script serviço de cards para criar cards e preenchê-los com widgets.

É necessário implementar o gmail.composeTrigger.selectActions[].runFunction definido no manifesto. A função de gatilho de criação precisa retornar um único Card objeto ou uma matriz de Card objetos que formam a interface de criação para essa ação. Essas funções são muito semelhantes a funções de gatilho contextual e precisam criar cards da mesma maneira.

Objetos de evento de gatilho de composição

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

Consulte Estrutura do objeto de evento para 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 gmail.composeTrigger.draftAccess campo de manifesto:

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

  • Se gmail.composeTrigger.draftAccess estiver definido como METADATA, o objeto de evento transmitido para a função de gatilho de criação será preenchido com listas de destinatários do e-mail que está sendo criado. O uso do acesso ao rascunho METADATA exige que o manifesto do complemento inclua o escopo do https://www.googleapis.com/auth/gmail.addons.current.message.metadata Gmail.

Inserir conteúdo em rascunhos ativos

Normalmente, uma interface de criação de complementos oferece opções e controles que ajudam a escrever uma mensagem. Para esses casos de uso, depois que o usuário faz seleções na interface, o complemento interpreta as seleções e atualiza o rascunho de e-mail atual de acordo.

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

Normalmente, uma interface de criação de complementos inclui um widget "Salvar" ou "Inserir" em que um usuário pode clicar para indicar que terminou de fazer seleções na interface e quer que as opções sejam adicionadas ao e-mail que está escrevendo. Para adicionar essa interatividade, o widget precisa ter um objeto Action associado que instrui o complemento a executar uma função de callback específica quando o widget é clicado. É necessário implementar essas funções de callback. Cada função de callback precisa retornar um objeto UpdateDraftActionResponse criado que detalha as mudanças a serem feitas no e-mail de rascunho atual.

Exemplo 1

O snippet de código a seguir mostra como criar uma interface de criação que atualiza o assunto e os destinatários dos campos "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 interface de criação que insere imagens no 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 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;
}