Coletar dados com uma variável de entrada

Este guia explica como criar uma variável de entrada.

Para serem executadas, as etapas exigem determinadas informações. Por exemplo, para enviar um e-mail, é necessário um endereço de e-mail. Para fornecer essas informações necessárias, defina variáveis de entrada. Depois de definidas, as variáveis de entrada são geralmente definidas pelo usuário no card de configuração de uma etapa enquanto ele configura a etapa.

Defina a variável de entrada em dois lugares: no arquivo de manifesto do complemento e no código com um card de configuração em que os usuários podem inserir valores para variáveis de entrada.

Definir a variável de entrada no arquivo de manifesto

No arquivo de manifesto, especifique as variáveis de entrada com a matriz inputs[]. Cada item na matriz inputs[] tem estas propriedades:

  • id: identificador exclusivo de uma variável de entrada. Para permitir que o fluxo associe um elemento de entrada de card de configuração a essa variável de entrada, precisa corresponder ao nome do elemento de card correspondente.
  • description: uma descrição da variável de entrada para mostrar aos usuários finais.
  • cardinality: quantos valores são permitidos. Os valores possíveis são:
    • SINGLE: apenas um valor é permitido.
  • dataType: o tipo de valores aceitos. dataType tem a propriedade basicType, que define o tipo de dados. Alguns dos valores válidos são:
    • STRING: uma string alfanumérica.
    • INTEGER: um número.
    • TIMESTAMP: um carimbo de data/hora no formato "milissegundos desde a época Unix". Por exemplo, 27 de novembro de 2025, 16h49min02s UTC é representado como 1764262142988.
    • BOOLEAN: verdadeiro ou falso.
    • EMAIL_ADDRESS: um endereço de e-mail no formato dana@example.com.

O exemplo a seguir define três variáveis de entrada para uma etapa de calculadora. As duas primeiras variáveis de entrada são números inteiros, e a terceira é uma operação aritmética.

JSON

{
  "timeZone": "America/Los_Angeles",
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8",
  "addOns": {
    "common": {
      "name": "Calculator",
      "logoUrl": "https://www.gstatic.com/images/branding/productlogos/calculator_search/v1/web-24dp/logo_calculator_search_color_1x_web_24dp.png",
      "useLocaleFromApp": true
    },
    "flows": {
      "workflowElements": [
        {
          "id": "calculatorDemo",
          "state": "ACTIVE",
          "name": "Calculate",
          "description": "Asks the user for two values and a math operation, then performs the math operation on the values and outputs the result.",
          "workflowAction": {
            "inputs": [
              {
                "id": "value1",
                "description": "value1",
                "cardinality": "SINGLE",
                "dataType": {
                  "basicType": "INTEGER"
                }
              },
              {
                "id": "value2",
                "description": "value2",
                "cardinality": "SINGLE",
                "dataType": {
                  "basicType": "INTEGER"
                }
              },
              {
                "id": "operation",
                "description": "operation",
                "cardinality": "SINGLE",
                "dataType": {
                  "basicType": "STRING"
                }
              }
            ],
            "outputs": [
              {
                "id": "result",
                "description": "Calculated result",
                "cardinality": "SINGLE",
                "dataType": {
                  "basicType": "INTEGER"
                }
              }
            ],
            "onConfigFunction": "onConfigCalculate",
            "onExecuteFunction": "onExecuteCalculate"
          }
        }
      ]
    }
  }
}

Definir a variável de entrada no código

O código da etapa inclui uma função chamada onConfigFunction() que retorna um card de configuração que define um widget de card de entrada para cada variável de entrada definida na matriz inputs[] do arquivo de manifesto.

Os widgets de entrada definidos no cartão de configuração têm os seguintes requisitos:

  • O name de cada widget de entrada precisa corresponder ao id da variável de entrada correspondente no arquivo de manifesto.
  • A cardinalidade do widget de entrada precisa corresponder ao cardinality da variável de entrada no arquivo de manifesto.
  • O tipo de dados do widget de entrada precisa corresponder ao dataType da variável de entrada no arquivo de manifesto. Se a variável de entrada tiver um dataType de número inteiro, ela não poderá conter uma string.

