В этом руководстве объясняется, как проверить входную переменную.
При определении входной переменной рекомендуется проверять, вводит ли пользователь соответствующее значение. Например, если вы просите пользователя ввести цифру, проверка того, что он вводит 1 вместо a , гарантирует, что ваш шаг выполняется без ошибок.
Существует два способа проверки входной переменной:
- Проверка на стороне клиента : При проверке на стороне клиента вы проверяете ввод пользователя непосредственно на его устройстве. Пользователь получает мгновенную обратную связь и может исправить любые ошибки во вводе при настройке шага.
- Серверная валидация : Серверная валидация позволяет выполнять логику на сервере во время проверки, что полезно, когда необходимо найти информацию, которой нет у клиента, например, данные в других системах или базах данных.
Проверка на стороне клиента
Существует два способа реализации проверки данных на стороне клиента:
- Для базовой проверки, например, проверки того, содержит ли виджет меньшее количество символов или содержит ли он символ
@, вызовите классValidationслужбы Card дополнения Google Workspace. - Для более надежной проверки, например, сравнения значений виджетов с другими значениями виджетов, вы можете добавить проверку Common Expression Language (CEL) к следующим поддерживаемым виджетам карточек, используя
CardService.
Вызовите класс Validation .
Следующий пример проверяет, содержит ли виджет TextInput не более 10 символов:
Apps Script
const validation = CardService.newValidation().setCharacterLimit('10').setInputType(
CardService.InputType.TEXT);
Для дополнительных параметров проверки используйте проверку CEL.
Проверка CEL
Проверка с помощью Common Expression Language (CEL) обеспечивает мгновенную проверку входных данных без задержек, характерных для серверной проверки, перенося проверки входных значений, не зависящие от поиска данных в других сервисах, на сторону клиента.
Вы также можете использовать CEL для создания поведения карточек, например, отображения или скрытия виджета в зависимости от результата проверки. Такое поведение полезно для отображения или скрытия сообщения об ошибке, которое помогает пользователям исправить введенные данные.
Создание полной системы валидации CEL включает в себя следующие компоненты:
ExpressionDataв карточке: содержит указанную логику проверки и логику запуска виджета при выполнении одного из определенных условий.-
Id: Уникальный идентификатор дляExpressionDataв текущей карточке. -
Expression: строка CEL, определяющая логику проверки (например,"value1 == value2"). -
Conditions: Список условий, содержащий набор предопределенных результатов проверки (УСПЕХ или НЕУДАЧА). Условия связаны сEventActionна стороне виджета черезTriggersс общимactionRuleId. - Событие уровня карточки (Cell-level
EventAction): Активирует проверки CEL на карточке и связывает полеExpressionDataс виджетами результатов посредством триггеров после события.-
actionRuleId: Уникальный идентификатор для этогоEventAction. -
ExpressionDataAction: Установите значениеSTART_EXPRESSION_EVALUATIONчтобы указать, что это действие запускает оценку CEL. -
Trigger: связываетConditionsсEventActionsна стороне виджета на основеactionRuleId.
-
-
EventActionна уровне виджета: управляет поведением виджета результатов при выполнении условия успеха или неудачи. Например, виджет результатов может представлять собойTextParagraph, содержащий сообщение об ошибке, которое становится видимым только в случае неудачной проверки.-
actionRuleId: СоответствуетactionRuleIdвTriggerна стороне карты. -
CommonWidgetAction: Определяет действия, не требующие вычислений, например, обновление видимости виджета.-
UpdateVisibilityAction: Действие, которое обновляет состояние видимости виджета (VISIBLE или HIDDEN).
-
-
В следующем примере показано, как реализовать проверку CEL для определения равенства двух текстовых полей ввода. В случае неравенства отображается сообщение об ошибке.

