بعد أن يرسل العميل طلب طعام، يمكنك إرسال رسالة تعديل طلب إلى خدمة Ordering End-to-End لإعلامنا بالتغيير.
في ما يلي بعض الأسباب الشائعة لإرسال تعديلات على الطلبات:
- يصبح الوقت المقدّر لاستيفاء الطلب متاحًا أو يتغيّر.
- تغيُّر حالة طلب
- لم يعُد بالإمكان تنفيذ الطلب.
- تغيّر سعر أحد عناصر القائمة المضمّنة في الطلب.
- يتوفّر للعميل طريقة جديدة لإدارة طلبه، مثل رقم هاتف فريق دعم العملاء أو رقم هاتف المطعم.
- يصبح إيصال الطلب متاحًا.
تقدّم الأقسام التالية تفاصيل حول كيفية معالجة هذه السيناريوهات المختلفة باستخدام تعديلات الطلبات.
حالات الطلب أثناء النقل
يتضمّن الطلب ست حالات محتملة. تم توضيح هذه الحالات والحالات الانتقالية المحتملة في الرسم البياني التالي:
عندما يرسل العميل طلبًا لأول مرة، تبدأ حالة الطلب بأحد القيم التالية:
CREATED
أو CONFIRMED
أو REJECTED
. يمكنك إرسال رسالة تعديل طلب بهدف تعديل حالة الطلب، ما دام انتقال الحالة صالحًا. يتم استخدام حالة CREATED
عندما لا تتمكّن منصة الشريك من تأكيد الطلب أو رفضه
على الفور. ومن الأمثلة على حالات الاستخدام عندما يطلب العميل من خلال جمعية تسليم. يتلقّى مجمّع عمليات التسليم الطلب من Google، ويُرسِل المُجمّع المعلومات إلى المطعم. بعد أن يتلقّى المطعم الطلبات ويؤكّد توفّرها، يمكن أن تكون الحالة الآن CONFIRMED
، وإلا
REJECTED
.
ينتقل الطلب الذي يكون في الحالة CONFIRMED
بعد ذلك إلى الحالة IN_PREPARATION
. استنادًا إلى ما إذا كان الطلب مخصّصًا للاستلام أو التسليم، استخدِم بعد ذلك الحالة READY_FOR_PICKUP
أو IN_TRANSIT
. عند تسليم الطعام أو استلامه، يتم ضبط الطلب على الحالة FULFILLED
.
إذا كنت تسمح للعملاء بإلغاء الطلبات، يمكنك استخدام الحالة CANCELLED
. يمكن إلغاء الطلب عندما يكون في الحالة CREATED
أو CONFIRMED
أو IN_PREPARATION
أو READY_FOR_PICKUP
أو IN_TRANSIT
.
من المفترض أن تردّ خدمة "الطلب من البداية إلى النهاية" الأموال استنادًا إلى
سياستك في الإلغاء وحالة الدفعات في وقت الإلغاء.
ليس من الضروري أن تتوافق خدمة "الطلب من البداية إلى النهاية" مع جميع الحالات المتاحة
والعمليات الانتقالية. ومع ذلك، يجب أن تكون الحالة النهائية للطلب هي FULFILLED
أو
REJECTED
أو CANCELLED
.
تقديم وقت مقدَّر لاستيفاء الطلب
يمكنك تزويد المستخدمين بنطاق زمني مقدَّر لوقت يصبح فيه طلبهم
جاهزًا للاستلام (أو يتم تسليمه). استخدِم الحقل estimatedFulfillmentTimeIso8601
في FoodOrderUpdateExtension
لتقديم نطاق زمني مقدَّر لوقت يصبح فيه سفارش العميل جاهزًا للاستلام أو يتم تسليمه.
أرسِل الرمز estimatedFulfillmentTimeIso8601
في الأوقات التالية:
- عندما يصبح الوقت المقدّر متاحًا، من الأفضل أن يكون الطلب في الحالة
CREATED
أوCONFIRMED
. - عندما يتغيّر الوقت المقدَّر، مثل تعديل الوقت المقدَّر ليكون
أكثر دقة عندما يكون الطلب
IN_TRANSIT
.
لإدارة توقعات المستخدمين بفعالية، يجب أن تكون تقديراتك متحفظة و أن تقدّم نطاقًا زمنيًا وتاريخًا بدلاً من تاريخ ووقت محدّدَين. يجب مراعاة الاختلافات، مثل ظروف حركة المرور، كلما أمكن ذلك. على سبيل المثال، يمكنك إرسال تقدير من الساعة 12:45 مساءً (الحد الأدنى) إلى الساعة 1:15 مساءً (الحد الأقصى) لطلب يكون وقت التسليم المقدَّر له هو الساعة 1:00 مساءً.
تقديم إجراءات إدارة الطلبات
عند إرسال إشعار بحالة الطلب، يمكنك تقديم موارد للعملاء تساعدهم في
إدارة طلبهم في شكل OrderManagementAction
. بعد أن يقدّم العميل طلبًا، قد يحتاج إلى التواصل معك أو مع المطعم الذي يوصّل الطلب لمتابعة مستوى التقدّم أو إجراء تغييرات أو إلغاء طلبه.
يتيح OrderManagementAction
للعملاء إرسال رسائل إلكترونية أو الاتصال أو الربط بأحد
عناوين URL مباشرةً من أجهزتهم. استخدِم المعلومات نفسها في
OrderManagementAction
كما في رسالة تأكيد الطلب المُرسَلة بالبريد الإلكتروني إلى
المستخدِم.
تشمل إجراءات إدارة الطلبات الأنواع التالية:
CUSTOMER_SERVICE
: عليك تقديم إجراء للعملاء للتواصل مع خدمة العميل. هذا النوع من إجراءات الإدارة مطلوب لتعديلات الطلبات.EMAIL
: عليك منح العملاء إجراءً لإرسال رسالة إلكترونية إلى عنوان البريد الإلكتروني الذي تم تقديمه.CALL
: عليك تقديم إجراء للعملاء للاتصال برقم الهاتف المقدَّم.VIEW_DETAIL
: عليك تقديم إجراء للعملاء لعرض تفاصيل طلبهم.
يجب أن يحتوي كل تعديل على طلب على إجراء واحد على الأقل لإدارة الطلبات. ومع ذلك،
يمكن أن تختلف إجراءات إدارة الطلبات المقدَّمة استنادًا إلى حالة الطلب.
على سبيل المثال، عندما يكون الطلب في الحالة CONFIRMED
، يمكن أن يشير الإجراء CUSTOMER_SERVICE
إلى رقم هاتف خدمة العملاء. عندما يتم تعديل حالة الطلب
إلى IN_TRANSIT
، يمكن أن يشير الإجراء CUSTOMER_SERVICE
إلى
رقم هاتف مطعم التسليم.
إرسال معلومات عن الطلبات
يمكنك استخدام نوع الرسالة AsyncOrderUpdateRequestMessage
لإرسال تعديل على طلب إلى خدمة "عملية الطلب الشاملة". يردّ محرّك بحث Google باستخدام
AsyncOrderUpdateResponseMessage
. على سبيل المثال، إذا أردت إبلاغ العميل بأنّ طلبه صالح وتم قبوله، يمكنك إرسال AsyncOrderUpdateRequestMessage
لتغيير حالة الطلب إلى CONFIRMED
مع التصنيف Accepted by restaurant
.
ضبط رسالة تعديل الطلب
عند إرسال AsyncOrderUpdateRequestMessage
إلى Google، يجب تضمين
معلومات عن حالة الطلب باستخدام حقل OrderUpdate
.
تعرض الأمثلة التالية نموذج AsyncOrderUpdateRequestMessage
لكل حالة من حالات الطلب:
تم تأكيد الحجز
يعرض هذا المثال نموذجًا لطلب تعديل الطلب يُعلم المستخدم بأنّه تم تأكيد الطلب من خلال إيصال ووقت مقدَّر للتسليم.
{ "isInSandbox": true, "customPushMessage": { "orderUpdate": { "actionOrderId": "sample_action_order_id", "orderState": { "state": "CONFIRMED", "label": "Provider confirmed" }, "receipt": { "userVisibleOrderId": "userVisibleId1234" }, "updateTime": "2017-07-17T12:00:00Z", "orderManagementActions": [ { "type": "CUSTOMER_SERVICE", "button": { "title": "Contact customer service", "openUrlAction": { "url": "mailto:support@example.com" } } }, { "type": "EMAIL", "button": { "title": "Email restaurant", "openUrlAction": { "url": "mailto:person@example.com" } } }, { "type": "CALL_RESTAURANT", "button": { "title": "Call restaurant", "openUrlAction": { "url": "tel:+16505554679" } } }, { "type": "CALL_DRIVER", "button": { "title": "Call driver", "openUrlAction": { "url": "tel:+16505554681" } } } ], "infoExtension": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodOrderUpdateExtension", "estimatedFulfillmentTimeIso8601": "2017-07-17T13:00:00Z/2017-07-17T13:30:00Z" } } } }
مرفوضة
يعرض هذا المثال نموذجًا لطلب تعديل الطلب يُعلم المستخدم بأنّه تم رفض الطلب مع توضيح سبب الرفض.
{ "isInSandbox": true, "customPushMessage": { "orderUpdate": { "actionOrderId": "sample_action_order_id", "orderState": { "state": "REJECTED", "label": "Order rejected" }, "updateTime": "2017-05-10T02:30:00.000Z", "rejectionInfo": { "type": "UNKNOWN", "reason": "Sorry, the restaurant cannot take your order right now." }, "orderManagementActions": [ { "type": "CUSTOMER_SERVICE", "button": { "title": "Contact customer service", "openUrlAction": { "url": "mailto:support@example.com" } } }, { "type": "EMAIL", "button": { "title": "Email restaurant", "openUrlAction": { "url": "mailto:person@example.com" } } }, { "type": "CALL_RESTAURANT", "button": { "title": "Call restaurant", "openUrlAction": { "url": "tel:+16505554679" } } }, { "type": "CALL_DRIVER", "button": { "title": "Call driver", "openUrlAction": { "url": "tel:+16505554681" } } } ], "infoExtension": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodOrderUpdateExtension", "foodOrderErrors": [ { "error": "NO_CAPACITY", "description": "Sorry, the restaurant cannot take your order right now." } ] } } } }
تم إلغاؤها
يعرض هذا المثال نموذجًا لطلب تعديل الطلب يُعلم المستخدم بأنّه تم إلغاء الطلب مع توضيح سبب الإلغاء.
{ "isInSandbox": true, "customPushMessage": { "orderUpdate": { "actionOrderId": "sample_action_order_id", "orderState": { "state": "CANCELLED", "label": "Order cancelled" }, "updateTime": "2017-05-10T02:30:00.000Z", "cancellationInfo": { "reason": "Customer requested" }, "orderManagementActions": [ { "type": "CUSTOMER_SERVICE", "button": { "title": "Contact customer service", "openUrlAction": { "url": "mailto:support@example.com" } } }, { "type": "EMAIL", "button": { "title": "Email restaurant", "openUrlAction": { "url": "mailto:person@example.com" } } }, { "type": "CALL_RESTAURANT", "button": { "title": "Call restaurant", "openUrlAction": { "url": "tel:+16505554679" } } }, { "type": "CALL_DRIVER", "button": { "title": "Call driver", "openUrlAction": { "url": "tel:+16505554681" } } } ] } } }
IN_PREPARATION
يعرض هذا المثال نموذجًا لطلب تعديل الطلب يُعلم المستخدم بأنّه يتم حاليًا تحضير الطعام.
{ "isInSandbox":true, "customPushMessage":{ "orderUpdate":{ "actionOrderId":"sample_action_order_id", "orderState":{ "state":"IN_PREPARATION", "label":"Order is being prepared" }, "receipt": { "userVisibleOrderId": "userVisibleId1234" }, "updateTime":"2018-04-15T11:30:00Z", "orderManagementActions": [ { "type": "CUSTOMER_SERVICE", "button": { "title": "Contact customer service", "openUrlAction": { "url": "mailto:support@example.com" } } }, { "type": "EMAIL", "button": { "title": "Email restaurant", "openUrlAction": { "url": "mailto:person@example.com" } } }, { "type": "CALL_RESTAURANT", "button": { "title": "Call restaurant", "openUrlAction": { "url": "tel:+16505554679" } } }, { "type": "CALL_DRIVER", "button": { "title": "Call driver", "openUrlAction": { "url": "tel:+16505554681" } } } ], "infoExtension":{ "@type":"type.googleapis.com/google.actions.v2.orders.FoodOrderUpdateExtension", "estimatedFulfillmentTimeIso8601":"PT20M" } } } }
READY_FOR_PICKUP
يعرض هذا المثال نموذجًا لطلب تعديل الطلب لإعلام المستخدم بأنّ الطعام جاهز للاستلام.
{ "isInSandbox": true, "customPushMessage": { "orderUpdate": { "actionOrderId": "sample_action_order_id", "orderState": { "state": "READY_FOR_PICKUP", "label": "Order is ready for pickup" }, "receipt": { "userVisibleOrderId": "userVisibleId1234" }, "updateTime": "2018-04-15T12:00:00Z", "orderManagementActions": [ { "type": "CUSTOMER_SERVICE", "button": { "title": "Contact customer service", "openUrlAction": { "url": "mailto:support@example.com" } } }, { "type": "EMAIL", "button": { "title": "Email restaurant", "openUrlAction": { "url": "mailto:person@example.com" } } }, { "type": "CALL_RESTAURANT", "button": { "title": "Call restaurant", "openUrlAction": { "url": "tel:+16505554679" } } }, { "type": "CALL_DRIVER", "button": { "title": "Call driver", "openUrlAction": { "url": "tel:+16505554681" } } } ], "infoExtension": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodOrderUpdateExtension", "estimatedFulfillmentTimeIso8601": "PT20M" } } } }
IN_TRANSIT
يعرض هذا المثال نموذجًا لطلب تعديل الطلب يُعلم المستخدم بأنّ الطلب قيد النقل مع تحديد وقت مقدَّر للتسليم.
{ "isInSandbox": true, "customPushMessage": { "orderUpdate": { "actionOrderId": "sample_action_order_id", "orderState": { "state": "IN_TRANSIT", "label": "Order is on the way" }, "inTransitInfo": { "updatedTime": "2017-07-17T12:00:00Z" }, "updateTime": "2017-07-17T12:00:00Z", "orderManagementActions": [ { "type": "CUSTOMER_SERVICE", "button": { "title": "Contact customer service", "openUrlAction": { "url": "mailto:support@example.com" } } }, { "type": "EMAIL", "button": { "title": "Email restaurant", "openUrlAction": { "url": "mailto:person@example.com" } } }, { "type": "CALL_RESTAURANT", "button": { "title": "Call restaurant", "openUrlAction": { "url": "tel:+16505554679" } } }, { "type": "CALL_DRIVER", "button": { "title": "Call driver", "openUrlAction": { "url": "tel:+16505554681" } } } ], "infoExtension": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodOrderUpdateExtension", "estimatedFulfillmentTimeIso8601": "PT20M" } } } }
FULFILLED
يعرض هذا المثال نموذجًا لطلب تعديل الطلب لإعلام المستخدم بأنّه تم استلام الطلب أو تسليمه:
{ "isInSandbox": true, "customPushMessage": { "orderUpdate": { "actionOrderId": "sample_action_order_id", "orderState": { "state": "FULFILLED", "label": "Order delivered" }, "updateTime": "2017-05-10T02:30:00.000Z", "fulfillmentInfo": { "deliveryTime": "2017-05-10T02:30:00.000Z" }, "orderManagementActions": [ { "type": "CUSTOMER_SERVICE", "button": { "title": "Contact customer service", "openUrlAction": { "url": "mailto:support@example.com" } } }, { "type": "EMAIL", "button": { "title": "Email restaurant", "openUrlAction": { "url": "mailto:person@example.com" } } }, { "type": "CALL_RESTAURANT", "button": { "title": "Call restaurant", "openUrlAction": { "url": "tel:+16505554679" } } }, { "type": "CALL_DRIVER", "button": { "title": "Call driver", "openUrlAction": { "url": "tel:+16505554681" } } } ] } } }
لمزيد من الأمثلة على طلبات تعديل الطلبات في حالات استخدام مختلفة، يُرجى الاطّلاع على مقالة تنفيذ التعديلات المتقدّمة للطلبات.
إنشاء رمز مميّز للتفويض وإرسال الرسالة
تتطلّب تعديلات الطلبات الحصول على رمز مميّز لإذن الوصول كي تتمكّن خدمة "عملية الطلب الشاملة" من التحقّق من أنّ الرسالة واردة من خدمة الويب "عملية الطلب الشاملة".
لتنفيذ تعديلات الطلبات لمشروعك، اتّبِع الخطوات التالية:
- أنشئ رمز مميّزًا للتفويض باتّباع الخطوات التالية:
- استخدِم مكتبة Google Auth لقراءة بيانات الاعتماد من ملف حساب الخدمة.
- اطلب الرمز المميّز باستخدام نطاق واجهة برمجة التطبيقات التالي:
https://www.googleapis.com/auth/actions.fulfillment.conversation
- استخدِم هذا الرمز المميّز لإرسال طلب POST مصادق عليه عبر بروتوكول HTTP إلى نقطة النهاية التالية:
https://actions.googleapis.com/v2/conversations:send
- اضبط عنوان
Content-Type
علىapplication/json
كجزء من طلبك.
توضّح الأمثلة التالية كيفية تنفيذ تعديلات الطلبات:
Node.js
يستخدم هذا الرمز البرمجي مكتبة مصادقة Google لنظام التشغيل Node.js.
const {auth} = require('google-auth-library') const request = require('request'); // The service account client secret file downloaded from the Google Cloud Console const serviceAccountJson = require('./service-account.json') // order-update.json is a file that contains the payload const jsonBody = require('./order-update.json') /** * Get the authorization token using a service account. */ async function getAuthToken() { let client = auth.fromJSON(serviceAccountJson) client.scopes = ['https://www.googleapis.com/auth/actions.fulfillment.conversation'] const tokens = await client.authorize() return tokens.access_token; } /** * Send an order update request */ async function sendOrderUpdate() { const token = await getAuthToken() request.post({ headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` }, url: 'https://actions.googleapis.com/v2/conversations:send', body: jsonBody, json: true }, (err, res, body) => { if (err) { return console.log(err); } console.log(`Response: ${JSON.stringify(res)}`) }) }
Python
تستخدِم هذه التعليمات البرمجية مكتبة مصادقة Google لبرنامج Python.
from google.oauth2 import service_account from google.auth.transport.requests import AuthorizedSession import json # service-account.json is the service account client secret file downloaded from the # Google Cloud Console credentials = service_account.Credentials.from_service_account_file( 'service-account.json') scoped_credentials = credentials.with_scopes( ['https://www.googleapis.com/auth/actions.fulfillment.conversation']) authed_session = AuthorizedSession(scoped_credentials) # order-update.json is a file that contains the payload json_payload=json.load(open('order-update.json')) response = authed_session.post( 'https://actions.googleapis.com/v2/conversations:send', json=json_payload)
Java
تستخدِم هذه الرموز البرمجية مكتبة مصادقة Google للغة Java.
/** * Get the authorization token using a service account. */ private static String getAuthToken() { InputStream serviceAccountFile = Example.class.getClassLoader().getResourceAsStream("service-account.json"); ServiceAccountCredentials.Builder credentialsSimpleBuilder = ServiceAccountCredentials.fromStream(serviceAccountFile).toBuilder(); credentialsSimpleBuilder.setScopes(ImmutableList.of("https://www.googleapis.com/auth/actions.fulfillment.conversation")); AccessToken accessToken = credentialsSimpleBuilder.build().refreshAccessToken(); return accessToken.getTokenValue(); } /** * Send an order update request */ public void sendOrderUpdate() { String authToken = getAuthToken(); // Execute POST request executePostRequest("https://actions.googleapis.com/v2/conversations:send", authToken, "update_order_example.json",); }
في حال تعديل الطلبات بنجاح بدون أي أخطاء، تعرض Google استجابة HTTP 200 مع بيانات أساسية فارغة. إذا حدثت مشكلة، مثل عدم صحة التنسيق في التحديث، ستعرض Google رسالة خطأ.