Создайте карту конфигурации для шага

В этом руководстве объясняется, как создать карточку конфигурации, которая позволяет пользователям настраивать параметры и вводить данные для определенного шага в Google Workspace Studio.

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

  • Конструктор карточек — интерактивный инструмент, который помогает создавать и определять карточки.
  • Карта в справочной документации по API дополнений Google Workspace.
  • Card Service — это сервис Apps Script, позволяющий скриптам настраивать и создавать карточки.
  • Интерфейсы на основе карточек в документации для разработчиков дополнений Google Workspace.

Некоторые виджеты-карточки обладают специальными функциями и возможностями, специфичными для Workspace Studio, которые подробно описаны в этом руководстве.

Определите конфигурационную карту

Определите конфигурационную карточку как в манифесте Apps Script, так и в коде.

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

Отредактируйте файл манифеста.

В файле манифеста определите workflowElements .

JSON

{
  "timeZone": "America/Los_Angeles",
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8",
  "addOns": {
    "common": {
      "name": "Chat space selector",
      "logoUrl": "https://www.gstatic.com/images/branding/productlogos/gsuite_addons/v6/web-24dp/logo_gsuite_addons_color_1x_web_24dp.png",
      "useLocaleFromApp": true
    },
    "flows": {
      "workflowElements": [
        {
          "id": "actionElement",
          "state": "ACTIVE",
          "name": "Chat space selector",
          "description": "Lets the user select a space from Google  Chat",
          "workflowAction": {
            "inputs": [
              {
                "id": "chooseSpace",
                "description": "Choose a Chat space",
                "cardinality": "SINGLE",
                "dataType": {
                  "basicType": "STRING"
                }
              }
            ],
            "onConfigFunction": "onConfigSpacePicker",
            "onExecuteFunction": "onExecuteSpacePicker"
          }
        }
      ]
    }
  }
}

Отредактируйте код

В коде приложения верните карту.

Apps Script

/**
 * Generates and displays a configuration card to choose a Chat space
 */
function onConfigSpacePicker() {

  const selectionInput = CardService.newSelectionInput()
    .setTitle("First Value")
    .setFieldName("chooseSpace")
    .setType(CardService.SelectionInputType.MULTI_SELECT)
    .setPlatformDataSource(
      CardService.newPlatformDataSource()
        .setHostAppDataSource(
          CardService.newHostAppDataSource()
            .setWorkflowDataSource(
              CardService.newWorkflowDataSource()
                .setIncludeVariables(true)
                .setType(CardService.WorkflowDataSourceType.SPACE)
            )
        )
    );

  const cardSection = CardService.newCardSection()
    .setHeader("Select Chat Space")
    .setId("section_1")
    .addWidget(selectionInput)

  var card = CardService.newCardBuilder()
    .addSection(cardSection)
    .build();

  return card;
}

function onExecuteSpacePicker(e) {
}

Настройте автозаполнение для виджетов ввода.

Для виджетов SelectionInput можно настроить автозаполнение, чтобы помочь пользователям выбирать из списка вариантов. Например, если пользователь начинает вводить Atl в меню, отображающем города США, ваш элемент может автоматически предложить Atlanta до того, как пользователь закончит ввод. Автозаполнение может поддерживать до 100 элементов.

Подсказки автозаполнения могут поступать из следующих источников данных:

  • Автозаполнение на стороне сервера: подсказки формируются из стороннего или внешнего источника данных, который вы определяете.
  • Данные Google Workspace: Предложения формируются на основе данных из источников Google Workspace, таких как пользователи Google Workspace или пространства Google Chat.

Автозаполнение на стороне сервера

Виджет SelectionInput можно настроить таким образом, чтобы он автоматически подсказывал варианты из внешнего источника данных. Например, можно помочь пользователям выбрать потенциальных клиентов из списка в системе управления взаимоотношениями с клиентами (CRM).

Для реализации автозаполнения на стороне сервера необходимо:

  1. Определите источник данных: в виджете SelectionInput добавьте DataSourceConfig , указывающий RemoteDataSource . Эта конфигурация указывает на функцию Apps Script, которая получает подсказки автозаполнения.
  2. Реализуйте функцию автозаполнения: эта функция срабатывает, когда пользователь вводит текст в поле ввода. Функция должна запрашивать данные из внешнего источника на основе ввода пользователя и возвращать список подсказок.

