Neste guia, explicamos como validar uma variável de entrada.
Ao definir uma variável de entrada, valide se o usuário insere um valor adequado. Por exemplo, se você pedir ao usuário para inserir um
numeral, verifique se ele inseriu 1 em vez de a para garantir que a etapa
seja executada sem erros.
Há duas maneiras de validar uma variável de entrada:
- Validação do lado do cliente: com a validação do lado do cliente, você verifica a entrada do usuário diretamente no dispositivo dele. O usuário recebe feedback imediato e pode corrigir erros na entrada ao configurar a etapa.
- Validação do lado do servidor: permite executar a lógica no servidor durante a validação, o que é útil quando você precisa pesquisar informações que o cliente não tem, como dados em outros sistemas ou bancos de dados.
Validação do lado do cliente
Há duas maneiras de implementar a validação do lado do cliente:
- Para validação básica, como verificar se um widget contém menos de um determinado número de caracteres ou o símbolo @, invoque a classeValidationdo serviço de card do complemento do Google Workspace.
- Para uma validação robusta, como comparar valores de widgets com outros valores, adicione a validação da Common Expression Language (CEL) aos seguintes widgets de card compatíveis usando CardService.
Invocar a classe Validation
O exemplo a seguir valida se um widget TextInput contém 10 ou menos
caracteres:
Apps Script
const validation = CardService.newValidation().setCharacterLimit('10').setInputType(
    CardService.InputType.TEXT);
Para outras opções de validação, use a validação do CEL.
Validação de CEL
A validação da Common Expression Language (CEL) oferece verificações instantâneas de entrada sem a latência da validação do lado do servidor. Isso é feito ao descarregar as verificações de valor de entrada que não dependem da pesquisa de dados de outros serviços para o lado do cliente.
Você também pode usar a CEL para criar comportamentos de card, como mostrar ou ocultar um widget dependendo do resultado da validação. Esse tipo de comportamento é útil para mostrar ou ocultar uma mensagem de erro que ajuda os usuários a corrigir as entradas.
A criação de uma validação completa da CEL envolve os seguintes componentes:
- ExpressionDatano card: contém a lógica de validação especificada e a lógica de acionamento de widget quando uma das condições definidas é atendida.- Id: um identificador exclusivo do- ExpressionDatano Card atual.
- Expression: a string CEL que define a lógica de validação (por exemplo,- "value1 == value2").
- Conditions: uma lista de condições que contém uma seleção de resultados de validação predefinidos (SUCCESS ou FAILURE). As condições são vinculadas ao- EventActiondo lado do widget por- Triggerscom um- actionRuleIdcompartilhado.
- EventActionno nível do card: ativa as validações de CEL no card e associa o campo- ExpressionDataaos widgets de resultados usando acionadores pós-evento.- actionRuleId: ID exclusivo para este- EventAction.
- ExpressionDataAction: defina como- START_EXPRESSION_EVALUATIONpara indicar que essa ação inicia a avaliação de CEL.
- Trigger: conecta o- Conditionsao- EventActionsdo lado do widget com base no- actionRuleId.
 
 
- EventActionno nível do widget: controla o comportamento do widget de resultado quando a condição de sucesso ou falha é atendida. Por exemplo, um widget de resultado pode ser um- TextParagraphque contém uma mensagem de erro que só fica visível quando a validação falha.- actionRuleId: corresponde ao- actionRuleIdno- Triggerdo lado do cartão.
- CommonWidgetAction: define ações que não envolvem avaliações, como atualizar a visibilidade do widget.- UpdateVisibilityAction: uma ação que atualiza o estado de visibilidade de um widget (VISIBLE ou HIDDEN).
 
 
O exemplo a seguir demonstra como implementar a validação da CEL para verificar se duas entradas de texto são iguais. Uma mensagem de erro será exibida se eles não forem iguais.
- 
          Figura 1:quando a condição failConditioné atendida (as entradas não são iguais), o widget de mensagem de erro é definido comoVISIBLEe aparece.
- 
          Figura 2:quando a successConditioné atendida (as entradas são iguais), o widget de mensagem de erro é definido comoHIDDENe não aparece.
