В этом руководстве объясняется, как проверить входную переменную.
При определении входной переменной рекомендуется убедиться, что пользователь вводит правильное значение. Например, если вы просите пользователя ввести число, проверка того, что он ввёл 1 вместо a подтверждает, что ваш шаг выполняется без ошибок.
Существует два способа проверки входной переменной:
- Валидация на стороне клиента : с помощью валидации на стороне клиента вы проверяете данные, введённые пользователем, непосредственно на его устройстве. Пользователь получает немедленную обратную связь и может исправить любые ошибки во введённых данных при настройке шага.
- Проверка на стороне сервера : проверка на стороне сервера позволяет запускать логику на сервере во время проверки, что полезно, когда вам нужно найти информацию, которой нет у клиента, например данные в других системах или базах данных.
Проверка на стороне клиента
Существует два способа реализации проверки на стороне клиента:
- Для базовой проверки, например проверки того, что виджет содержит меньше определенного количества символов или содержит символ
@, вызовите классValidationслужбы Card надстройки Google Workspace. - Для надежной проверки, например сравнения значений виджета со значениями других виджетов, вы можете добавить проверку Common Expression Language (CEL) к следующим поддерживаемым виджетам карт с помощью
CardService.
Вызов класса Validation
Следующий пример проверяет, что виджет TextInput содержит 10 или менее символов:
Скрипт приложений
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. -
EventActionна уровне карты: активирует проверки CEL в карте и связывает полеExpressionDataс виджетами результатов через триггеры после события.-
actionRuleId: Уникальный идентификатор для этогоEventAction. -
ExpressionDataAction: установите значениеSTART_EXPRESSION_EVALUATION, чтобы указать, что это действие запускает оценку CEL. -
Trigger: связываетConditionsсEventActionsна стороне виджета на основеactionRuleId.
-
-
EventActionна уровне виджета: управляет поведением виджета результата при выполнении условия успеха или неудачи. Например, виджет результата может бытьTextParagraph, содержащим сообщение об ошибке, которое отображается только в случае неудачной проверки.-
actionRuleId: СоответствуетactionRuleIdвTriggerна стороне карты. -
CommonWidgetAction: определяет действия, не требующие оценок, например обновление видимости виджета.-
UpdateVisibilityAction: действие, которое обновляет состояние видимости виджета (ВИДИМЫЙ или СКРЫТЫЙ).
-
-
В следующем примере показано, как реализовать проверку CEL для проверки равенства двух текстовых полей. Если они не равны, выводится сообщение об ошибке.

Рисунок 1: При выполнении failCondition(входные данные не равны) виджет сообщения об ошибке становитсяVISIBLEи отображается.
Рисунок 2: Если выполняется successCondition(входные данные равны), виджет сообщения об ошибке становитсяHIDDENи не отображается.
Вот пример кода приложения и файл манифеста JSON:
Скрипт приложений
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();
}
Файл манифеста 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"
}
}
]
}
}
}
Поддерживаемые виджеты и операции проверки 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": "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"
}
}
]
}
}
}
Код приложения
Код шага включает функцию onSave() . Она проверяет, содержит ли введённая пользователем строка символ @. Если да, шаг сохраняется. Если нет, возвращается карточка конфигурации с сообщением об ошибке, поясняющим, как её исправить.
Скрипт приложений
/**
* 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);
}
}
Похожие темы
- Определить входную переменную
- Журнал активности и ошибок
- Объект события Flows
- Общий язык выражений (CEL)