Eingabevariable validieren

In dieser Anleitung wird erklärt, wie Sie eine Eingabevariable validieren.

Wenn Sie eine Eingabevariable definieren, sollten Sie als Best Practice prüfen, ob der Nutzer einen geeigneten Wert eingibt. Wenn Sie den Nutzer beispielsweise bitten, eine Zahl einzugeben, können Sie prüfen, ob er 1 anstelle von a eingibt, um sicherzustellen, dass der Schritt ohne Fehler ausgeführt wird.

Es gibt zwei Möglichkeiten, eine Eingabevariable zu validieren:

  • Clientseitige Validierung: Bei der clientseitigen Validierung wird die Eingabe des Nutzers direkt auf seinem Gerät überprüft. Der Nutzer erhält sofort Feedback und kann Fehler in seiner Eingabe korrigieren, während er den Schritt konfiguriert.
  • Serverseitige Validierung: Bei der serverseitigen Validierung können Sie während der Validierung Logik auf dem Server ausführen. Das ist nützlich, wenn Sie Informationen abrufen müssen, die der Client nicht hat, z. B. Daten in anderen Systemen oder Datenbanken.

Clientseitige Validierung

Es gibt zwei Möglichkeiten, die clientseitige Validierung zu implementieren:

  • Für die grundlegende Validierung, z. B. um zu prüfen, ob ein Widget weniger als eine bestimmte Anzahl von Zeichen enthält oder das Symbol @ enthält, rufen Sie die Klasse Validation des Kartendienstes des Google Workspace-Add-ons auf.
  • Für eine robuste Validierung, z. B. um Widget-Werte mit anderen Widget Werten zu vergleichen, können Sie den folgenden unterstützten Karten-Widgets mit eine CEL-Validierung (Common Expression Language) hinzufügenCardService.

Klasse Validation aufrufen

Im folgenden Beispiel wird geprüft, ob ein TextInput-Widget 10 oder weniger Zeichen enthält:

Apps Script

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

Für zusätzliche Validierungsoptionen verwenden Sie die CEL-Validierung.

CEL-Validierung

Die CEL-Validierung (Common Expression Language) bietet sofortige Eingabeüberprüfungen ohne die Latenz der serverseitigen Validierung, indem Eingabewertprüfungen, die nicht vom Abruf von Daten aus anderen Diensten abhängen, auf die Clientseite ausgelagert werden.

Sie können CEL auch verwenden, um Kartenverhalten zu erstellen, z. B. um ein Widget je nach Ergebnis der Validierung ein- oder auszublenden. Diese Art von Verhalten ist nützlich, um eine Fehlermeldung ein- oder auszublenden, die Nutzern hilft, ihre Eingaben zu korrigieren.

Eine vollständige CEL-Validierung besteht aus den folgenden Komponenten:

  • ExpressionData in der Karte: Enthält die angegebene Validierungslogik und die Widget-Auslösungslogik, wenn eine der definierten Bedingungen erfüllt ist.

    • Id: Eine eindeutige ID für ExpressionData auf der aktuellen Karte.
    • Expression: Der CEL-String, der die Validierungslogik definiert (z. B., "value1 == value2").
    • Conditions: Eine Liste von Bedingungen, die eine Auswahl vordefinierter Validierungsergebnisse (SUCCESS oder FAILURE) enthält. Bedingungen sind über Triggers mit einer gemeinsamen actionRuleId mit der widgetseitigen EventAction verknüpft.
    • EventAction auf Kartenebene: Aktiviert CEL-Validierungen auf der Karte und verknüpft das Feld ExpressionData über Post-Event-Trigger mit Ergebnis-Widgets.
      • actionRuleId: Eindeutige ID für diese EventAction.
      • ExpressionDataAction: Auf START_EXPRESSION_EVALUATION festgelegt, um anzugeben, dass diese Aktion die CEL-Auswertung startet.
      • Trigger: Verknüpft die Conditions basierend auf der actionRuleId mit den widgetseitigen EventActions.
  • EventAction auf Widget-Ebene: Steuert das Verhalten des Ergebnis-Widgets, wenn die Bedingung für Erfolg oder Fehler erfüllt ist. Ein Ergebnis-Widget kann beispielsweise ein TextParagraph sein, der eine Fehlermeldung enthält, die nur angezeigt wird, wenn die Validierung fehlschlägt.

    • actionRuleId: Entspricht der actionRuleId im Trigger auf Kartenebene.
    • CommonWidgetAction: Definiert Aktionen, die keine Auswertungen umfassen, z. B. das Aktualisieren der Widget-Sichtbarkeit.
      • UpdateVisibilityAction: Eine Aktion, die den Sichtbarkeitsstatus eines Widgets aktualisiert (VISIBLE oder HIDDEN).

