Recopila datos con una variable de entrada

En esta guía, se explica cómo crear una variable de entrada.

Para ejecutarse, los pasos requieren cierta información. Por ejemplo, para enviar un correo electrónico, se requiere una dirección de correo electrónico. Para proporcionar esta información necesaria, define variables de entrada. Una vez definidas, las variables de entrada suelen ser establecidas por el usuario en la tarjeta de configuración de un paso mientras el usuario configura el paso.

Define la variable de entrada en dos lugares: el archivo de manifiesto del complemento y en el código con una tarjeta de configuración en la que los usuarios pueden ingresar valores para las variables de entrada.

Cómo definir la variable de entrada en el archivo de manifiesto

En el archivo de manifiesto, especifica las variables de entrada con el array inputs[]. Cada elemento del array inputs[] tiene estas propiedades:

  • id: Es el identificador único de una variable de entrada. Para permitir que el flujo asocie un elemento de entrada de la tarjeta de configuración con esta variable de entrada, debe coincidir con el nombre del elemento de tarjeta correspondiente.
  • description: Es una descripción de la variable de entrada que se mostrará a los usuarios finales.
  • cardinality: Cantidad de valores permitidos. Los valores posibles son los siguientes:
    • SINGLE: Solo se permite un valor.
  • dataType: Es el tipo de valores aceptados. dataType tiene la propiedad basicType, que define el tipo de datos. Estos son algunos de los valores válidos:
    • STRING: Es una cadena alfanumérica.
    • INTEGER: Es un número.
    • TIMESTAMP: Es una marca de tiempo en formato de "milisegundos desde la época de Unix". Por ejemplo, el 27 de noviembre de 2025 a las 16:49:02 UTC se representa como 1764262142988.
    • BOOLEAN: Puede ser verdadero o falso.
    • EMAIL_ADDRESS: Una dirección de correo electrónico en el formato dana@example.com

En el siguiente ejemplo, se definen tres variables de entrada para un paso de calculadora. Las primeras dos variables de entrada son números enteros y la tercera es una operación 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"
          }
        }
      ]
    }
  }
}

Cómo definir la variable de entrada en el código

El código del paso incluye una función llamada onConfigFunction() que devuelve una tarjeta de configuración que define un widget de tarjeta de entrada para cada variable de entrada definida en el array inputs[] del archivo de manifiesto.

Los widgets de entrada definidos en la tarjeta de configuración tienen los siguientes requisitos:

  • El name de cada widget de entrada debe coincidir con el id de la variable de entrada correspondiente en el archivo de manifiesto.
  • La cardinalidad del widget de entrada debe coincidir con la cardinality de la variable de entrada en el archivo de manifiesto.
  • El tipo de datos del widget de entrada debe coincidir con el dataType de la variable de entrada en el archivo de manifiesto. Si la variable de entrada tiene un dataType de número entero, no puede contener una cadena.

Para obtener ayuda para crear interfaces de tarjetas, consulta una de las siguientes opciones:

  • Card Builder: Es una herramienta interactiva que puedes usar para crear y definir tarjetas.
  • Card: En la documentación de referencia de la API del complemento de Google Workspace
  • Card Service: Es un servicio de Apps Script que permite que las secuencias de comandos configuren y compilen tarjetas.
  • Descripción general de las interfaces basadas en tarjetas: En la documentación para desarrolladores de complementos de Google Workspace

En el siguiente ejemplo, se muestra una tarjeta de configuración para cada widget de entrada definido en Define la variable de entrada en el archivo de manifiesto.

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

Cómo usar variables de salida de pasos anteriores

Puedes configurar variables de entrada para que acepten variables de salida de pasos anteriores del flujo de trabajo.

Habilita la selección de variables

Para permitir que los usuarios seleccionen variables de pasos anteriores, usa la propiedad includeVariables en los widgets TextInput y SelectionInput.

Los widgets TextInput y SelectionInput tienen estas funciones específicas de Workspace Studio:

  • includeVariables: Es una propiedad booleana que permite a los usuarios seleccionar variables de pasos anteriores. Para que el selector de variables se muestre en pasos posteriores, tanto el evento de inicio como al menos una variable de salida correspondiente deben asignarse a la variable.
  • type: Es un valor enumerado que autocompleta las sugerencias. Entre los valores admitidos, se incluyen los siguientes:
    • USER: Proporciona sugerencias de autocompletar para las personas en los contactos del usuario.
    • SPACE: Proporciona sugerencias de autocompletado para los espacios de Google Chat de los que el usuario es miembro.