Рисунок 1: Когда выполняется условие failCondition(входные данные не равны), виджет сообщения об ошибке становитсяVISIBLEи отображается.
Рисунок 2: Когда выполняется условие successCondition(входные данные равны), виджет сообщения об ошибке устанавливается вHIDDENи не отображается.
Ниже приведён пример кода приложения и JSON-файл манифеста:
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
{
"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"
}
}
]
}
}
}
Поддерживаемые виджеты и операции проверки CEL
Виджеты карточек, поддерживающие проверку CEL.
Следующие виджеты поддерживают проверку CEL:
-
TextInput -
SelectionInput -
DateTimePicker
Поддерживаемые операции проверки CEL
- Арифметические операции
-
+: Складывает два числа типаint64,uint64илиdouble. -
-: Вычитает два числа типаint64,uint64илиdouble. -
*: Умножает два числа типаint64,uint64илиdouble. -
/: Делит два числа типаint64,uint64илиdouble(целочисленное деление). -
%: Вычисляет остаток от деления двух чисел типаint64илиuint64. -
-: Отменяет значение числа типаint64илиuint64.
-
- Логические операции:
-
&&: Выполняет логическую операциюANDнад двумя логическими значениями. -
||: Выполняет логическую операциюORнад двумя логическими значениями. -
!: Выполняет логическую операциюNOTнад логическим значением.
-
- Операции сравнения:
-
==: Проверяет равенство двух значений. Поддерживает числа и списки. -
!=: Проверяет, равны ли два значения. Поддерживаются числа и списки. -
<: Проверяет, меньше ли первое число типаint64,uint64илиdoubleвторого числа. -
<=: Проверяет, меньше ли или равно ли первое число типаint64,uint64илиdoubleвторому. -
>: Проверяет, больше ли первое число типаint64,uint64илиdouble, чем второе. -
>=: Проверяет, больше ли или равно второе первое число типаint64,uint64илиdouble.
-
- Операции со списками:
-
inпроверяет наличие значения в списке. Поддерживает числа, строки и вложенные списки. -
size: Возвращает количество элементов в списке. Поддерживает числа и вложенные списки.
-
Неподдерживаемые сценарии проверки CEL
- Неправильный размер аргументов для бинарных операций : Бинарные операции (например,
add_int64, equals) требуют ровно два аргумента. Указание другого количества аргументов приведет к ошибке. - Неправильный размер аргументов для унарных операций : Унарные операции (например,
negate_int64) требуют ровно одного аргумента. Предоставление другого количества аргументов вызовет ошибку. - Неподдерживаемые типы в числовых операциях : Числовые двоичные и унарные операции принимают только числовые аргументы. Предоставление других типов (например, логического значения) вызовет ошибку.
Проверка на стороне сервера
Благодаря серверной валидации вы можете запускать серверную логику, указав метод onSaveFunction() в коде шага. Когда пользователь покидает карточку конфигурации шага, onSaveFunction() запускается и позволяет проверить введенные пользователем данные.
Если введенные пользователем данные корректны, верните saveWorkflowAction .
Если введенные пользователем данные недействительны, верните карточку конфигурации, которая отобразит пользователю сообщение об ошибке с объяснением того, как ее устранить.
Поскольку серверная проверка данных выполняется асинхронно, пользователь может не узнать об ошибке ввода до тех пор, пока не опубликует свой процесс.
id каждого проверяемого поля ввода в файле манифеста должен совпадать с name виджета карточки в коде.
Следующий пример проверяет, содержит ли введенный пользователем текст знак "@":
файл манифеста
В фрагменте файла манифеста указана функция onSaveFunction() с именем "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": "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"
}
}
]
}
}
}
Код приложения
В коде этого шага есть функция onSave() . Она проверяет, содержит ли введенная пользователем строка символ "@". Если да, то шаг сохраняется. Если нет, то возвращается карточка конфигурации с сообщением об ошибке, объясняющим, как ее исправить.
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();
}
}
Связанные темы
- Определите входную переменную
- Журналы активности и ошибок
- Объекты событий Workspace Studio
- Язык выражений общего назначения (CEL)