Универсальные действия

Универсальные действия — это элементы меню, которые позволяют пользователю открывать новую веб-страницу, отображать новые карточки пользовательского интерфейса или запускать определенную функцию сценария приложения при выборе. По действию они очень похожи на карточные действия , за исключением того, что универсальные действия всегда размещаются на каждой карточке вашего дополнения, независимо от текущего контекста дополнения.

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

  • Откройте веб-страницу настроек (или отобразите карточку настроек).
  • Показать справочную информацию пользователю.
  • Запустите новый рабочий процесс, например «Добавить нового клиента».
  • Отобразите карточку, которая позволяет пользователю отправить отзыв о надстройке.

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

Использование универсальных действий

Универсальные действия настраиваются в манифесте проекта вашей надстройки. После настройки универсального действия оно всегда будет доступно пользователям вашего дополнения. Если пользователь просматривает карточку, набор универсальных действий, которые вы определ��ли, всегда отображается в меню карточки после любых действий с карточкой, определенных вами для этой карточки. Универсальные действия появляются в меню карточек в том же порядке, в котором они определены в манифесте дополнения.

Настройка универсальных действий

Вы настраиваете универсальные действия в манифесте вашего дополнения; более подробную информацию см. в разделе «Манифесты» .

Для каждого действия вы указываете текст, который должен появиться в меню этого действия. Затем вы можете указать поле openLink , указывающее, что действие должно напрямую открывать веб-страницу на новой вкладке. Альтернативно вы можете указать поле runFunction , в котором указывается функция обратного вызова Apps Script, которая будет выполняться при выборе универсального действия.

При использовании runFunction указанная функция обратного вызова обычно выполняет одно из следующих действий:

  • Создает карты пользовательского интерфейса для немедленного отображения, возвращая построенный объект UniversalActionResponse .
  • Открывает URL-адрес, возможно, после выполнения других задач, возвращая встроенный объект UniversalActionResponse .
  • Выполняет фоновые задачи, при которых не происходит переключение на новую карточку или открытие URL-адреса. В этом случае функция обратного вызова ничего не возвращает.

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

Пример

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

  "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"
        }
      ]
    },
    ...
  },
  ...

Три универсальных действия, определенные в предыдущем примере, выполняют следующие действия:

  • Открытие google.com открывает https://www.google.com в новой вкладке.
  • Открыть URL-адрес контакта запускает функцию, которая определяет, какой URL-адрес открыть, а затем открывает его на новой вкладке с помощью объекта OpenLink . Код создает URL-адрес, используя адрес электронной почты отправителя.
  • Открытие настроек запускает функцию createSettingsCards() определенную в проекте дополнительного скрипта. Эта функция возвращает действительный объект UniversalActionResponse , содержащий набор карточек с настройками надстройки и другой информацией. После того, как функция завершит построение этого объекта, пользовательский интерфейс отобразит список карточек (см. Возврат нескольких карточек ).
  • Запустить фоновую синхронизацию запускает функцию runBackgroundSync() определенную в проекте дополнительного скрипта. Эта функция не строит карты; вместо этого он выполняет некоторые другие фоновые задачи, которые не меняют пользовательский интерфейс. Поскольку функция не возвращает UniversalActionResponse , пользовательский интерфейс не отображает новую карточку после завершения функции. Вместо этого пользовательский интерфейс отображает индикатор загрузки во время работы функции.

Вот пример того, как вы можете создать функции openContactURL() , createSettingsResponse() и 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.
}