В следующем примере показано, как настроить виджет SelectionInput для автозаполнения на стороне сервера:

Apps Script

// In your onConfig function:
var multiSelect1 =
  CardService.newSelectionInput()
    .setFieldName("value1")
    .setTitle("Server Autocomplete")
    .setType(CardService.SelectionInputType.MULTI_SELECT)
    .setMultiSelectMaxSelectedItems(3)
    .addDataSourceConfig(
      CardService.newDataSourceConfig()
        .setRemoteDataSource(
          CardService.newAction().setFunctionName('getAutocompleteResults')
        )
    )
    .addDataSourceConfig(
      CardService.newDataSourceConfig()
        .setPlatformDataSource(
          CardService.newPlatformDataSource()
            .setHostAppDataSource(
              CardService.newHostAppDataSource()
                .setWorkflowDataSource(
                  CardService.newWorkflowDataSource()
                    .setIncludeVariables(true)
                ))
        )
    );

// ... add widget to card ...

Обработайте запрос автозаполнения.

Функция, указанная в setFunctionName (например, getAutocompleteResults ), получает объект события, когда пользователь вводит текст в поле. Эта функция должна:

  1. Проверьте значение event.workflow.elementUiAutocomplete.invokedFunction , чтобы убедиться, что оно соответствует ожидаемому имени функции.
  2. Получите ввод пользователя из event.workflow.elementUiAutocomplete.query .
  3. Выполните запрос к внешнему источнику данных, используя соответствующий запрос.
  4. Возвращает до 100 предложений в требуемом формате.

В следующем примере показано, как реализовать функцию handleAutocompleteRequest() для возврата подсказок на основе запроса пользователя:

Apps Script

function handleAutocompleteRequest(event) {
  var invokedFunction = event.workflow.elementUiAutocomplete.invokedFunction;
  var query = event.workflow.elementUiAutocomplete.query;

  if (invokedFunction != "getAutocompleteResults" || query == undefined || query == "") {
    return {};
  }

  // Query your data source to get results based on the query
  let autocompleteResponse = AddOnsResponseService.newUpdateWidget()
    .addSuggestion(
      query + " option 1",
      query + "_option1",
      false,
      "https://developers.google.com/workspace/add-ons/images/person-icon.png",
      "option 1 bottom text"
    )
    .addSuggestion(
      query + " option 2",
      query + "_option2",
      false,
      "https://developers.google.com/workspace/add-ons/images/person-icon.png",
      "option 2 bottom text"
    ).addSuggestion(
      query + " option 3",
      query + "_option3",
      false,
      "https://developers.google.com/workspace/add-ons/images/person-icon.png",
      "option 3 bottom text"
    );

  const modifyAction = AddOnsResponseService.newAction()
    .addModifyCard(
      AddOnsResponseService.newModifyCard()
        .setUpdateWidget(autocompleteResponse)
    );

  return AddOnsResponseService.newRenderActionBuilder()
    .setAction(modifyAction)
    .build();
}

// In your onConfig function, handle the autocomplete event
function onConfigAutocompleteTest(event) {
  // Handle autocomplete request
  if (event.workflow && event.workflow.elementUiAutocomplete) {
    return handleAutocompleteRequest(event);
  }

  // ... rest of your card building logic ...
}

Автозаполнение данных в Google Workspace

Также можно заполнять подсказки автозаполнения данными из рабочей среды Google пользователя:

  • Пользователи Google Workspace: заполнение данных о пользователях в рамках одной организации Google Workspace.
  • Пространства Google Chat: Заполните пространства Google Chat, в которых пользователь является участником.

Для настройки этого параметра задайте PlatformDataSource в виджете SelectionInput , указав WorkflowDataSourceType как USER или SPACE .

Apps Script