Im folgenden Beispiel wird gezeigt, wie Sie die CEL-Validierung implementieren, um zu prüfen, ob zwei Texteingaben gleich sind. Wenn sie nicht gleich sind, wird eine Fehlermeldung angezeigt.

  • Die Konfigurationskarte für Workspace Studio mit einer roten Fehlermeldung unter den nicht übereinstimmenden Eingabefeldern.
    Abbildung 1: Wenn die failCondition erfüllt ist (Eingaben sind nicht gleich), wird das Widget für die Fehlermeldung auf VISIBLE gesetzt und angezeigt.
  • Die Workspace Studio-Konfigurationskarte mit übereinstimmenden Eingaben und ohne angezeigte Fehlermeldung.
    Abbildung 2: Wenn die successCondition erfüllt ist (Eingaben sind gleich), wird das Widget für die Fehlermeldung auf HIDDEN gesetzt und nicht angezeigt.

Das folgende Codebeispiel und die JSON-Manifestdatei zeigen:

Apps Script

function onConfig() {
  // Create a Card
  let cardBuilder = CardService.newCardBuilder();

  const textInput_1 = CardService.newTextInput()
    .setTitle("Input field 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 field 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("Enter same values for the two input fields")
    .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("<font color=\"#FF0000\"><b>Error:</b> Please enter the same values for both input fields.</font>")
    .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();
}

JSON-Manifestdatei

{
  "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": "cel_validation_demo",
          "state": "ACTIVE",
          "name": "CEL Demo",
          "description": "Demonstrates CEL Validation",
          "workflowAction": {
            "inputs": [
              {
                "id": "value1",
                "description": "The first number",
                "cardinality": "SINGLE",
                "dataType": {
                  "basicType": "STRING"
                }
              },
              {
                "id": "value2",
                "description": "The second number",
                "cardinality": "SINGLE",
                "dataType": {
                  "basicType": "STRING"
                }
              }
            ],
            "onConfigFunction": "onConfig",
            "onExecuteFunction": "onExecute"
          }
        }
      ]
    }
  }
}

Unterstützte CEL-Validierungs-Widgets und -Vorgänge

Karten-Widgets, die die CEL-Validierung unterstützen

Die folgenden Widgets unterstützen die CEL-Validierung:

  • TextInput
  • SelectionInput
  • DateTimePicker

Unterstützte CEL-Validierungsvorgänge

  • Arithmetische Operationen
    • +: Addiert zwei int64, uint64, oder double-Zahlen.
    • -: Subtrahiert zwei int64, uint64, oder double-Zahlen.
    • *: Multipliziert zwei int64, uint64, oder double-Zahlen.
    • /: Dividiert zwei int64, uint64, oder double-Zahlen (Ganzzahldivision).
    • %: Berechnet den Modulo von zwei int64 oder uint64-Zahlen.
    • -: Negiert eine int64- oder uint64-Zahl.
  • Logische Operationen:
    • &&: Führt eine logische AND-Operation für zwei boolesche Werte aus.
    • ||: Führt eine logische OR-Operation für zwei boolesche Werte aus.
    • !: Führt eine logische NOT-Operation für einen booleschen Wert aus.
  • Vergleichsoperationen:
    • ==: Prüft, ob zwei Werte gleich sind. Unterstützt Zahlen und Listen.
    • !=: Prüft, ob zwei Werte ungleich sind. Unterstützt Zahlen und Listen.
    • <: Prüft, ob die erste int64-, uint64- oder double-Zahl kleiner als die zweite ist.
    • <=: Prüft, ob die erste int64, uint64- oder double-Zahl kleiner oder gleich der zweiten ist.
    • >: Prüft, ob die erste int64, uint64, oder double-Zahl größer als die zweite ist.
    • >=: Prüft, ob die erste int64, uint64- oder double-Zahl größer oder gleich der zweiten ist.
  • Listenoperationen:
    • in: Prüft, ob ein Wert in einer Liste vorhanden ist. Unterstützt Zahlen, Strings und verschachtelte Listen.
    • size: Gibt die Anzahl der Elemente in einer Liste zurück. Unterstützt Zahlen und verschachtelte Listen.

Nicht unterstützte CEL-Validierungsszenarien

  • Falsche Argumentgrößen für binäre Operationen: Für binäre Operationen (z. B. add_int64, „ist gleich“) sind genau zwei Argumente erforderlich. Wenn Sie eine andere Anzahl von Argumenten angeben, wird ein Fehler ausgegeben.
  • Falsche Argumentgrößen für unäre Operationen: Für unäre Operationen (z. B. negate_int64) ist genau ein Argument erforderlich. Wenn Sie eine andere Anzahl von Argumenten angeben, wird ein Fehler ausgegeben.
  • Nicht unterstützte Typen bei numerischen Operationen: Für numerische binäre und unäre Operationen sind nur Zahlenargumente zulässig. Wenn Sie andere Typen angeben (z. B. boolesch), wird ein Fehler ausgegeben.

Serverseitige Validierung

Bei der serverseitigen Validierung können Sie serverseitige Logik ausführen, indem Sie die onSaveFunction im Code Ihres Schritts angeben. Wenn der Nutzer die Konfigurationskarte des Schritts verlässt, wird onSaveFunction ausgeführt und Sie können die Eingabe des Nutzers überprüfen.