Confira o exemplo de código do aplicativo e o arquivo de manifesto JSON:
Apps Script
function onConfig() {
  // Create a Card
  let card = CardService.newCardBuilder();
  const textInput_1 = CardService.newTextInput()
    .setTitle("Input number 1")
    .setFieldName("value1"); // FieldName's value must match a corresponding ID defined in the inputs[] array in the manifest file.
  const textInput_2 = CardService.newTextInput()
    .setTitle("Input number 2")
    .setFieldName("value2"); // FieldName's value must match a corresponding ID defined in the inputs[] array in the manifest file.
  let sections = CardService.newCardSection()
    .setHeader("Two number equals")
    .addWidget(textInput_1)
    .addWidget(textInput_2);
  // CEL Validation
  // Define Conditions
  const condition_success = CardService.newCondition()
    .setActionRuleId("CEL_TEXTINPUT_SUCCESS_RULE_ID")
    .setExpressionDataCondition(
      CardService.newExpressionDataCondition()
      .setConditionType(
        CardService.ExpressionDataConditionType.EXPRESSION_EVALUATION_SUCCESS));
  const condition_fail = CardService.newCondition()
    .setActionRuleId("CEL_TEXTINPUT_FAILURE_RULE_ID")
    .setExpressionDataCondition(
      CardService.newExpressionDataCondition()
      .setConditionType(
        CardService.ExpressionDataConditionType.EXPRESSION_EVALUATION_FAILURE));
  // Define Card-side EventAction
  const expressionDataAction = CardService.newExpressionDataAction()
    .setActionType(
      CardService.ExpressionDataActionType.START_EXPRESSION_EVALUATION);
  // Define Triggers for each Condition respectively
  const trigger_success = CardService.newTrigger()
    .setActionRuleId("CEL_TEXTINPUT_SUCCESS_RULE_ID");
  const trigger_failure = CardService.newTrigger()
    .setActionRuleId("CEL_TEXTINPUT_FAILURE_RULE_ID");
  const eventAction = CardService.newEventAction()
    .setActionRuleId("CEL_TEXTINPUT_EVALUATION_RULE_ID")
    .setExpressionDataAction(expressionDataAction)
    .addPostEventTrigger(trigger_success)
    .addPostEventTrigger(trigger_failure);
  // Define ExpressionData for the current Card
  const expressionData = CardService.newExpressionData()
    .setId("expData_id")
    .setExpression("value1 == value2") // CEL expression
    .addCondition(condition_success)
    .addCondition(condition_fail)
    .addEventAction(eventAction);
  card = card.addExpressionData(expressionData);
  // Create Widget-side EventActions and a widget to display error message
  const widgetEventActionFail = CardService.newEventAction()
    .setActionRuleId("CEL_TEXTINPUT_FAILURE_RULE_ID")
    .setCommonWidgetAction(
      CardService.newCommonWidgetAction()
      .setUpdateVisibilityAction(
        CardService.newUpdateVisibilityAction()
        .setVisibility(
          CardService.Visibility.VISIBLE)));
  const widgetEventActionSuccess = CardService.newEventAction()
    .setActionRuleId("CEL_TEXTINPUT_SUCCESS_RULE_ID")
    .setCommonWidgetAction(
      CardService.newCommonWidgetAction()
      .setUpdateVisibilityAction(
        CardService.newUpdateVisibilityAction()
        .setVisibility(
          CardService.Visibility.HIDDEN)));
  const errorWidget = CardService.newTextParagraph()
    .setText("The first and second value must match.")
    .setVisibility(CardService.Visibility.HIDDEN) // Initially hidden
    .addEventAction(widgetEventActionFail)
    .addEventAction(widgetEventActionSuccess);
  sections = sections.addWidget(errorWidget);
  card = card.addSection(sections);
  // Build and return the Card
  return card.build();
}
Arquivo de manifesto JSON
{
  "timeZone": "America/Los_Angeles",
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8",
  "addOns": {
    "common": {
      "name": "CEL validation example",
      "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": "actionElement",
          "state": "ACTIVE",
          "name": "CEL Demo",
          "description": "Demonstrates CEL Validation",
          "workflowAction": {
            "inputs": [
              {
                "id": "value1",
                "description": "The first number",
                "cardinality": "SINGLE",
                "dataType": {
                  "basicType": "INTEGER"
                }
              },
              {
                "id": "value2",
                "description": "The second number",
                "cardinality": "SINGLE",
                "dataType": {
                  "basicType": "INTEGER"
                }
              }
            ],
            "onConfigFunction": "onConfig",
            "onExecuteFunction": "onExecute"
          }
        }
      ]
    }
  }
}
Widgets e operações de validação da CEL compatíveis
Widgets de card que oferecem suporte à validação de CEL
Os seguintes widgets são compatíveis com a validação da CEL:
- TextInput
- SelectionInput
- DateTimePicker
Operações de validação de CEL compatíveis
- Operações aritméticas
        - +: adiciona dois números- int64,- uint64ou- double.
- -: subtrai dois números- int64,- uint64ou- double.
- *: multiplica dois números- int64,- uint64ou- double.
- /: divide dois números- int64,- uint64ou- double(divisão inteira).
- %: calcula o módulo de dois números- int64ou- uint64.
- -: nega um número- int64ou- uint64.
 