// User Autocomplete
var multiSelect2 =
  CardService.newSelectionInput()
    .setFieldName("value2")
    .setTitle("User Autocomplete")
    .setType(CardService.SelectionInputType.MULTI_SELECT)
    .setMultiSelectMaxSelectedItems(3)
    .setPlatformDataSource(
      CardService.newPlatformDataSource()
        .setHostAppDataSource(
          CardService.newHostAppDataSource()
            .setWorkflowDataSource(
              CardService.newWorkflowDataSource()
                .setIncludeVariables(true)
                .setType(CardService.WorkflowDataSourceType.USER)
            ))
    );

// Chat Space Autocomplete
var multiSelect3 =
  CardService.newSelectionInput()
    .setFieldName("value3")
    .setTitle("Chat Space Autocomplete")
    .setType(CardService.SelectionInputType.MULTI_SELECT)
    .setMultiSelectMaxSelectedItems(3)
    .setPlatformDataSource(
      CardService.newPlatformDataSource()
        .setHostAppDataSource(
          CardService.newHostAppDataSource()
            .setWorkflowDataSource(
              CardService.newWorkflowDataSource()
                .setIncludeVariables(true)
                .setType(CardService.WorkflowDataSourceType.SPACE)
            ))
    );

Пример: Объединение типов автозаполнения

В следующем примере показана функция onConfig , которая создает карточку с тремя виджетами SelectionInput , демонстрируя автозаполнение на стороне сервера, пользователя и пространства:

JSON

{
  "timeZone": "America/Los_Angeles",
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8",
  "addOns": {
    "common": {
      "name": "Autocomplete Demo",
      "logoUrl": "https://www.gstatic.com/images/icons/material/system/1x/pets_black_48dp.png",
      "useLocaleFromApp": true
    },
    "flows": {
      "workflowElements": [
        {
          "id": "autocomplete_demo",
          "state": "ACTIVE",
          "name": "Autocomplete Demo",
          "description": "Provide autocompletion in input fields",
          "workflowAction": {
            "inputs": [
              {
                "id": "value1",
                "description": "A multi-select field with autocompletion",
                "cardinality": "SINGLE",
                "dataType": {
                  "basicType": "STRING"
                }
              }
            ],
            "onConfigFunction": "onConfigAutocomplete",
            "onExecuteFunction": "onExecuteAutocomplete"
          }
        }
      ]
    }
  }
}

Apps Script

function onConfigAutocompleteTest(event) {
  // Handle autocomplete request
  if (event.workflow && event.workflow.elementUiAutocomplete) {
    return handleAutocompleteRequest(event);
  }

  // Server-side autocomplete widget
  var multiSelect1 =
    CardService.newSelectionInput()
      .setFieldName("value1")
      .setTitle("Server Autocomplete")
      .setType(CardService.SelectionInputType.MULTI_SELECT)
      .setMultiSelectMaxSelectedItems(3)
      .addDataSourceConfig(
        CardService.newDataSourceConfig()
          .setRemoteDataSource(
            CardService.newAction().setFunctionName('getAutocompleteResults')
          )
      )
      .addDataSourceConfig(
        CardService.newDataSourceConfig()
          .setPlatformDataSource(
            CardService.newPlatformDataSource()
              .setHostAppDataSource(
                CardService.newHostAppDataSource()
                  .setWorkflowDataSource(
                    CardService.newWorkflowDataSource()
                      .setIncludeVariables(true)
                  ))
          )
      );

  // User autocomplete widget
  var multiSelect2 =
    CardService.newSelectionInput()
      .setFieldName("value2")
      .setTitle("User Autocomplete")
      .setType(CardService.SelectionInputType.MULTI_SELECT)
      .setMultiSelectMaxSelectedItems(3)
      .setPlatformDataSource(
        CardService.newPlatformDataSource()
          .setHostAppDataSource(
            CardService.newHostAppDataSource()
              .setWorkflowDataSource(
                CardService.newWorkflowDataSource()
                  .setIncludeVariables(true)
                  .setType(CardService.WorkflowDataSourceType.USER)
              ))
      );

  // Space autocomplete widget
  var multiSelect3 =
    CardService.newSelectionInput()
      .setFieldName("value3")
      .setTitle("Chat Space Autocomplete")
      .setType(CardService.SelectionInputType.MULTI_SELECT)
      .setMultiSelectMaxSelectedItems(3)
      .setPlatformDataSource(
        CardService.newPlatformDataSource()
          .setHostAppDataSource(
            CardService.newHostAppDataSource()
              .setWorkflowDataSource(
                CardService.newWorkflowDataSource()
                  .setIncludeVariables(true)
                  .setType(CardService.WorkflowDataSourceType.SPACE)
              ))
      );

  var sectionBuilder =
    CardService.newCardSection()
      .addWidget(multiSelect1)
      .addWidget(multiSelect2)
      .addWidget(multiSelect3);

  var card =
    CardService.newCardBuilder()
      .addSection(sectionBuilder)
      .build();
  return card;
}