Para receber ajuda na criação de interfaces de card, consulte uma destas opções:

  • O Card Builder: uma ferramenta interativa que você pode usar para criar e definir cards.
  • Card: na documentação de referência da API de complementos do Google Workspace.
  • Card Service: um serviço do Apps Script que permite que os scripts configurem e criem cards.
  • Visão geral das interfaces baseadas em cards: na documentação para desenvolvedores de complementos do Google Workspace.

O exemplo a seguir retorna um card de configuração para cada widget de entrada definido em Definir a variável de entrada no arquivo de manifesto.

Apps Script

/**
* Generates and displays a configuration card for the sample calculation step.
*
* This function creates a card with input fields for two values and a drop-down
* for selecting an arithmetic operation.
*
* The input fields are configured to let the user select outputs from previous
* workflow steps as input values using the `hostAppDataSource` property.
*/
function onConfigCalculate() {
  const firstInput = CardService.newTextInput()
    .setFieldName("value1") // "FieldName" must match an "id" in the manifest file's inputs[] array.
    .setTitle("First Value")
    .setHostAppDataSource(
      CardService.newHostAppDataSource()
        .setWorkflowDataSource(
          CardService.newWorkflowDataSource()
            .setIncludeVariables(true)
        )
    );

  const secondInput = CardService.newTextInput()
    .setFieldName("value2") // "FieldName" must match an "id" in the manifest file's inputs[] array.
    .setTitle("Second Value")
    .setHostAppDataSource(
      CardService.newHostAppDataSource()
        .setWorkflowDataSource(
          CardService.newWorkflowDataSource()
            .setIncludeVariables(true)
        )
    );

  const selectionInput = CardService.newSelectionInput()
    .setTitle("operation")
    .setFieldName("operation") // "FieldName" must match an "id" in the manifest file's inputs[] array.
    .setType(CardService.SelectionInputType.DROPDOWN)
    .addItem("+", "+", false)
    .addItem("-", "-", true)
    .addItem("x", "x", false)
    .addItem("/", "/", false);

  const sections = CardService.newCardSection()
    .setHeader("Action_sample: Calculate")
    .setId("section_1")
    .addWidget(firstInput)
    .addWidget(selectionInput)
    .addWidget(secondInput)

  let card = CardService.newCardBuilder()
    .addSection(sections)
    .build();

  return card;
}

Usar variáveis de saída de etapas anteriores

É possível configurar variáveis de entrada para aceitar variáveis de saída de etapas anteriores no fluxo de trabalho.

Ativar seleção de variáveis

Para permitir que os usuários selecionem variáveis de etapas anteriores, use a propriedade includeVariables nos widgets TextInput e SelectionInput.

Os widgets TextInput e SelectionInput têm estes recursos específicos do Workspace Studio:

  • includeVariables: uma propriedade booleana que permite aos usuários selecionar variáveis de etapas anteriores. Para que o seletor de variáveis apareça nas etapas posteriores, o evento inicial e pelo menos uma variável de saída correspondente precisam ser mapeados para a variável.
  • type: um valor enumerado que preenche automaticamente as sugestões. Os valores aceitos incluem:
    • USER: oferece sugestões de preenchimento automático para pessoas nos contatos do usuário.
    • SPACE: oferece sugestões de preenchimento automático para espaços do Google Chat de que o usuário participa.

Quando includeVariables e type estão definidos, o campo de entrada combina as experiências deles. Os usuários podem selecionar uma variável do type correspondente em um menu suspenso e conferir sugestões de preenchimento automático.

  • Sugestões de preenchimento automático para um espaço do Google Chat.
    Figura 4:um usuário analisa as sugestões de preenchimento automático ao escolher um espaço.
  • No menu "Variáveis", os usuários podem selecionar variáveis de saída das etapas anteriores.
    Figura 5:um usuário seleciona a variável de saída de uma etapa anterior no menu suspenso ➕Variáveis.