Cuando se configuran includeVariables y type, el campo de entrada combina sus experiencias. Los usuarios pueden seleccionar una variable del type coincidente en un menú desplegable y ver sugerencias de autocompletar para ella.

  • Sugerencias de autocompletar para un espacio de Google Chat.
    Figura 4: Un usuario revisa las sugerencias de autocompletado cuando elige un espacio.
  • El menú de variables permite a los usuarios seleccionar variables de salida de los pasos anteriores.
    Figura 5: Un usuario selecciona la variable de resultado de un paso anterior en el menú desplegable ➕ Variables.

Selecciona solo una variable de salida con un menú ampliado

Puedes configurar un widget SelectionInput para permitir que los usuarios seleccionen una sola variable de salida de un paso anterior con un menú de desbordamiento.

Cuando configuras SelectionInputType como OVERFLOW_MENU, el widget funciona como un selector de variables exclusivo. A diferencia del uso de includeVariables con TextInput, que convierte los valores de las variables en cadenas, OVERFLOW_MENU conserva el tipo de datos original de la variable seleccionada.

Apps Script

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

Permitir que los usuarios combinen texto y variables de salida

Puedes configurar widgets de TextInput para controlar cómo los usuarios interactúan con el texto y las variables de salida con setInputMode().

  • RICH_TEXT: Permite a los usuarios combinar texto y variables de salida. El resultado es una sola cadena concatenada.
  • PLAIN_TEXT: Restringe la entrada. Los usuarios pueden escribir texto o seleccionar una sola variable de salida. Si seleccionas una variable, se reemplazará cualquier texto existente. Usa este modo para aplicar tipos de datos específicos definidos en el manifiesto.

En la siguiente imagen, se muestran dos widgets de TextInput. La primera se configura como RICH_TEXT y contiene texto y una variable de salida. El segundo se configura como PLAIN_TEXT y solo permite una variable de salida.

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

Te recomendamos que establezcas de forma explícita el modo de entrada para todos los widgets TextInput.

Este es el archivo de manifiesto para configurar widgets TextInput con 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"
          }
        }
      ]
    }
  }
}

Este es el código para configurar widgets de TextInput con 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) {
}

Personaliza los botones del selector de variables

Puedes personalizar el botón del selector de variables configurando el tamaño y la etiqueta del botón.

Tamaño del botón

Para establecer el tamaño del botón, usa setVariableButtonSize() con una de las siguientes enumeraciones de VariableButtonSize:

  • UNSPECIFIED: Es el valor predeterminado. El botón es compacto en el panel lateral y de tamaño completo en otros contextos.
  • COMPACT: El botón solo muestra un signo más (+).
  • FULL_SIZE: El botón muestra la etiqueta de texto completa.

Etiqueta del botón

Para establecer el texto del botón, usa setVariableButtonLabel().

Ejemplo: Personalización del selector de variables

En el siguiente ejemplo, se muestra cómo configurar widgets TextInput con diferentes tamaños de botones del selector de variables y una etiqueta personalizada.

  • Se personalizó el botón del selector de variables en la Web.
    Figura 1: Personalización del botón del selector de variables en la Web.
  • Personalización del botón del selector de variables en un panel lateral del complemento.
    Figura 2: Personalización del botón del selector de variables en un panel lateral del complemento.

Este es el archivo de manifiesto para personalizar los botones del selector de variables:

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

Este es el código para personalizar los botones del selector de variables:

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

Cómo configurar la función de autocompletar datos de Google Workspace

También puedes propagar sugerencias de autocompletar a partir de los datos del entorno de Google Workspace del usuario:

  • Usuarios de Google Workspace: Se completan los usuarios dentro de la misma organización de Google Workspace.
  • Espacios de Google Chat: Se completan los espacios de Google Chat de los que el usuario es miembro.

Para configurar esto, establece PlatformDataSource en el widget SelectionInput y especifica WorkflowDataSourceType como USER o 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)
            ))
    );

Ejemplo: Combinación de tipos de autocompletado

En el siguiente ejemplo, se muestra una función onConfig que crea una tarjeta con tres widgets SelectionInput, lo que demuestra la función de autocompletar del servidor, del usuario y del espacio:

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

Valida la variable de entrada

Como práctica recomendada, valida que el usuario ingrese un valor adecuado. Consulta Cómo validar una variable de entrada.