- Operações lógicas:
        - &&: executa uma operação lógica- ANDem dois valores booleanos.
- ||: executa uma operação lógica- ORem dois valores booleanos.
- !: executa uma operação lógica- NOTem um valor booleano.
 
- Operações de comparação:
        - ==: verifica se dois valores são iguais. Aceita números e listas.
- !=: verifica se dois valores são diferentes. Aceita números e listas.
- <: verifica se o primeiro número- int64,- uint64ou- doubleé menor que o segundo.
- <=: verifica se o primeiro número- int64,- uint64ou- doubleé menor ou igual ao segundo.
- >: verifica se o primeiro número- int64,- uint64ou- doubleé maior que o segundo.
- >=: verifica se o primeiro número- int64,- uint64ou- doubleé maior ou igual ao segundo.
 
- Listar operações:
        - in: verifica se um valor está presente em uma lista. Aceita números, strings e listas aninhadas.
- size: retorna o número de itens em uma lista. Aceita números e listas aninhadas.
 
Cenários de validação CEL sem suporte
- Tamanhos de argumentos incorretos para operações binárias: as operações binárias (por exemplo, add_int64, igual a) exigem exatamente dois argumentos. Fornecer um número diferente de argumentos vai gerar um erro.
- Tamanhos de argumentos incorretos para operações unárias: as operações unárias (por exemplo, negate_int64) exigem exatamente um argumento. Fornecer um número diferente de argumentos vai gerar um erro.
- Tipos não aceitos em operações numéricas: operações numéricas binárias e unárias só aceitam argumentos numéricos. Fornecer outros tipos (por exemplo, booleano) vai gerar um erro.
Validação do servidor
Com a validação do lado do servidor, é possível executar a lógica do lado do servidor especificando o
onSaveFunction() no código da etapa. Quando o usuário sai do card de configuração da etapa, o onSaveFunction() é executado e permite verificar a entrada do usuário.
Se a entrada do usuário for válida, retorne saveWorkflowAction.
Se a entrada do usuário for inválida, retorne um card de configuração que mostre uma mensagem de erro explicando como resolver o problema.
Como a validação do lado do servidor é assíncrona, o usuário só descobre o erro de entrada quando publica o fluxo.
Cada id de entrada validada no arquivo de manifesto precisa corresponder a um name de widget de card no código.
O exemplo a seguir valida se uma entrada de texto do usuário inclui o sinal "@":
Arquivo de manifesto
O trecho do arquivo de manifesto especifica um onSaveFunction() chamado
"onSave":
JSON
{
  "timeZone": "America/Los_Angeles",
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8",
  "addOns": {
    "common": {
      "name": "Server-side validation example",
      "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": "actionElement",
          "state": "ACTIVE",
          "name": "Calculate",
          "description": "Asks the user for an email address",
          "workflowAction": {
            "inputs": [
              {
                "id": "email",
                "description": "email address",
                "cardinality": "SINGLE",
                "required": true,
                "dataType": {
                  "basicType": "STRING"
                }
              }
            ],
            "onConfigFunction": "onConfigCalculate",
            "onExecuteFunction": "onExecuteCalculate",
            "onSaveFunction": "onSave"
          }
        }
      ]
    }
  }
}
Código do aplicativo
O código da etapa inclui uma função chamada onSave(). Ele valida se uma string inserida pelo usuário inclui @. Se sim, salva a etapa do fluxo. Caso contrário, ele retorna um card de configuração com uma mensagem de erro explicando como corrigir o problema.
Apps Script
/**
 * Validates user input asynchronously when the user
 * navigates away from a step's configuration card.
*/
function onSave(event) {
  // "email" matches the input ID specified in the manifest file.
  var email = event.workflow.actionInvocation.inputs["email"];
  // Validate that the email address contains an "@" sign:
  if(email.includes("@")) {
  // If successfully validated, save and proceed.
    return {
      "hostAppAction" : {
        "workflowAction" : {
          "saveWorkflowAction" : {}
        }
      }
    };
  // If the input is invalid, return a card with an error message
  } else {
var card = {
    "sections": [
      {
        "header": "Collect Email",
        "widgets": [
          {
            "textInput": {
              "name": "email",
              "label": "email address",
              "hostAppDataSource" : {
                "workflowDataSource" : {
                  "includeVariables" : true
                }
              }
            }
          },
          {
            "textParagraph": {
              "text": "<b>Error:</b> Email addresses must include the '@' sign.",
              "maxLines": 1
            }
          }
        ]
      }
    ]
  };
  return pushCard(card);
  }
}
Temas relacionados
- Definir uma variável de entrada
- Registrar atividades e erros
- Objeto de evento de fluxos
- Common Expression Language (CEL)