function handleAutocompleteRequest(event) {
  var invokedFunction = event.workflow.elementUiAutocomplete.invokedFunction;
  var query = event.workflow.elementUiAutocomplete.query;

  if (invokedFunction != "getAutocompleteResults" || query == undefined || query == "") {
    return {};
  }

  // Query your data source to get results
  let autocompleteResponse = AddOnsResponseService.newUpdateWidget()
    .addSuggestion(
      query + " option 1",
      query + "_option1",
      false,
      "https://developers.google.com/workspace/add-ons/images/person-icon.png",
      "option 1 bottom text"
    )
    .addSuggestion(
      query + " option 2",
      query + "_option2",
      false,
      "https://developers.google.com/workspace/add-ons/images/person-icon.png",
      "option 2 bottom text"
    ).addSuggestion(
      query + " option 3",
      query + "_option3",
      false,
      "https://developers.google.com/workspace/add-ons/images/person-icon.png",
      "option 3 bottom text"
    );

  const modifyAction = AddOnsResponseService.newAction()
    .addModifyCard(
      AddOnsResponseService.newModifyCard()
        .setUpdateWidget(autocompleteResponse)
    );

  return AddOnsResponseService.newRenderActionBuilder()
    .setAction(modifyAction)
    .build();
}

Настройка кнопок выбора переменных

Вы можете настроить кнопку выбора переменных, задав размер кнопки и подпись.

Размер пуговицы

Чтобы задать размер кнопки, используйте setVariableButtonSize() с одним из следующих перечислений VariableButtonSize :

  • UNSPECIFIED : Значение по умолчанию. Кнопка отображается в компактном виде на боковой панели и в полноразмерном режиме в других контекстах.
  • COMPACT : На кнопке отображается только знак плюс (+).
  • FULL_SIZE : Кнопка отображает полный текст метки.

Метка кнопки

Для установки текста кнопки используйте setVariableButtonLabel() .

Пример: Настройка средства выбора переменных

В следующем примере показано, как настроить виджеты TextInput с кнопками выбора разных размеров и пользовательской меткой.

  • Настройка кнопок выбора переменных в веб-интерфейсе.
    Рисунок 1: Настройка кнопки выбора переменных в веб-версии.
  • Возможность настройки кнопок выбора переменных в дополнительной боковой панели.
    Рисунок 2: Настройка кнопок выбора переменных в дополнительной боковой панели.

Вот файл манифеста для настройки кнопок выбора переменных:

JSON

{
  "timeZone": "America/Los_Angeles",
  "dependencies": {},
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8",
  "oauthScopes": [
    "https://www.googleapis.com/auth/script.locale"
  ],
  "addOns": {
    "common": {
      "name": "Variable button customization",
      "logoUrl": "https://www.gstatic.com/images/icons/material/system/1x/pets_black_48dp.png",
      "useLocaleFromApp": true
    },
    "flows": {
      "workflowElements": [
        {
          "id": "variable_picker_customization",
          "state": "ACTIVE",
          "name": "Variable Picker demo",
          "description": "List all possible variable picker customization options",
          "workflowAction": {
            "onConfigFunction": "onUpdateCardConfigFunction",
            "onExecuteFunction": "onUpdateCardExecuteFunction"
          }
        }
      ]
    }
  }
}

Вот код для настройки кнопок выбора переменных:

Apps Script

