Расширение пользовательского интерфейса компоновки с помощью действий компоновки

Помимо предоставления интерфейса на основе карточек, когда пользователь читает сообщение Gmail, надстройки Google Workspace, расширяющие Gmail, могут предоставлять еще один интерфейс, когда пользователь составляет новые сообщения или отвечает на существующие. Это позволяет надстройкам Google Workspace автоматизировать задачу составления электронных писем для пользователя.

Доступ к пользовательскому интерфейсу создания надстройки

Существует два способа просмотра пользовательского интерфейса создания надстройки. Первый способ — начать писать новый черновик или ответ, пока дополнение уже открыто. Второй способ — запустить дополнение во время составления черновика.

В любом случае надстройка выполняет соответствующую триггерную функцию составления , определенную в манифесте надстройки. Функция триггера создания сообщения создает пользовательский интерфейс создания сообщения для этого действия, который Gmail затем отображает пользователю.

Создание дополнения для создания сообщений

Вы можете добавить функцию создания сообщения в надстройку, выполнив следующие общие шаги:

  1. Добавьте поле gmail.composeTrigger в манифест проекта дополнительного скрипта и обновите области манифеста, включив в них те, которые необходимы для действий создания.
  2. Реализуйте функцию триггера создания, которая создает пользовательский интерфейс создания при срабатывании триггера. Триггерные функции Compose возвращают либо один объект Card , либо массив объектов Card , которые составляют пользовательский интерфейс создания для действия создания.
  3. Реализуйте связанные функции обратного вызова, необходимые для реагирования на действия пользователя в пользовательском интерфейсе. Эти функции не являются самим действием создания (которое только вызывает появление пользовательского интерфейса создания); скорее, это отдельные функции, которые управляют тем, что происходит, когда выбираются различные элементы пользовательского интерфейса создания. Например, карта пользовательского интерфейса, содержащая кнопку, обычно имеет связанную с ней функцию обратного вызова, которая выполняется, когда пользователь нажимает эту кнопку. Функция обратного вызова для виджетов, которые обновляют содержимое черновика сообщения, должна возвращать объект UpdateDraftActionResponse .

Создать триггерную функцию

Пользовательский интерфейс создания надстройки построен так же, как и пользовательский интерфейс сообщения надстройки: для создания карточек и заполнения их виджетами используется служба Apps Script Card .

Вы должны реализовать функцию gmail.composeTrigger.selectActions[].runFunction , которую вы определяете в своем манифесте. Триггерная функция создания должна возвращать либо один объект Card , либо массив объектов Card , которые составляют пользовательский интерфейс создания для этого действия. Эти функции очень похожи на контекстные триггерные функции и должны создавать карты таким же образом.

Создание объектов событий триггера

Когда выбрано действие создания, оно выполняет соответствующую триггерную функцию создания и передает функции объект события в качестве параметра. Объект события может передавать в триггерную функцию информацию о контексте надстройки и создаваемом черновике.

См. «Структура объекта события» для получения подробной информации о том, как информация устроена в объекте события. Информация, содержащаяся в объекте события, частично контролируется значением поля манифеста gmail.composeTrigger.draftAccess :

  • Если поле манифеста gmail.composeTrigger.draftAccess имеет NONE или не включено, объект события содержит лишь минимальную информацию.

  • Если gmail.composeTrigger.draftAccess установлено значение METADATA , объект события, передаваемый триггерной функции составления, заполняется списками получателей создаваемого электронного письма.

Вставка контента в активные черновики

Обычно пользовательский интерфейс создания надстройки Google Workspace предоставляет пользователю параметры и элементы управления, которые помогают составить сообщение. В этих случаях использования, как только пользователь сделал выбор в пользовательском интерфейсе, надстройка интерпретирует выбор и соответствующим образом обновляет текущий рабочий черновик электронного письма.

Чтобы упростить обновление текущего черновика электронного письма, сервис Card был расширен следующими классами:

  • ContentType — перечисление, определяющее, следует ли добавлять изменяемый HTML, неизменяемый HTML (который пользователи Gmail не могут редактировать) или обычный текстовый контент.
  • UpdateDraftActionResponse — представляет ответ на действие, которое обновляет текущий черновик электронного письма.
  • UpdateDraftActionResponseBuilder — Построитель объектов UpdateDraftActionResponse .
  • UpdateDraftBodyAction — представляет действие, которое обновляет тело текущего черновика электронного письма.
  • UpdateDraftBodyType — Перечисление, определяющее способ изменения тела.
  • UpdateDraftSubjectAction — представляет действие, которое обновляет поле темы текущего черновика электронного письма.
  • UpdateDraftToRecipientsAction — представляет действие, которое обновляет поле «Кому» текущего черновика электронного письма.
  • UpdateDraftCcRecipientsAction — представляет действие, которое обновляет получателей копии текущего черновика электронного письма.
  • UpdateDraftBccRecipientsAction — представляет действие, которое обновляет получателей скрытой копии текущего черновика электронного письма.

Обычно пользовательский интерфейс создания надстройки включает виджет «Сохранить» или «Вставить», который пользователь может щелкнуть, чтобы указать, что он закончил делать выбор в пользовательском интерфейсе и хочет, чтобы этот выбор был добавлен в создаваемое им электронное письмо. Чтобы добавить эту интерактивность , с виджетом должен быть связан объект Action , который инструктирует надстройку запускать определенную функцию обратного вызова при нажатии на виджет. Вы должны реализовать эти функции обратного вызова. Каждая функция обратного вызова должна возвращать встроенный объект UpdateDraftActionResponse , в котором подробно описаны изменения, которые необходимо внести в текущий черновик электронного письма.

Пример 1

В следующем фрагменте кода показано, как создать пользовательский интерфейс создания, который обновляет тему, а также получателей «Кому», «Копия» и «СК» текущего черновика электронного письма.

    /**
     * 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;
    }

Пример 2

В следующем фрагменте кода показано, как создать пользовательский интерфейс создания, который вставляет изображения в текущий черновик электронного письма.

    /**
     * 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;
    }