Wenn die Eingabe des Nutzers gültig ist, geben Sie saveWorkflowAction zurück.

Wenn die Eingabe des Nutzers ungültig ist, geben Sie eine Konfigurationskarte zurück, auf der eine Fehlermeldung angezeigt wird, in der erklärt wird, wie der Fehler behoben werden kann.

Da die serverseitige Validierung asynchron ist, erfährt der Nutzer möglicherweise erst beim Veröffentlichen des Ablaufs von dem Eingabefehler.

Die id jeder validierten Eingabe in der Manifestdatei muss mit dem name eines Karten-Widgets im Code übereinstimmen.

Im folgenden Beispiel wird geprüft, ob eine Texteingabe des Nutzers das Zeichen „@“ enthält:

Manifestdatei

Der Auszug aus der Manifestdatei gibt eine onSaveFunction mit dem Namen „onSave“ an:

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": "server_validation_demo",
          "state": "ACTIVE",
          "name": "Email address validation",
          "description": "Asks the user for an email address",
          "workflowAction": {
            "inputs": [
              {
                "id": "email",
                "description": "email address",
                "cardinality": "SINGLE",
                "required": true,
                "dataType": {
                  "basicType": "STRING"
                }
              }
            ],
            "onConfigFunction": "onConfig",
            "onExecuteFunction": "onExecute",
            "onSaveFunction": "onSave"
          }
        }
      ]
    }
  }
}

Anwendungscode

Der Code des Schritts enthält eine Funktion namens onSave. Sie prüft, ob ein vom Nutzer eingegebener String „@“ enthält. Wenn ja, wird der Schritt gespeichert. Andernfalls wird eine Konfigurationskarte mit einer Fehlermeldung zurückgegeben, in der erklärt wird, wie der Fehler behoben werden kann.

Apps Script

// A helper method to push a card interface
function pushCard(card) {
  const navigation = AddOnsResponseService.newNavigation()
    .pushCard(card);

  const action = AddOnsResponseService.newAction()
    .addNavigation(navigation);

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

function onConfig() {
  const emailInput = CardService.newTextInput()
    .setFieldName("email")
    .setTitle("User e-mail")
    .setId("email");

  const saveButton = CardService.newTextButton()
    .setText("Save!")
    .setOnClickAction(
      CardService.newAction()
        .setFunctionName('onSave')
    )

  const sections = CardService.newCardSection()
    .setHeader("Server-side validation")
    .setId("section_1")
    .addWidget(emailInput)
    .addWidget(saveButton);

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

  return pushCard(card);
}

function onExecute(event) {
}

/**
* Validates user input asynchronously when the user
* navigates away from a step's configuration card.
*/
function onSave(event) {
  console.log(JSON.stringify(event, null, 2));

  // "email" matches the input ID specified in the manifest file.
  var email = event.formInputs["email"][0];

  console.log(JSON.stringify(email, null, 2));

  // Validate that the email address contains an "@" sign:
  if (email.includes("@")) {
    // If successfully validated, save and proceed.
    const hostAppAction = AddOnsResponseService.newHostAppAction()
      .setWorkflowAction(
        AddOnsResponseService.newSaveWorkflowAction()
      );

    const textDeletion = AddOnsResponseService.newRemoveWidget()
      .setWidgetId("errorMessage");

    const modifyAction = AddOnsResponseService.newAction()
      .addModifyCard(
        AddOnsResponseService.newModifyCard()
          .setRemoveWidget(textDeletion)
      );

    return AddOnsResponseService.newRenderActionBuilder()
      .setHostAppAction(hostAppAction)
      .setAction(modifyAction)
      .build();

  } else {
    // If the input is invalid, return a card with an error message

    const textParagraph = CardService.newTextParagraph()
      .setId("errorMessage")
      .setMaxLines(1)
      .setText("<font color=\"#FF0000\"><b>Error:</b> Email addresses must include the '@' sign.</font>");

    const emailInput = CardService.newTextInput()
      .setFieldName("email")
      .setTitle("User e-mail")
      .setId("email");

    const saveButton = CardService.newTextButton()
      .setText("Save!")
      .setOnClickAction(
        CardService.newAction().setFunctionName('onSave')
      )

    const sections = CardService.newCardSection()
      .setHeader("Server-side validation")
      .setId("section_1")
      .addWidget(emailInput)
      .addWidget(textParagraph) //Insert the error message
      .addWidget(saveButton);

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

    const navigation = AddOnsResponseService.newNavigation()
      .pushCard(card);

    const action = AddOnsResponseService.newAction()
      .addNavigation(navigation);

    const hostAppAction = AddOnsResponseService.newHostAppAction()
      .setWorkflowAction(
        AddOnsResponseService.newWorkflowValidationErrorAction()
          .setSeverity(AddOnsResponseService.ValidationErrorSeverity.CRITICAL)
      );

    return AddOnsResponseService.newRenderActionBuilder()
      .setHostAppAction(hostAppAction)
      .setAction(action)
      .build();
  }
}