function onUpdateCardConfigFunction(event) {
  const textInput1 = CardService.newTextInput()
    .setFieldName("value1")
    .setTitle("Regular variable picker button")
    .setHostAppDataSource(
      CardService.newHostAppDataSource().setWorkflowDataSource(
        CardService.newWorkflowDataSource()
          .setIncludeVariables(true)
          .setVariableButtonSize(CardService.VariableButtonSize.UNSPECIFIED)
      )
    );

  const textInput2 = CardService.newTextInput()
    .setFieldName("value2")
    .setTitle("Size: Unspecified")
    .setHostAppDataSource(
      CardService.newHostAppDataSource().setWorkflowDataSource(
        CardService.newWorkflowDataSource()
          .setIncludeVariables(true)
          .setVariableButtonSize(CardService.VariableButtonSize.UNSPECIFIED)
      )
    );

  const textInput3 = CardService.newTextInput()
    .setFieldName("value3")
    .setTitle("Size: Full size")
    .setHostAppDataSource(
      CardService.newHostAppDataSource().setWorkflowDataSource(
        CardService.newWorkflowDataSource()
          .setIncludeVariables(true)
          .setVariableButtonSize(CardService.VariableButtonSize.FULL_SIZE)
      )
    );

  const textInput4 = CardService.newTextInput()
    .setFieldName("value4")
    .setTitle("Size: Compact")
    .setHostAppDataSource(
      CardService.newHostAppDataSource().setWorkflowDataSource(
        CardService.newWorkflowDataSource()
          .setIncludeVariables(true)
          .setVariableButtonSize(CardService.VariableButtonSize.COMPACT)
      )
    );

  const textInput5 = CardService.newTextInput()
    .setFieldName("value5")
    .setTitle("Custom button label")
    .setHostAppDataSource(
      CardService.newHostAppDataSource().setWorkflowDataSource(
        CardService.newWorkflowDataSource()
          .setIncludeVariables(true)
          .setVariableButtonLabel("New button label!")
      )
    );

  var cardSection = CardService.newCardSection()
    .addWidget(textInput1)
    .addWidget(textInput2)
    .addWidget(textInput3)
    .addWidget(textInput4)
    .addWidget(textInput5)
    .setId("section_1");

  var card = CardService.newCardBuilder().addSection(cardSection).build();

  return card;
}

function onUpdateCardExecuteFunction(event) {
}

Функции, специфичные для Workspace Studio

Некоторые виджеты-карточки обладают специальными функциями и возможностями, специфичными для Workspace Studio, подробно описанными здесь.

TextInput и SelectionInput

Виджеты TextInput и SelectionInput обладают следующими функциями, специфичными для Workspace Studio:

  • includeVariables : Логическое свойство, позволяющее пользователям выбирать переменные из предыдущих шагов. Для отображения средства выбора переменных на последующих шагах, как начальное событие, так и как минимум одна соответствующая выходная переменная должны соответствовать выбранной переменной.
  • type : Перечисляемое значение, которое автоматически дополняет подсказки. Поддерживаемые значения:
    • USER : Предоставляет подсказки для автозаполнения для людей из контактов пользователя.
    • SPACE : Предоставляет подсказки для автозаполнения в чатах Google, участником которых является пользователь.

Если заданы параметры includeVariables и type , поле ввода объединяет их возможности. Пользователи могут выбрать переменную соответствующего type из выпадающего меню и увидеть подсказки автозаполнения.

  • Подсказки автозаполнения для пространства Google Chat.
    Рисунок 3: Пользователь просматривает подсказки автозаполнения при выборе пространства.
  • Меню переменных позволяет пользователям выбирать выходные переменные из предыдущих шагов.
    Рисунок 4: Пользователь выбирает выходную переменную предыдущего шага из выпадающего списка «Переменные».

Выберите только одну выходную переменную с помощью меню переполнения.

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

Если установить для SelectionInputType значение OVERFLOW_MENU , виджет будет выступать в качестве специального средства выбора переменных. В отличие от использования includeVariables с TextInput , которое преобразует значения переменных в строки, OVERFLOW_MENU сохраняет исходный тип данных выбранной переменной.

