इस गाइड में, ऐसे Actions प्रोजेक्ट को बनाने की प्रोसेस के बारे में बताया गया है जो बुकिंग करने के लिए ऑर्डर एपीआई का इस्तेमाल करता है.
लेन-देन फ़्लो
जब आपका Actions प्रोजेक्ट बुकिंग मैनेज करता है, तब यह इस फ़्लो का इस्तेमाल करता है:
- लेन-देन से जुड़ी ज़रूरी शर्तों की पुष्टि करना (ज़रूरी नहीं) - बातचीत की शुरुआत में ही लेन-देन से जुड़ी ज़रूरी शर्तों के लिए दिए गए हेल्पर का इस्तेमाल करें. इससे यह पक्का हो जाता है कि उपयोगकर्ता लेन-देन करने के लिए ज़रूरी है या नहीं.
- ऑर्डर बनाएं - उपयोगकर्ता को "कार्ट असेंबली" के ज़रिए बताएं, जहां वे अपनी बुकिंग की जानकारी तैयार करते हैं.
- ऑर्डर पेश करना - "कार्ट" पूरा होने पर, उपयोगकर्ता को रिज़र्वेशन "ऑर्डर" करने का सुझाव दें, ताकि वह पुष्टि कर सके कि ऑर्डर सही है. बुकिंग की पुष्टि हो जाने पर, आपको बुकिंग की जानकारी के साथ जवाब मिलेगा.
- ऑर्डर पूरा करें और रसीद भेजें - ऑर्डर की पुष्टि हो जाने के बाद, अपना रिज़र्वेशन सिस्टम अपडेट करें और उपयोगकर्ता को रसीद भेजें.
- ऑर्डर के अपडेट भेजें - बुकिंग खत्म होने के दौरान, ऑर्डर एपीआई को पैच अनुरोध भेजकर, उपयोगकर्ता की बुकिंग की स्थिति के अपडेट दें.
पाबंदियां और समीक्षा के लिए दिशा-निर्देश
ध्यान रखें कि लेन-देन और ऑर्डर एपीआई का इस्तेमाल करने वाली कार्रवाइयों पर दूसरी नीतियां भी लागू होती हैं. ट्रांज़ैक्शन से जुड़ी कार्रवाइयों की समीक्षा करने में हमें छह हफ़्ते लग सकते हैं. इसलिए, रिलीज़ शेड्यूल बनाते समय उस समय का ध्यान रखें. समीक्षा के लिए की गई कार्रवाई को सबमिट करने से पहले, पक्का करें कि समीक्षा की प्रोसेस को आसान बनाने के लिए, लेन-देन से जुड़ी नीतियों और दिशा-निर्देशों का पालन किया जा रहा हो.
नीचे दिए गए देशों में सिर्फ़ उन कार्रवाइयों को डिप्लॉय किया जा सकता है जो ऑर्डर एपीआई का इस्तेमाल करती हैं:
ऑस्ट्रेलिया ब्राज़ील कनाडा इंडोनेशिया |
जापान मेक्सिको कतर रूस |
सिंगापुर स्विट्ज़रलैंड थाईलैंड तुर्किये यूनाइटेड किंगडम अमेरिका |
अपना प्रोजेक्ट बनाएं
लेन-देन से जुड़ी बातचीत के सभी उदाहरणों के लिए, Node.js और Java में हमारे लेन-देन के नमूने देखें.
प्रोजेक्ट सेटअप
कार्रवाई बनाते समय, आपको यह बताना होगा कि आपको Actions कंसोल में लेन-देन करना है. साथ ही, अगर Node.JS क्लाइंट लाइब्रेरी का इस्तेमाल किया जा रहा है, तो ऑर्डर एपीआई के नए वर्शन का इस्तेमाल करने के लिए, फ़ुलफ़िलमेंट सेट अप करें.
अपना प्रोजेक्ट सेट अप करने और उसे पूरा करने के लिए, यह तरीका अपनाएं:
- एक नया प्रोजेक्ट बनाएं या कोई मौजूदा प्रोजेक्ट इंपोर्ट करें.
- डिप्लॉय करें > डायरेक्ट्री की जानकारी पर जाएं.
ज़्यादा जानकारी > लेन-देन में जाकर > "क्या आपकी कार्रवाइयां, भौतिक चीज़ों के लेन-देन के लिए लेन-देन एपीआई का इस्तेमाल करती हैं?" वाले बॉक्स को चुनें.
अगर आपकी सेट की गई कार्रवाई को पूरा करने के लिए Node.JS क्लाइंट लाइब्रेरी का इस्तेमाल किया जा रहा है, तो फ़ुलफ़िलमेंट कोड खोलें और
ordersv3
फ़्लैग कोtrue
पर सेट करने के लिए, अपने ऐप्लिकेशन के एलान को अपडेट करें. नीचे दिया गया कोड स्निपेट, ऑर्डर के वर्शन 3 के लिए ऐप्लिकेशन की जानकारी का एक उदाहरण दिखाता है.
Node.js
const {dialogflow} = require('actions-on-google'); let app = dialogflow({ clientId, // If using account linking debug: true, ordersv3: true, });
Node.js
const {actionssdk} = require('actions-on-google'); let app = actionssdk({ clientId, // If using account linking debug: true, ordersv3: true, });
1. लेन-देन से जुड़ी ज़रूरी शर्तों की पुष्टि करना (ज़रूरी नहीं)
लोगों का अनुभव
जैसे ही उपयोगकर्ता यह बताता है कि उसे बुकिंग सेट अप करनी है, हमारा सुझाव है कि वह
actions.intent.TRANSACTION_REQUIREMENTS_CHECK
इंटेंट ट्रिगर करें, ताकि यह पक्का हो सके कि वह बुकिंग का अनुरोध कर सकता है. उदाहरण के लिए, शुरू किए जाने पर आपकी सेट की गई कार्रवाई में आपसे पूछा जा सकता है कि
"क्या आपको कोई सीट बुक करनी है?" अगर उपयोगकर्ता "हां" कहता है, तो आपको तुरंत इसके लिए अनुरोध करना चाहिए. इससे यह पक्का होगा कि वे आगे बढ़ेंगे और उन सभी सेटिंग को ठीक करने का मौक़ा देंगे जो उन्हें लेन-देन जारी रखने से रोकने वाली हो.
ट्रांज़ैक्शन की ज़रूरी शर्तों का अनुरोध करने से, इंटेंट की जांच के इन नतीजों में से कोई एक नतीजा मिलता है:
- अगर ज़रूरी शर्तें पूरी हो जाती हैं, तो आपके फ़ुलफ़िलमेंट को एक इंटेंट मिलता है. इसके बाद, उपयोगकर्ता के लिए ऑर्डर बनाया जा सकता है.
अगर एक या उससे ज़्यादा ज़रूरी शर्तें पूरी नहीं हो पाती हैं, तो आपके पूरे किए गए ऐक्शन को पूरा न करने वाले इंटेंट वाला इंटेंट मिल जाता है. ऐसा होने पर, बातचीत को खत्म कर दें या रिज़र्वेशन फ़्लो को बंद कर दें.
अगर उपयोगकर्ता गड़बड़ी को ठीक कर सकते हैं, तो उन्हें अपने डिवाइस पर उन समस्याओं को ठीक करने का निर्देश अपने-आप मिल जाता है. अगर कोई बातचीत किसी स्मार्ट स्पीकर जैसे सिर्फ़ आवाज़ से डिवाइस पर चल रही हो, तो इसे उपयोगकर्ता के फ़ोन पर दिया जाता है.
ग्राहक का ऑर्डर पूरा करना
यह पक्का करने के लिए कि उपयोगकर्ता
लेन-देन की ज़रूरी शर्तें पूरी करता है,
TransactionRequirementsCheckSpec ऑब्जेक्ट की मदद से,
actions.intent.TRANSACTION_REQUIREMENTS_CHECK
इंटेंट को पूरा करने का अनुरोध करें.
ज़रूरी शर्तें देखें
देखें कि कोई उपयोगकर्ता, क्लाइंट लाइब्रेरी की मदद से रिज़र्वेशन कैंपेन की ज़रूरी शर्तों को पूरा करता है या नहीं:
conv.ask(new TransactionRequirements());
return getResponseBuilder(request) .add("Placeholder for transaction requirements text") .add(new TransactionRequirements()) .build();
ध्यान दें कि नीचे दिया गया JSON, वेबहुक रिस्पॉन्स के बारे में बताता है.
{ "payload": { "google": { "expectUserResponse": true, "systemIntent": { "intent": "actions.intent.TRANSACTION_REQUIREMENTS_CHECK", "data": { "@type": "type.googleapis.com/google.actions.transactions.v3.TransactionRequirementsCheckSpec" } } } } }
ध्यान दें कि नीचे दिया गया JSON, वेबहुक रिस्पॉन्स के बारे में बताता है.
{ "expectUserResponse": true, "expectedInputs": [ { "possibleIntents": [ { "intent": "actions.intent.TRANSACTION_REQUIREMENTS_CHECK", "inputValueData": { "@type": "type.googleapis.com/google.actions.transactions.v3.TransactionRequirementsCheckSpec" } } ] } ] }
ज़रूरी शर्तों से जुड़ी जांच का नतीजा पाएं
Assistant जब आपके इंटेंट को पूरा कर लेती है, तब वह आपकी जांच के नतीजे के साथ, actions.intent.TRANSACTION_REQUIREMENTS_CHECK
इंटेंट के साथ आपका पूरा करने का अनुरोध भेजती है.
इस अनुरोध को ठीक से मैनेज करने के लिए, actions_intent_TRANSACTION_REQUIREMENTS_CHECK
इवेंट से ट्रिगर होने वाले Dialogflow इंटेंट का एलान करें. ट्रिगर होने पर,
अपने फ़ुलफ़िलमेंट में इस इंटेंट को हैंडल करें:
const arg = conv.arguments.get('TRANSACTION_REQUIREMENTS_CHECK_RESULT'); if (arg && arg.resultType === 'CAN_TRANSACT') { // Normally take the user through cart building flow conv.ask(`Looks like you're good to go!`); } else { conv.close('Transaction failed.'); }
Argument transactionCheckResult = request .getArgument("TRANSACTION_REQUIREMENTS_CHECK_RESULT"); boolean result = false; if (transactionCheckResult != null) { Map<String, Object> map = transactionCheckResult.getExtension(); if (map != null) { String resultType = (String) map.get("resultType"); result = resultType != null && resultType.equals("CAN_TRANSACT"); } } ResponseBuilder responseBuilder = getResponseBuilder(request); if (result) { responseBuilder.add("Looks like you're good to go! Now say 'confirm transaction'"); } else { responseBuilder.add("Transaction failed"); } return responseBuilder.build();
ध्यान दें कि नीचे दिया गया JSON, वेबहुक अनुरोध के बारे में बताता है.
{ "responseId": "", "queryResult": { "queryText": "", "action": "", "parameters": {}, "allRequiredParamsPresent": true, "fulfillmentText": "", "fulfillmentMessages": [], "outputContexts": [], "intent": { "name": "reservation_transaction_check_complete_df", "displayName": "reservation_transaction_check_complete_df" }, "intentDetectionConfidence": 1, "diagnosticInfo": {}, "languageCode": "" }, "originalDetectIntentRequest": { "source": "google", "version": "2", "payload": { "isInSandbox": true, "surface": { "capabilities": [ { "name": "actions.capability.SCREEN_OUTPUT" }, { "name": "actions.capability.AUDIO_OUTPUT" }, { "name": "actions.capability.MEDIA_RESPONSE_AUDIO" }, { "name": "actions.capability.WEB_BROWSER" } ] }, "inputs": [ { "rawInputs": [], "intent": "", "arguments": [ { "extension": { "@type": "type.googleapis.com/google.transactions.v3.TransactionRequirementsCheckResult", "resultType": "CAN_TRANSACT" }, "name": "TRANSACTION_REQUIREMENTS_CHECK_RESULT" } ] } ], "user": {}, "conversation": {}, "availableSurfaces": [ { "capabilities": [ { "name": "actions.capability.SCREEN_OUTPUT" }, { "name": "actions.capability.AUDIO_OUTPUT" }, { "name": "actions.capability.MEDIA_RESPONSE_AUDIO" }, { "name": "actions.capability.WEB_BROWSER" } ] } ] } }, "session": "" }
ध्यान दें कि नीचे दिया गया JSON, वेबहुक अनुरोध के बारे में बताता है.
{ "user": {}, "device": {}, "surface": { "capabilities": [ { "name": "actions.capability.SCREEN_OUTPUT" }, { "name": "actions.capability.AUDIO_OUTPUT" }, { "name": "actions.capability.MEDIA_RESPONSE_AUDIO" }, { "name": "actions.capability.WEB_BROWSER" } ] }, "conversation": {}, "inputs": [ { "rawInputs": [], "intent": "reservation_transaction_check_complete_asdk", "arguments": [ { "extension": { "@type": "type.googleapis.com/google.transactions.v3.TransactionRequirementsCheckResult", "resultType": "CAN_TRANSACT" }, "name": "TRANSACTION_REQUIREMENTS_CHECK_RESULT" } ] } ], "availableSurfaces": [ { "capabilities": [ { "name": "actions.capability.SCREEN_OUTPUT" }, { "name": "actions.capability.AUDIO_OUTPUT" }, { "name": "actions.capability.MEDIA_RESPONSE_AUDIO" }, { "name": "actions.capability.WEB_BROWSER" } ] } ] }
2. ऑर्डर बनाएं
लोगों का अनुभव
उपयोगकर्ता की ज़रूरत की जानकारी मिलने के बाद, "कार्ट असेंबली" का एक ऐसा अनुभव बनाएं जो उपयोगकर्ता को बुकिंग करने में मदद करे. हर कार्रवाई की सेवा के हिसाब से, कार्ट असेंबली फ़्लो थोड़ा अलग होगा.
कार्ट असेंबली के बुनियादी अनुभव में, कोई उपयोगकर्ता अपने रिज़र्वेशन में जोड़ने के लिए, सूची से विकल्पों को चुनता है. हालांकि, आपके पास उपयोगकर्ता अनुभव को आसान बनाने के लिए बातचीत को इस तरह से डिज़ाइन करने का विकल्प होता है. उदाहरण के लिए, एक ऐसा कार्ट असेंबली अनुभव तैयार करें जिसकी मदद से उपयोगकर्ता हां या नहीं में सवाल पूछने के लिए हर महीने अपनी बुकिंग शेड्यूल कर सकें. आप उपयोगकर्ता को "सुझाई गई" बुकिंग का कैरसेल या सूची कार्ड भी दिखा सकते हैं.
हमारा सुझाव है कि लोगों के विकल्पों को विज़ुअल तरीके से दिखाने के लिए, बेहतर रिस्पॉन्स का इस्तेमाल करें. साथ ही, बातचीत को इस तरह से डिज़ाइन करें कि लोग सिर्फ़ अपनी आवाज़ का इस्तेमाल करके कार्ट बना सकें. कार्ट असेंबली प्रोसेस के कुछ सबसे सही तरीकों और उदाहरणों के लिए, ट्रांज़ैक्शन डिज़ाइन से जुड़े दिशा-निर्देश देखें.
ग्राहक का ऑर्डर पूरा करना
अपनी पूरी बातचीत के दौरान, रिज़र्वेशन की ऐसी जानकारी इकट्ठा करें जिसे कोई उपयोगकर्ता
खरीदना चाहता है और फिर एक Order
ऑब्जेक्ट बनाएं.
आपके Order
में कम से कम ये चीज़ें होनी चाहिए:
buyerInfo
- बुकिंग शेड्यूल करने वाले उपयोगकर्ता के बारे में जानकारी.transactionMerchant
- बुकिंग की सुविधा देने वाले व्यापारी/कंपनी के बारे में जानकारी.contents
-lineItems
के तौर पर लिस्ट की गई बुकिंग की असल जानकारी.
अपना कार्ट बनाने के लिए, Order
रिस्पॉन्स दस्तावेज़
देखें. ध्यान दें कि रिज़र्वेशन के आधार पर आपको अलग-अलग फ़ील्ड शामिल करने पड़ सकते हैं.
यहां दिए गए सैंपल कोड में, रिज़र्वेशन कैंपेन की पूरी जानकारी दी गई है. इसमें वैकल्पिक फ़ील्ड भी शामिल हैं:
app.intent('build_reservation_df', (conv) => { const now = new Date().toISOString(); const order = { createTime: now, lastUpdateTime: now, merchantOrderId: 'UNIQUE_ORDER_ID', userVisibleOrderId: 'USER_VISIBLE_ORDER_ID', transactionMerchant: { id: 'https://www.example.com', name: 'Example Merchant', }, contents: { lineItems: [ { id: 'LINE_ITEM_ID', name: 'Dinner reservation', description: 'A world of flavors all in one destination.', reservation: { status: 'PENDING', userVisibleStatusLabel: 'Reservation is pending.', type: 'RESTAURANT', reservationTime: { timeIso8601: '2020-01-16T01:30:15.01Z', }, userAcceptableTimeRange: { timeIso8601: '2020-01-15/2020-01-17', }, partySize: 6, staffFacilitators: [ { name: 'John Smith', }, ], location: { zipCode: '94086', city: 'Sunnyvale', postalAddress: { regionCode: 'US', postalCode: '94086', administrativeArea: 'CA', locality: 'Sunnyvale', addressLines: [ '222, Some other Street', ], }, }, }, }, ], }, buyerInfo: { email: 'janedoe@gmail.com', firstName: 'Jane', lastName: 'Doe', displayName: 'Jane Doe', }, followUpActions: [ { type: 'VIEW_DETAILS', title: 'View details', openUrlAction: { url: 'https://example.com', }, }, { type: 'CALL', title: 'Call us', openUrlAction: { url: 'tel:+16501112222', }, }, { type: 'EMAIL', title: 'Email us', openUrlAction: { url: 'mailto:person@example.com', }, }, ], termsOfServiceUrl: 'https://www.example.com', };
private static OrderV3 createOrder() { // Transaction Merchant MerchantV3 transactionMerchant = new MerchantV3() .setId("http://www.example.com") .setName("Example Merchant"); // Line Item // Reservation Item Extension ReservationItemExtension reservationItemExtension = new ReservationItemExtension() .setStatus("PENDING") .setUserVisibleStatusLabel("Reservation pending.") .setType("RESTAURANT") .setReservationTime(new TimeV3() .setTimeIso8601("2020-01-16T01:30:15.01Z")) .setUserAcceptableTimeRange(new TimeV3() .setTimeIso8601("2020-01-15/2020-01-17")) .setPartySize(6) .setStaffFacilitators(Collections.singletonList(new StaffFacilitator() .setName("John Smith"))) .setLocation(new Location() .setZipCode("94086") .setCity("Sunnyvale") .setPostalAddress(new PostalAddress() .setRegionCode("US") .setPostalCode("94086") .setAdministrativeArea("CA") .setLocality("Sunnyvale") .setAddressLines( Collections.singletonList("222, Some other Street")))); LineItemV3 lineItem = new LineItemV3() .setId("LINE_ITEM_ID") .setName("Dinner reservation") .setDescription("A world of flavors all in one destination.") .setReservation(reservationItemExtension); // Order Contents OrderContents contents = new OrderContents() .setLineItems(Collections.singletonList(lineItem)); // User Info UserInfo buyerInfo = new UserInfo() .setEmail("janedoe@gmail.com") .setFirstName("Jane") .setLastName("Doe") .setDisplayName("Jane Doe"); // Follow up actions Action viewDetails = new Action() .setType("VIEW_DETAILS") .setTitle("View details") .setOpenUrlAction(new OpenUrlAction() .setUrl("https://example.com")); Action call = new Action() .setType("CALL") .setTitle("Call us") .setOpenUrlAction(new OpenUrlAction() .setUrl("tel:+16501112222")); Action email = new Action() .setType("EMAIL") .setTitle("Email us") .setOpenUrlAction(new OpenUrlAction() .setUrl("mailto:person@example.com")); // Terms of service and order note String termsOfServiceUrl = "https://example.com"; String now = Instant.now().toString(); OrderV3 order = new OrderV3() .setCreateTime(now) .setLastUpdateTime(now) .setMerchantOrderId("UNIQUE_ORDER_ID") .setUserVisibleOrderId("UNIQUE_USER_VISIBLE_ORDER_ID") .setTransactionMerchant(transactionMerchant) .setContents(contents) .setBuyerInfo(buyerInfo) .setFollowUpActions(Arrays.asList( viewDetails, call, email )) .setTermsOfServiceUrl(termsOfServiceUrl); return order; }
ध्यान दें कि नीचे दिया गया JSON, वेबहुक रिस्पॉन्स के बारे में बताता है.
{ "payload": { "google": { "expectUserResponse": true, "systemIntent": { "intent": "actions.intent.TRANSACTION_DECISION", "data": { "@type": "type.googleapis.com/google.actions.transactions.v3.TransactionDecisionValueSpec", "order": { "createTime": "2019-07-17T18:25:30.182Z", "lastUpdateTime": "2019-07-17T18:25:30.182Z", "merchantOrderId": "UNIQUE_ORDER_ID", "userVisibleOrderId": "USER_VISIBLE_ORDER_ID", "transactionMerchant": { "id": "https://www.example.com", "name": "Example Merchant" }, "contents": { "lineItems": [ { "id": "LINE_ITEM_ID", "name": "Dinner reservation", "description": "A world of flavors all in one destination.", "reservation": { "status": "PENDING", "userVisibleStatusLabel": "Reservation is pending.", "type": "RESTAURANT", "reservationTime": { "timeIso8601": "2020-01-16T01:30:15.01Z" }, "userAcceptableTimeRange": { "timeIso8601": "2020-01-15/2020-01-17" }, "partySize": 6, "staffFacilitators": [ { "name": "John Smith" } ], "location": { "zipCode": "94086", "city": "Sunnyvale", "postalAddress": { "regionCode": "US", "postalCode": "94086", "administrativeArea": "CA", "locality": "Sunnyvale", "addressLines": [ "222, Some other Street" ] } } } } ] }, "buyerInfo": { "email": "janedoe@gmail.com", "firstName": "Jane", "lastName": "Doe", "displayName": "Jane Doe" }, "followUpActions": [ { "type": "VIEW_DETAILS", "title": "View details", "openUrlAction": { "url": "https://example.com" } }, { "type": "CALL", "title": "Call us", "openUrlAction": { "url": "tel:+16501112222" } }, { "type": "EMAIL", "title": "Email us", "openUrlAction": { "url": "mailto:person@example.com" } } ], "termsOfServiceUrl": "https://www.example.com" }, "orderOptions": { "requestDeliveryAddress": false, "userInfoOptions": { "userInfoProperties": [ "EMAIL" ] } }, "presentationOptions": { "actionDisplayName": "RESERVE" } } } } } }
3. आदेश प्रस्तावित करें
पुष्टि या अस्वीकार करने के लिए उपयोगकर्ता को अपना बुकिंग ऑर्डर दिखाएं. actions.intent.TRANSACTION_DECISION
इंटेंट का अनुरोध करें और वह Order
दें जिसे आपने बनाया है.
प्रयोक्ता अनुभव
जब आप actions.intent.TRANSACTION_DECISION
इंटेंट का अनुरोध करते हैं, तो Assistant पहले से मौजूद अनुभव देती है, जिसमें Order
को सीधे "कार्ट की झलक दिखाने वाले कार्ड" में रेंडर किया जाता है. उपयोगकर्ता "बुकिंग शेड्यूल करो" कह सकते हैं,
लेन-देन अस्वीकार कर सकते हैं या बुकिंग की जानकारी बदलने का अनुरोध कर सकते हैं.
इस समय, उपयोगकर्ता ऑर्डर में बदलाव करने का अनुरोध भी कर सकता है. इस मामले में, आपको यह पक्का करना चाहिए कि कार्ट असेंबली अनुभव पूरा करने के बाद आपका फ़ुलफ़िलमेंट, ऑर्डर में बदलाव के अनुरोधों को हैंडल कर सके.
ग्राहक का ऑर्डर पूरा करना
actions.intent.TRANSACTION_DECISION
इंटेंट का अनुरोध करने पर, ऐसा TransactionDecision
बनाएं जिसमें Order
और orderOptions
शामिल हों
इस कोड में, ऑर्डर के लिए TransactionsDecision
का उदाहरण दिया गया है:
conv.ask(new TransactionDecision({ orderOptions: { requestDeliveryAddress: 'false', }, presentationOptions: { actionDisplayName: 'RESERVE', }, order: order, }));
// Create order options OrderOptionsV3 orderOptions = new OrderOptionsV3() .setRequestDeliveryAddress(false) .setUserInfoOptions(new UserInfoOptions() .setUserInfoProperties(Collections.singletonList("EMAIL"))); // Create presentation options PresentationOptionsV3 presentationOptions = new PresentationOptionsV3() .setActionDisplayName("RESERVE"); // Ask for transaction decision return getResponseBuilder(request) .add("Placeholder for transaction decision text") .add(new TransactionDecision() .setOrder(order) .setOrderOptions(orderOptions) .setPresentationOptions(presentationOptions) ) .build();
ध्यान दें कि नीचे दिया गया JSON, वेबहुक रिस्पॉन्स के बारे में बताता है.
{ "payload": { "google": { "expectUserResponse": true, "systemIntent": { "intent": "actions.intent.TRANSACTION_DECISION", "data": { "@type": "type.googleapis.com/google.actions.transactions.v3.TransactionDecisionValueSpec", "orderOptions": { "requestDeliveryAddress": "false" }, "presentationOptions": { "actionDisplayName": "RESERVE" }, "order": { "createTime": "2019-07-17T18:25:30.184Z", "lastUpdateTime": "2019-07-17T18:25:30.184Z", "merchantOrderId": "UNIQUE_ORDER_ID", "userVisibleOrderId": "USER_VISIBLE_ORDER_ID", "transactionMerchant": { "id": "https://www.example.com", "name": "Example Merchant" }, "contents": { "lineItems": [ { "id": "LINE_ITEM_ID", "name": "Dinner reservation", "description": "A world of flavors all in one destination.", "reservation": { "status": "PENDING", "userVisibleStatusLabel": "Reservation is pending.", "type": "RESTAURANT", "reservationTime": { "timeIso8601": "2020-01-16T01:30:15.01Z" }, "userAcceptableTimeRange": { "timeIso8601": "2020-01-15/2020-01-17" }, "partySize": 6, "staffFacilitators": [ { "name": "John Smith" } ], "location": { "zipCode": "94086", "city": "Sunnyvale", "postalAddress": { "regionCode": "US", "postalCode": "94086", "administrativeArea": "CA", "locality": "Sunnyvale", "addressLines": [ "222, Some other Street" ] } } } } ] }, "buyerInfo": { "email": "janedoe@gmail.com", "firstName": "Jane", "lastName": "Doe", "displayName": "Jane Doe" }, "followUpActions": [ { "type": "VIEW_DETAILS", "title": "View details", "openUrlAction": { "url": "https://example.com" } }, { "type": "CALL", "title": "Call us", "openUrlAction": { "url": "tel:+16501112222" } }, { "type": "EMAIL", "title": "Email us", "openUrlAction": { "url": "mailto:person@example.com" } } ], "termsOfServiceUrl": "https://www.example.com" } } } } } }
ध्यान दें कि नीचे दिया गया JSON, वेबहुक रिस्पॉन्स के बारे में बताता है.
{ "expectUserResponse": true, "expectedInputs": [ { "possibleIntents": [ { "intent": "actions.intent.TRANSACTION_DECISION", "inputValueData": { "@type": "type.googleapis.com/google.actions.transactions.v3.TransactionDecisionValueSpec", "orderOptions": { "requestDeliveryAddress": "false" }, "presentationOptions": { "actionDisplayName": "RESERVE" }, "order": { "createTime": "2019-07-17T18:25:30.057Z", "lastUpdateTime": "2019-07-17T18:25:30.057Z", "merchantOrderId": "UNIQUE_ORDER_ID", "userVisibleOrderId": "USER_VISIBLE_ORDER_ID", "transactionMerchant": { "id": "https://www.example.com", "name": "Example Merchant" }, "contents": { "lineItems": [ { "id": "LINE_ITEM_ID", "name": "Dinner reservation", "description": "A world of flavors all in one destination.", "reservation": { "status": "PENDING", "userVisibleStatusLabel": "Reservation is pending.", "type": "RESTAURANT", "reservationTime": { "timeIso8601": "2020-01-16T01:30:15.01Z" }, "userAcceptableTimeRange": { "timeIso8601": "2020-01-15/2020-01-17" }, "partySize": 6, "staffFacilitators": [ { "name": "John Smith" } ], "location": { "zipCode": "94086", "city": "Sunnyvale", "postalAddress": { "regionCode": "US", "postalCode": "94086", "administrativeArea": "CA", "locality": "Sunnyvale", "addressLines": [ "222, Some other Street" ] } } } } ] }, "buyerInfo": { "email": "janedoe@gmail.com", "firstName": "Jane", "lastName": "Doe", "displayName": "Jane Doe" }, "followUpActions": [ { "type": "VIEW_DETAILS", "title": "View details", "openUrlAction": { "url": "https://example.com" } }, { "type": "CALL", "title": "Call us", "openUrlAction": { "url": "tel:+16501112222" } }, { "type": "EMAIL", "title": "Email us", "openUrlAction": { "url": "mailto:person@example.com" } } ], "termsOfServiceUrl": "https://www.example.com" } } } ] } ] }
लोगों का फ़ैसला मैनेज करें
जब उपयोगकर्ता सुझाए गए ऑर्डर का जवाब दे देता है, तो आपके फ़ुलफ़िलमेंट को
actions_intent_TRANSACTION_DECISION
इंटेंट के साथ एक तर्क के साथ
TransactionDecisionValue
मिलता है. इस वैल्यू में नीचे दी गई चीज़ें शामिल होंगी:
transactionDecision
- प्रस्तावित आदेश के बारे में उपयोगकर्ता का फ़ैसला. इसकी वैल्यूORDER_ACCEPTED
,ORDER_REJECTED
,CART_CHANGE_REQUESTED
, औरUSER_CANNOT_TRANSACT
हो सकती हैं.
इस अनुरोध को मैनेज करने के लिए, actions_intent_TRANSACTION_DECISION
इवेंट से ट्रिगर होने वाले Dialogflow इंटेंट का एलान करें. ज़रूरत पड़ने पर,
इस मकसद को पूरा करें:
const arg = conv.arguments.get('TRANSACTION_DECISION_VALUE'); if (arg && arg.transactionDecision === 'ORDER_ACCEPTED') { console.log('order accepted'); const order = arg.order; }
Argument transactionDecisionValue = request .getArgument("TRANSACTION_DECISION_VALUE"); Map<String, Object> extension = null; if (transactionDecisionValue != null) { extension = transactionDecisionValue.getExtension(); } String transactionDecision = null; if (extension != null) { transactionDecision = (String) extension.get("transactionDecision"); } if ((transactionDecision != null && transactionDecision.equals("ORDER_ACCEPTED"))) { OrderV3 order = ((OrderV3) extension.get("order")); }
ध्यान दें कि नीचे दिया गया JSON, वेबहुक अनुरोध के बारे में बताता है.
{ "responseId": "", "queryResult": { "queryText": "", "action": "", "parameters": {}, "allRequiredParamsPresent": true, "fulfillmentText": "", "fulfillmentMessages": [], "outputContexts": [], "intent": { "name": "reservation_get_transaction_decision_df", "displayName": "reservation_get_transaction_decision_df" }, "intentDetectionConfidence": 1, "diagnosticInfo": {}, "languageCode": "" }, "originalDetectIntentRequest": { "source": "google", "version": "2", "payload": { "isInSandbox": true, "surface": { "capabilities": [ { "name": "actions.capability.SCREEN_OUTPUT" }, { "name": "actions.capability.AUDIO_OUTPUT" }, { "name": "actions.capability.MEDIA_RESPONSE_AUDIO" }, { "name": "actions.capability.WEB_BROWSER" } ] }, "inputs": [ { "rawInputs": [], "intent": "", "arguments": [] } ], "user": {}, "conversation": {}, "availableSurfaces": [ { "capabilities": [ { "name": "actions.capability.SCREEN_OUTPUT" }, { "name": "actions.capability.AUDIO_OUTPUT" }, { "name": "actions.capability.MEDIA_RESPONSE_AUDIO" }, { "name": "actions.capability.WEB_BROWSER" } ] } ] } }, "session": "" }
ध्यान दें कि नीचे दिया गया JSON, वेबहुक अनुरोध के बारे में बताता है.
{ "user": {}, "device": {}, "surface": { "capabilities": [ { "name": "actions.capability.SCREEN_OUTPUT" }, { "name": "actions.capability.AUDIO_OUTPUT" }, { "name": "actions.capability.MEDIA_RESPONSE_AUDIO" }, { "name": "actions.capability.WEB_BROWSER" } ] }, "conversation": {}, "inputs": [ { "rawInputs": [], "intent": "reservation_get_transaction_decision_asdk", "arguments": [] } ], "availableSurfaces": [ { "capabilities": [ { "name": "actions.capability.SCREEN_OUTPUT" }, { "name": "actions.capability.AUDIO_OUTPUT" }, { "name": "actions.capability.MEDIA_RESPONSE_AUDIO" }, { "name": "actions.capability.WEB_BROWSER" } ] } ] }
4. बुकिंग की प्रक्रिया पूरी करें और रसीद भेजें
जब actions.intent.TRANSACTION_DECISION
इंटेंट, ORDER_ACCEPTED
के
transactionDecision
के साथ वापस आता है, तो रिज़र्वेशन को शेड्यूल करने के लिए
ज़रूरी प्रोसेसिंग को पूरा करें. जैसे, इसे अपने डेटाबेस में
बनाए रखना.
बातचीत जारी रखने के लिए, आसान जवाब भेजें. उपयोगकर्ता को आपके जवाब के साथ, एक "छोटा रसीद कार्ड" भी मिलता है.
ग्राहक का ऑर्डर पूरा करना
// Set lastUpdateTime and update status of reservation order.lastUpdateTime = new Date().toISOString(); order.reservation.status = 'CONFIRMED'; order.reservation.userVisibleStatusLabel = 'Reservation confirmed'; order.reservation.confirmationCode = '123ABCDEFGXYZ'; // Send synchronous order update conv.ask(`Transaction completed! You're all set!`); conv.ask(new OrderUpdate({ type: 'SNAPSHOT', reason: 'Reason string', order: order, }));
ResponseBuilder responseBuilder = getResponseBuilder(request); order.setLastUpdateTime(Instant.now().toString()); // Set reservation status to confirmed and provide confirmation code LineItemV3 lineItem = order.getContents().getLineItems().get(0); ReservationItemExtension reservationItemExtension = lineItem.getReservation(); reservationItemExtension.setStatus("CONFIRMED"); reservationItemExtension.setUserVisibleStatusLabel("Reservation confirmed."); reservationItemExtension.setConfirmationCode("123ABCDEFGXYZ"); lineItem.setReservation(reservationItemExtension); order.getContents().getLineItems().set(0, lineItem); // Order update OrderUpdateV3 orderUpdate = new OrderUpdateV3() .setType("SNAPSHOT") .setReason("Reason string") .setOrder(order); responseBuilder .add("Transaction completed! You're all set! Would you like to do anything else?") .add(new StructuredResponse().setOrderUpdateV3(orderUpdate)); return responseBuilder.build();
ध्यान दें कि नीचे दिया गया JSON, वेबहुक रिस्पॉन्स के बारे में बताता है.
{ "payload": { "google": { "expectUserResponse": true, "richResponse": { "items": [ { "simpleResponse": { "textToSpeech": "Transaction completed! You're all set!" } }, { "structuredResponse": { "orderUpdateV3": { "type": "SNAPSHOT", "reason": "Reason string", "order": { "merchantOrderId": "UNIQUE_ORDER_ID", "reservation": { "status": "CONFIRMED", "userVisibleStatusLabel": "Reservation confirmed", "confirmationCode": "123ABCDEFGXYZ" }, "lastUpdateTime": "2019-07-17T18:25:30.187Z" } } } } ] } } } }
ध्यान दें कि नीचे दिया गया JSON, वेबहुक रिस्पॉन्स के बारे में बताता है.
{ "expectUserResponse": true, "expectedInputs": [ { "possibleIntents": [ { "intent": "actions.intent.TEXT" } ], "inputPrompt": { "richInitialPrompt": { "items": [ { "simpleResponse": { "textToSpeech": "Transaction completed! You're all set!" } }, { "structuredResponse": { "orderUpdateV3": { "type": "SNAPSHOT", "reason": "Reason string", "order": { "merchantOrderId": "UNIQUE_ORDER_ID", "reservation": { "status": "CONFIRMED", "userVisibleStatusLabel": "Reservation confirmed", "confirmationCode": "123ABCDEFGXYZ" }, "lastUpdateTime": "2019-07-17T18:25:30.059Z" } } } } ] } } } ] }
5. ऑर्डर के अपडेट भेजें
इसके लाइफ़टाइम में रिज़र्वेशन की स्थिति बदल जाती है. एचटीटीपी पैच अनुरोधों के साथ, उपयोगकर्ता रिज़र्वेशन ऑर्डर के अपडेट, ऑर्डर की स्थिति और उससे जुड़ी जानकारी वाले ऑर्डर एपीआई को भेजें.
ऑर्डर एपीआई के लिए एसिंक्रोनस अनुरोध सेट अप करना
ऑर्डर एपीआई को ऑर्डर अपडेट करने के अनुरोधों को ऐक्सेस टोकन से अनुमति दी जाती है. ऑर्डर अपडेट को ऑर्डर एपीआई में पैच करने के लिए, अपने Actions Console प्रोजेक्ट से जुड़ा JSON सेवा खाता कुंजी डाउनलोड करें. इसके बाद, सेवा खाता कुंजी को एक ऐसे बेयरर टोकन से बदलें जिसे एचटीटीपी अनुरोध के Authorization
हेडर में भेजा जा सके.
सेवा खाते की कुंजी को वापस पाने के लिए, यह तरीका अपनाएं:
- Google Cloud कंसोल में, मेन्यू ≡ > एपीआई और सेवाएं > क्रेडेंशियल > क्रेडेंशियल बनाएं > सेवा खाता कुंजी पर जाएं.
- सेवा खाते में, नया सेवा खाता चुनें.
- सेवा खाते को
service-account
पर सेट करें. - भूमिका को प्रोजेक्ट > मालिक पर सेट करें.
- कुंजी के टाइप को JSON पर सेट करें.
- बनाएं चुनें.
- आपके कंप्यूटर पर एक निजी JSON सेवा खाता कुंजी डाउनलोड हो जाएगी.
अपने ऑर्डर अपडेट कोड में, Google API क्लाइंट लाइब्रेरी और "https://www.googleapis.com/auth/actions.order.developer" स्कोप का इस्तेमाल करके, अपनी सेवा कुंजी को बेयरर टोकन से बदलें. एपीआई क्लाइंट लाइब्रेरी के GitHub पेज पर, आपको इंस्टॉल करने के तरीके और उदाहरण मिल सकते हैं.
की-एक्सचेंज के उदाहरण के लिए, हमारे Node.js में order-update.js
और Java से जुड़े नमूने देखें.
ऑर्डर के अपडेट भेजें
अपनी सेवा खाता कुंजी को OAuth बेयर टोकन से बदलने के बाद, ऑर्डर से जुड़े अपडेट, अनुमति वाले PATCH अनुरोधों के तौर पर ऑर्डर एपीआई को भेजें.
ऑर्डर एपीआई यूआरएल:
PATCH https://actions.googleapis.com/v3/orders/${orderId}
अपने अनुरोध में ये हेडर दें:
"Authorization: Bearer token"
को OAuth बेयरर टोकन के साथ बदला गया है. इसके लिए, आपने अपनी सेवा खाता कुंजी का इस्तेमाल किया है."Content-Type: application/json"
.
PATCH अनुरोध को JSON फ़ॉर्मैट में इस तरह लिखा जाना चाहिए:
{ "orderUpdate": OrderUpdate }
OrderUpdate
ऑब्जेक्ट में, ये टॉप लेवल फ़ील्ड होते हैं:
updateMask
- ऑर्डर के वे फ़ील्ड जिन्हें अपडेट किया जा रहा है. बुकिंग की स्थिति अपडेट करने के लिए, वैल्यू कोreservation.status, reservation.userVisibleStatusLabel
पर सेट करें.order
- अपडेट का कॉन्टेंट. अगर बुकिंग के कॉन्टेंट अपडेट किए जा रहे हैं, तो अपडेट किए गएOrder
ऑब्जेक्ट पर वैल्यू सेट करें. अगर बुकिंग की स्थिति अपडेट की जा रही है, जैसे कि"PENDING"
से"FULFILLED"
में, तो ऑब्जेक्ट में ये फ़ील्ड शामिल होंगे:merchantOrderId
- वही आईडी जिसे आपने अपनेOrder
ऑब्जेक्ट में सेट किया है.lastUpdateTime
- इस अपडेट का टाइमस्टैंप.purchase
- एक ऑब्जेक्ट जिसमें ये चीज़ें शामिल हैं:status
- ऑर्डर की स्थितिReservationStatus
के तौर पर, जैसे कि "CONFIRMED
" या "CANCELLED
".userVisibleStatusLabel
- उपयोगकर्ता को दिखने वाला लेबल, जो ऑर्डर की स्थिति के बारे में जानकारी देता है, जैसे कि "आपकी बुकिंग हो गई है".
userNotification
ऑब्जेक्ट, जो यह अपडेट भेजे जाने के बाद, उपयोगकर्ता के डिवाइस पर दिख सकता है. ध्यान दें कि इस ऑब्जेक्ट को शामिल करने से यह गारंटी नहीं मिलती कि उपयोगकर्ता के डिवाइस पर सूचना दिखेगी.
इस सैंपल कोड में, OrderUpdate
का एक उदाहरण दिया गया है. इससे, रिज़र्वेशन ऑर्डर की स्थिति को FULFILLED
में अपडेट किया जाता है:
// Import the 'googleapis' module for authorizing the request. const {google} = require('googleapis'); // Import the 'request' module for sending an HTTP POST request. const request = require('request'); // Import the OrderUpdate class from the Actions on Google client library. const {OrderUpdate} = require('actions-on-google'); // Import the service account key used to authorize the request. Replace the string path with a path to your service account key. const key = require('./service-account.json'); // Create a new JWT client for the Actions API using credentials from the service account key. let jwtClient = new google.auth.JWT( key.client_email, null, key.private_key, ['https://www.googleapis.com/auth/actions.order.developer'], null ); // Authorize the client asynchronously, passing in a callback to run upon authorization. jwtClient.authorize((err, tokens) => { if (err) { console.log(err); return; } // Declare the ID of the order to update. const orderId = '<UNIQUE_MERCHANT_ORDER_ID>'; const orderUpdateJson = new OrderUpdate({ updateMask: [ 'lastUpdateTime', 'contents.lineItems.reservation.status', 'contents.lineItems.reservation.userVisibleStatusLabel', ].join(','), order: { merchantOrderId: orderId, lastUpdateTime: new Date().toISOString(), contents: { lineItems: [ { reservation: { status: 'FULFILLED', userVisibleStatusLabel: 'Reservation fulfilled', }, } ] } }, reason: 'Reservation status was updated to fulfilled.', }); // Set up the PATCH request header and body, including the authorized token // and order update. const bearer = 'Bearer ' + tokens.access_token; const options = { method: 'PATCH', url: `https://actions.googleapis.com/v3/orders/${orderId}`, headers: { 'Authorization': bearer, }, body: { header: { 'isInSandbox': true, }, orderUpdate: orderUpdateJson, }, json: true, }; // Send the PATCH request to the Orders API. request.patch(options, (err, httpResponse, body) => { if (err) { console.log('There was an error...'); console.log(err); return; } }); });
// Create order update FieldMask fieldMask = FieldMask.newBuilder().addAllPaths(Arrays.asList( "lastUpdateTime", "contents.lineItems.reservation.status", "contents.lineItems.reservation.userVisibleStatusLabel")) .build(); OrderUpdateV3 orderUpdate = new OrderUpdateV3() .setOrder(new OrderV3() .setMerchantOrderId(orderId) .setLastUpdateTime(Instant.now().toString()) .setContents(new OrderContents() .setLineItems(Collections.singletonList(new LineItemV3() .setReservation(new ReservationItemExtension() .setStatus("FULFILLED") .setUserVisibleStatusLabel("Reservation fulfilled.")))))) .setUpdateMask(FieldMaskUtil.toString(fieldMask)) .setReason("Reservation status was updated to fulfilled."); // Setup JSON body containing order update JsonParser parser = new JsonParser(); JsonObject orderUpdateJson = parser.parse(new Gson().toJson(orderUpdate)).getAsJsonObject(); JsonObject body = new JsonObject(); body.add("orderUpdate", orderUpdateJson); JsonObject header = new JsonObject(); header.addProperty("isInSandbox", true); body.add("header", header); StringEntity entity = new StringEntity(body.toString()); entity.setContentType(ContentType.APPLICATION_JSON.getMimeType()); request.setEntity(entity); // Make request HttpClient httpClient = HttpClientBuilder.create().build(); HttpResponse response = httpClient.execute(request);
बुकिंग की स्थिति सेट करना
किसी ऑर्डर के अपडेट के ReservationStatus
में, ऑर्डर की मौजूदा स्थिति के बारे में जानकारी होनी चाहिए. अपने अपडेट के order.ReservationStatus
फ़ील्ड में, इनमें से किसी एक वैल्यू का इस्तेमाल करें:
PENDING
- आपकी सेट की गई कार्रवाई ने बुकिंग को "बनाया" है. हालांकि, इसके लिए आपके बैक-एंड पर अतिरिक्त प्रोसेसिंग की ज़रूरत है.CONFIRMED
- आपके शेड्यूलिंग बैक-एंड में बुकिंग की पुष्टि हो जाती है.CANCELLED
- उपयोगकर्ता ने अपनी बुकिंग रद्द कर दी है.FULFILLED
- उपयोगकर्ता की बुकिंग, सेवा के ज़रिए पूरी की गई थी.CHANGE_REQUESTED
- उपयोगकर्ता ने बुकिंग में बदलाव का अनुरोध किया था और बदलाव को प्रोसेस किया जा रहा है.REJECTED
- अगर बुकिंग को प्रोसेस नहीं किया जा सका या किसी और तरीके से बुकिंग की पुष्टि नहीं की जा सकी, तो
अपनी बुकिंग के हिसाब से हर स्थिति के लिए, ऑर्डर के अपडेट भेजें. उदाहरण के लिए, अगर आपकी बुकिंग का अनुरोध किए जाने के बाद उसकी पुष्टि करने के लिए मैन्युअल तरीके से प्रोसेस करने की ज़रूरत है, तो अतिरिक्त प्रोसेसिंग पूरी होने तक PENDING
के ऑर्डर का अपडेट भेजें. हर बुकिंग के लिए, हर स्टेटस वैल्यू की ज़रूरत नहीं होती.
समस्या हल करना
अगर आपको जांच के दौरान कोई समस्या आती है, तो लेन-देन से जुड़ी समस्या हल करने का तरीका लेख पढ़ें.