במדריך הזה מוסבר איך לאמת משתנה קלט.
כשמגדירים משתנה קלט, מומלץ לוודא שהמשתמש מזין ערך מתאים. לדוגמה, אם מבקשים מהמשתמש להזין ספרה, אימות ההזנה של 1 במקום a מאמת שהשלב פועל ללא שגיאה.
יש שתי דרכים לאמת משתנה קלט:
- אימות בצד הלקוח: באימות בצד הלקוח, המערכת מאמתת את הקלט של המשתמש ישירות במכשיר שלו. המשתמש מקבל משוב מיידי ויכול לתקן שגיאות בהזנה שלו במהלך הגדרת השלב.
- אימות בצד השרת: אימות בצד השרת מאפשר להריץ לוגיקה בשרת במהלך האימות. זה שימושי כשצריך לחפש מידע שלא קיים בצד הלקוח, כמו נתונים במערכות או במסדי נתונים אחרים.
אימות בצד הלקוח
יש שתי דרכים להטמיע אימות בצד הלקוח:
- כדי לבצע אימות בסיסי, כמו אימות של ווידג'ט שמכיל פחות ממספר מסוים של תווים או שמכיל את הסמל
@, מפעילים את המחלקהValidationשל שירות הכרטיסים של תוסף 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בתוך Card הנוכחי. -
Expression: מחרוזת CEL שמגדירה את לוגיקת האימות (למשל,"value1 == value2"). -
Conditions: רשימה של תנאים שמכילה מבחר של תוצאות אימות מוגדרות מראש (SUCCESS או FAILURE). התנאים קשורים ל-EventActionבצד הווידג'ט דרךTriggersעםactionRuleIdמשותף. - ברמת הכרטיס
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(הערכים של קלט 1 וקלט 2 לא שווים), הווידג'ט של הודעת השגיאה מוגדר ל-VISIBLEומופיע. -
איור 2: כשמתקיים התנאי successCondition(הערכים של הקלט שווים), הווידג'ט של הודעת השגיאה מוגדר ל-HIDDENולא מוצג.
דוגמה לקוד האפליקציה ולקובץ המניפסט בפורמט 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();
}
קובץ מניפסט 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:
TextInputSelectionInputDateTimePicker
פעולות אימות נתמכות של 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():
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(). הפונקציה בודקת אם מחרוזת שהוזנה על ידי המשתמש כוללת את התו @. אם כן, היא שומרת את שלב התהליך. אם לא, היא מחזירה כרטיס הגדרה עם הודעת שגיאה שמסבירה איך לתקן את השגיאה.
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);
}
}
נושאים קשורים
- הגדרה של משתנה קלט
- רישום פעילות ושגיאות ביומן
- אובייקט האירוע של Flows
- Common Expression Language (CEL)