يوضّح هذا الدليل كيفية التحقّق من صحة متغيّر إدخال.
عند تحديد متغيّر إدخال، من أفضل الممارسات التحقّق من أنّ المستخدم
يدخل قيمة مناسبة. على سبيل المثال، إذا طلبت من المستخدم إدخال رقم، سيؤدي التحقّق من إدخاله 1 بدلاً من a إلى التأكّد من أنّ خطوتك تعمل بدون أخطاء.
هناك طريقتان للتحقّق من صحة متغيّر إدخال:
- التحقّق من صحة البيانات من جهة العميل: من خلال التحقّق من صحة البيانات من جهة العميل، يمكنك التأكّد من صحة البيانات التي يُدخلها المستخدم مباشرةً على جهازه. يتلقّى المستخدم ملاحظات فورية ويمكنه تصحيح أي أخطاء في الإدخال أثناء إعداد الخطوة.
- عملية التأكّد من صحة البيانات من جهة الخادم: تتيح لك عملية التأكّد من صحة البيانات من جهة الخادم تنفيذ منطق على الخادم أثناء عملية التأكّد من صحة البيانات، وهو أمر مفيد عندما تحتاج إلى البحث عن معلومات غير متوفّرة لدى العميل، مثل البيانات في أنظمة أو قواعد بيانات أخرى.
التحقّق من صحة البيانات من جهة العميل
تتوفّر طريقتان لتنفيذ عملية التحقّق من الصحة من جهة العميل:
- لإجراء عمليات التحقّق الأساسية، مثل التأكّد من أنّ إحدى الأدوات تحتوي على عدد أقل من عدد معيّن من الأحرف أو أنّها تحتوي على الرمز
@، استدعِ الفئةValidationمن خدمة "البطاقات" في إضافة Google Workspace. - لإجراء عملية تحقّق قوية، مثل مقارنة قيم عناصر واجهة المستخدم بقيم عناصر واجهة مستخدم أخرى، يمكنك إضافة عملية التحقّق باستخدام "لغة التعبير العادي" (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: قائمة بالشروط التي تتضمّن مجموعة من نتائج التحقّق المحدّدة مسبقًا (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(عدم تساوي القيم المُدخَلة)، يتم ضبط أداة رسالة الخطأ على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:
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، يساوي) وسيطتَين بالضبط. سيؤدي تقديم عدد مختلف من الوسيطات إلى ظهور خطأ. - أحجام وسيطات غير صحيحة للعمليات الأحادية: تتطلّب العمليات الأحادية (مثل
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);
}
}