Weryfikowanie zmiennej wejściowej

Z tego przewodnika dowiesz się, jak sprawdzić poprawność zmiennej wejściowej.

Podczas definiowania zmiennej wejściowej sprawdź, czy użytkownik wpisuje odpowiednią wartość. Jeśli na przykład poprosisz użytkownika o wpisanie cyfry, sprawdzenie, czy wpisze on 1 zamiast a, potwierdzi, że krok działa bez błędów.

Zmienną wejściową możesz zweryfikować na 2 sposoby:

  • Weryfikacja po stronie klienta: w przypadku weryfikacji po stronie klienta dane wejściowe użytkownika są weryfikowane bezpośrednio na jego urządzeniu. Użytkownik otrzymuje natychmiastową informację zwrotną i może poprawić wszelkie błędy w danych wejściowych podczas konfigurowania kroku.
  • Weryfikacja po stronie serwera: weryfikacja po stronie serwera umożliwia uruchamianie logiki na serwerze podczas weryfikacji. Jest to przydatne, gdy musisz wyszukać informacje, których klient nie ma, np. dane w innych systemach lub bazach danych.

Weryfikacja po stronie klienta

Weryfikację po stronie klienta można wdrożyć na 2 sposoby:

  • W przypadku podstawowej weryfikacji, np. sprawdzenia, czy widżet zawiera mniej niż określoną liczbę znaków lub czy zawiera symbol @, wywołaj klasę Validation usługi Card dodatku do Google Workspace.
  • Aby przeprowadzić dokładną weryfikację, np. porównać wartości widżetów z wartościami innych widżetów, możesz dodać weryfikację w języku Common Expression Language (CEL) do tych obsługiwanych widżetów kart za pomocą znaku CardService.

Wywołaj klasę Validation.

Poniższy przykład sprawdza, czy widżet TextInput zawiera maksymalnie 10 znaków:

Google Apps Script

const validation = CardService.newValidation().setCharacterLimit('10').setInputType(
    CardService.InputType.TEXT);

Aby uzyskać dodatkowe opcje weryfikacji, użyj weryfikacji CEL.

Weryfikacja CEL

Weryfikacja za pomocą Common Expression Language (CEL) umożliwia natychmiastowe sprawdzanie danych wejściowych bez opóźnień związanych z weryfikacją po stronie serwera. Odciąża ona klienta od sprawdzania wartości wejściowych, które nie zależą od wyszukiwania danych z innych usług.

Możesz też używać CEL do tworzenia zachowań kart, np. wyświetlania lub ukrywania widżetu w zależności od wyniku weryfikacji. Takie zachowanie jest przydatne do wyświetlania lub ukrywania komunikatu o błędzie, który pomaga użytkownikom poprawić wprowadzane dane.

Tworzenie pełnej weryfikacji w języku CEL obejmuje te komponenty:

  • ExpressionData w karcie: zawiera określoną logikę weryfikacji i logikę wywoływania widżetu, gdy zostanie spełniony jeden ze zdefiniowanych warunków.

    • Id: unikalny identyfikator ExpressionData w bieżącej karcie.
    • Expression: ciąg CEL, który definiuje logikę weryfikacji (np. "value1 == value2").
    • Conditions: lista warunków zawierająca wybór wstępnie zdefiniowanych wyników weryfikacji (SUCCESS lub FAILURE). Warunki są powiązane z EventAction po stronie widżetu za pomocą Triggers ze wspólnym actionRuleId.
    • Poziom kartyEventAction: aktywuje weryfikacje CEL na karcie i ExpressionData powiązuje pole z widgetami wyników za pomocą wyzwalaczy po zdarzeniu.
      • actionRuleId: unikalny identyfikator tego EventAction.
      • ExpressionDataAction: ustaw wartość START_EXPRESSION_EVALUATION, aby wskazać, że to działanie rozpoczyna ocenę CEL.
      • Trigger: Łączy ConditionsEventActions po stronie widżetu na podstawie actionRuleId.
  • EventAction na poziomie widżetu: określa działanie widżetu wyników po spełnieniu warunku powodzenia lub niepowodzenia. Widżet wyniku może być na przykład elementem TextParagraph, który zawiera komunikat o błędzie widoczny tylko wtedy, gdy weryfikacja się nie powiedzie.

    • actionRuleId: pasuje do actionRuleIdTrigger po stronie karty.
    • CommonWidgetAction: Określa działania, które nie wymagają oceny, np. aktualizowanie widoczności widżetu.
      • UpdateVisibilityAction: działanie, które aktualizuje stan widoczności widżetu (VISIBLE lub HIDDEN).