Apps Script

const selectionInput = CardService.newSelectionInput()
  .setFieldName("variable_picker_1")
  .setTitle("Variable Picker")
  .setType(
    CardService.SelectionInputType.OVERFLOW_MENU
  );

Позвольте пользователям объединять текст и выходные переменные.

Вы можете настроить виджеты TextInput для управления взаимодействием пользователей с текстом и выводом переменных с помощью setInputMode() .

  • RICH_TEXT : Позволяет пользователям объединять текст и выходные переменные. В результате получается единая объединенная строка.
  • PLAIN_TEXT : Ограничивает ввод. Пользователи могут либо вводить текст, либо выбирать одну выходную переменную. Выбор переменной заменяет любой существующий текст. Используйте этот режим для принудительного использования определенных типов данных, определенных в манифесте.

На следующем изображении показаны два виджета TextInput . Первый настроен как RICH_TEXT и содержит текст и переменную вывода. Второй настроен как PLAIN_TEXT и допускает только переменную вывода.

  • Виджеты ввода текста настроены как RICH_TEXT и PLAIN_TEXT.
    Рисунок 5: Виджеты ввода текста, настроенные как RICH_TEXT и PLAIN_TEXT .

Мы рекомендуем явно задавать режим ввода для всех виджетов TextInput .

Вот файл манифеста для настройки виджетов TextInput с различными режимами ввода:

JSON

{
  "timeZone": "America/Toronto",
  "dependencies": {},
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8",
  "addOns": {
    "common": {
      "name": "Text and output variable demo",
      "logoUrl": "https://www.gstatic.com/images/icons/material/system/1x/pets_black_48dp.png",
      "useLocaleFromApp": true
    },
    "flows": {
      "workflowElements": [
        {
          "id": "richTextDemo",
          "state": "ACTIVE",
          "name": "Rich Text Demo",
          "description": "Show the difference between rich text and plain text TextInput widgets",
          "workflowAction": {
            "inputs": [
              {
                "id": "value1",
                "description": "First user input",
                "cardinality": "SINGLE",
                "dataType": {
                  "basicType": "STRING"
                }
              },
              {
                "id": "value2",
                "description": "Second user input",
                "cardinality": "SINGLE",
                "dataType": {
                  "basicType": "STRING"
                }
              }
            ],
            "onConfigFunction": "onConfiguration",
            "onExecuteFunction": "onExecution"
          }
        }
      ]
    }
  }
}

Вот код для настройки виджетов TextInput с различными режимами ввода:

Apps Script

function onConfiguration() {
  const input1 = CardService.newTextInput()
    .setFieldName("value1")
    .setId("value1")
    .setTitle("Rich Text")
    .setHostAppDataSource(
      CardService.newHostAppDataSource()
        .setWorkflowDataSource(
          CardService.newWorkflowDataSource()
            .setIncludeVariables(true)
        )
    )
    // Set input mode to RICH_TEXT to allow mixed text and variables.
    .setInputMode(CardService.TextInputMode.RICH_TEXT);

  const input2 = CardService.newTextInput()
    .setFieldName("value2")
    .setId("value2")
    .setTitle("Plain text")
    .setHostAppDataSource(
      CardService.newHostAppDataSource()
        .setWorkflowDataSource(
          CardService.newWorkflowDataSource()
            .setIncludeVariables(true)
        )
    )
    // Set input mode to PLAIN_TEXT to enforce single variable selection.
    .setInputMode(CardService.TextInputMode.PLAIN_TEXT);

  const section = CardService.newCardSection()
    .addWidget(input1)
    .addWidget(input2);

  const card = CardService.newCardBuilder()
    .addSection(section)
    .build();

  return card;
}

function onExecution(e) {
}

Особенности и ограничения использования карты

  • Функции навигации по карточкам, такие как popCard() , pushCard() и updateCard() , не поддерживаются в дополнениях, расширяющих функциональность Workspace Studio.

  • При использовании SelectionInput в элементе выбора переменных виджеты поддерживают только "type": "MULTI_SELECT" . В других местах конфигурационных карточек SelectionInput поддерживает все значения SelectionType .