Selecionar apenas uma variável de saída com um menu flutuante

É possível configurar um widget SelectionInput para que os usuários selecionem uma única variável de saída de uma etapa anterior usando um menu de estouro.

Quando você define SelectionInputType como OVERFLOW_MENU, o widget funciona como um seletor de variáveis dedicado. Ao contrário do uso de includeVariables com TextInput, que converte valores de variáveis em strings, o OVERFLOW_MENU preserva o tipo de dados original da variável selecionada.

Apps Script

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

Permitir que os usuários combinem texto e variáveis de saída

É possível configurar widgets TextInput para controlar como os usuários interagem com texto e variáveis de saída usando setInputMode().

  • RICH_TEXT: permite que os usuários combinem texto e variáveis de saída. O resultado é uma única string concatenada.
  • PLAIN_TEXT: restringe a entrada. Os usuários podem digitar texto ou selecionar uma única variável de saída. Ao selecionar uma variável, o texto atual é substituído. Use esse modo para exigir tipos de dados específicos definidos no manifesto.

A imagem a seguir mostra dois widgets TextInput. O primeiro é configurado como RICH_TEXT e tem texto e uma variável de saída. O segundo é configurado como PLAIN_TEXT e permite apenas uma variável de saída.

  • Widgets de entrada de texto configurados como RICH_TEXT e PLAIN_TEXT
    Figura 3:widgets de entrada de texto configurados como RICH_TEXT e PLAIN_TEXT.

Recomendamos que você defina explicitamente o modo de entrada para todos os widgets TextInput.

Confira o arquivo de manifesto para configurar widgets TextInput com diferentes modos de entrada:

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

Confira o código para configurar widgets TextInput com diferentes modos de entrada:

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) {
}

Personalizar botões do seletor de variáveis

É possível personalizar o botão do seletor de variáveis definindo o tamanho e o rótulo dele.

Tamanho do botão

Para definir o tamanho do botão, use setVariableButtonSize() com uma das seguintes enums VariableButtonSize:

  • UNSPECIFIED: o padrão. O botão é compacto no painel lateral e de tamanho normal em outros contextos.
  • COMPACT: o botão mostra apenas um sinal de adição (+).
  • FULL_SIZE: o botão mostra o rótulo de texto completo.

Rótulo do botão

Para definir o texto do botão, use setVariableButtonLabel().

Exemplo: personalização do seletor de variáveis

O exemplo a seguir mostra como configurar widgets TextInput com diferentes tamanhos de botão do seletor de variáveis e um rótulo personalizado.

  • Personalização do botão do seletor de variáveis na Web.
    Figura 1:personalização do botão de seleção de variáveis na Web.
  • Personalização do botão de seleção de variáveis em um painel lateral de complemento.
    Figura 2:personalização do botão de seleção de variáveis em um painel lateral de complemento.

Confira o arquivo de manifesto para personalizar os botões do seletor de variáveis:

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

Confira o código para personalizar os botões do seletor de variáveis:

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) {
}

Configurar o preenchimento automático de dados do Google Workspace

Você também pode preencher sugestões de preenchimento automático com dados do ambiente do Google Workspace do usuário:

  • Usuários do Google Workspace:preencha os usuários na mesma organização do Google Workspace.
  • Espaços do Google Chat:preenche os espaços do Google Chat de que o usuário é membro.

Para configurar isso, defina o PlatformDataSource no widget SelectionInput especificando o WorkflowDataSourceType como USER ou 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)
            ))
    );

Exemplo: combinar tipos de preenchimento automático

O exemplo a seguir mostra uma função onConfig que cria um card com três widgets SelectionInput e demonstra o preenchimento automático do servidor, do usuário e do espaço:

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();
}

Validar a variável de entrada

Como prática recomendada, valide se o usuário inseriu um valor adequado. Consulte Validar uma variável de entrada.