Poniższy przykład pokazuje, jak wdrożyć weryfikację za pomocą języka CEL, aby sprawdzić, czy 2 pola tekstowe są równe. Jeśli nie są równe, wyświetli się komunikat o błędzie.

  • Gdy warunek failCondition zostanie spełniony (dane wejściowe nie są równe), widżet komunikatu o błędzie zostanie ustawiony na VISIBLE i pojawi się.
    Ilustracja 1. Gdy warunek failCondition jest spełniony (dane wejściowe nie są równe), widżet komunikatu o błędzie jest ustawiony na VISIBLE i pojawia się.
  • Gdy warunek successCondition zostanie spełniony (dane wejściowe są równe), widżet komunikatu o błędzie zostanie ustawiony na HIDDEN i nie będzie się wyświetlać.
    Ilustracja 2. Gdy warunek successCondition jest spełniony (dane wejściowe są równe), widżet komunikatu o błędzie jest ustawiony na HIDDEN i nie jest wyświetlany.

Oto przykładowy kod aplikacji i plik manifestu JSON:

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

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

Obsługiwane widżety i operacje weryfikacji CEL

Widżety kart obsługujące weryfikację CEL

Walidację CEL obsługują te widżety:

  • TextInput
  • SelectionInput
  • DateTimePicker

Obsługiwane operacje weryfikacji CEL

  • Operacje arytmetyczne
    • +: dodaje 2 liczby int64, uint64 lub double.
    • -: odejmuje od siebie 2 liczby typu int64, uint64 lub double.
    • *: mnoży 2 liczby typu int64, uint64 lub double.
    • /: dzieli dwie liczby int64, uint64 lub double (dzielenie całkowite).
    • %: oblicza resztę z dzielenia dwóch liczb typu int64 lub uint64.
    • -: neguje liczbę int64 lub uint64.
  • Operacje logiczne:
    • &&: wykonuje logiczną operację AND na 2 wartościach logicznych.
    • ||: wykonuje logiczną operację OR na 2 wartościach logicznych.
    • !: wykonuje operację logiczną NOT na wartości logicznej.
  • Operacje porównania:
    • ==: sprawdza, czy dwie wartości są równe. Obsługuje liczby i listy.
    • !=: sprawdza, czy dwie wartości są różne. Obsługuje liczby i listy.
    • <: sprawdza, czy pierwsza liczba int64, uint64 lub double jest mniejsza od drugiej.
    • <=: sprawdza, czy pierwsza liczba int64, uint64 lub double jest mniejsza lub równa drugiej.
    • >: sprawdza, czy pierwsza liczba int64, uint64 lub double jest większa od drugiej.
    • >=: sprawdza, czy pierwsza liczba int64, uint64 lub double jest większa lub równa drugiej.
  • Wyświetlanie listy operacji:
    • in: sprawdza, czy wartość znajduje się na liście. Obsługuje liczby, ciągi znaków i listy zagnieżdżone.
    • size: Zwraca liczbę elementów na liście. Obsługuje liczby i listy zagnieżdżone.

Nieobsługiwane scenariusze weryfikacji CEL

  • Nieprawidłowe rozmiary argumentów w przypadku operacji binarnych: operacje binarne (np. add_int64, równa się) wymagają dokładnie 2 argumentów. Podanie innej liczby argumentów spowoduje błąd.
  • Nieprawidłowe rozmiary argumentów w przypadku operacji jednoargumentowych: operacje jednoargumentowe (np. negate_int64) wymagają dokładnie jednego argumentu. Podanie innej liczby argumentów spowoduje błąd.
  • Nieobsługiwane typy w operacjach numerycznych: binarne i unarne operacje numeryczne akceptują tylko argumenty liczbowe. Podanie innych typów (np. wartości logicznych) spowoduje błąd.

Weryfikacja po stronie serwera

W przypadku weryfikacji po stronie serwera możesz uruchamiać logikę po stronie serwera, określając onSaveFunction() w kodzie kroku. Gdy użytkownik opuści kartę konfiguracji kroku, funkcja onSaveFunction() zostanie uruchomiona i umożliwi Ci sprawdzenie danych wprowadzonych przez użytkownika.

Jeśli dane wejściowe użytkownika są prawidłowe, zwróć saveWorkflowAction.

Jeśli dane wejściowe użytkownika są nieprawidłowe, zwróć kartę konfiguracji, która wyświetla komunikat o błędzie z wyjaśnieniem, jak go rozwiązać.

Weryfikacja po stronie serwera jest asynchroniczna, więc użytkownik może nie wiedzieć o błędzie wejściowym, dopóki nie opublikuje przepływu.

Każdy zweryfikowany element wejściowy id w pliku manifestu musi odpowiadać elementowi name widżetu karty w kodzie.

W tym przykładzie sprawdzamy, czy tekst wpisany przez użytkownika zawiera znak „@”:

Plik manifestu

Fragment pliku manifestu określa funkcję onSaveFunction() o nazwie „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"
          }
        }
      ]
    }
  }
}

Kod aplikacji

Kod kroku zawiera funkcję o nazwie onSave(). Sprawdza, czy wpisany przez użytkownika ciąg znaków zawiera znak @. Jeśli tak, zapisuje krok przepływu. Jeśli nie, zwraca kartę konfiguracji z komunikatem o błędzie, który wyjaśnia, jak go naprawić.

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