Dopo che un cliente ha inviato un ordine di cibo, puoi inviare un messaggio di aggiornamento dell'ordine a al servizio end-to-end dell'ordine per informarci della modifica.
Di seguito sono riportati alcuni motivi comuni per l'invio di aggiornamenti sugli ordini:
- Il tempo di evasione stimato per l'ordine diventa disponibile o cambia.
- Lo stato di un ordine cambia.
- L'ordine non può più essere evaso.
- Il prezzo di una voce del menu inclusa nell'ordine è cambiato.
- Il cliente ha a disposizione un nuovo modo per gestire il proprio ordine, ad esempio contattare l'assistenza clienti o il numero di telefono del ristorante.
- La ricevuta dell'ordine diventa disponibile.
Le sezioni successive forniscono dettagli su come affrontare questi diversi scenari usando gli aggiornamenti degli ordini.
Transizione degli stati degli ordini
Un ordine ha sei stati possibili. Questi stati e le loro possibili transizioni sono descritti nel diagramma seguente:
Quando un cliente invia un ordine per la prima volta, l'ordine inizia con lo stato
CREATED
, CONFIRMED
o REJECTED
. Puoi inviare un messaggio di aggiornamento sull'ordine a
aggiornare lo stato di un ordine purché la transizione di stato sia valida. CREATED
viene utilizzato quando la piattaforma del partner non può confermare o rifiutare l'ordine
immediatamente. Un esempio di caso d'uso è quando un cliente effettua un ordine tramite una consegna
aggregatore. L'aggregatore di consegne riceve la consegna da Google e
l'aggregatore invia le informazioni al ristorante. Una volta che il ristorante ha ricevuto
e ha confermato la disponibilità dell'ordine, lo stato ora può essere CONFIRMED
, altrimenti
REJECTED
.
Successivamente, un ordine nello stato CONFIRMED
passa allo stato IN_PREPARATION
. A seconda che l'ordine sia per il ritiro o la consegna, utilizza lo stato READY_FOR_PICKUP
o IN_TRANSIT
. Quando il cibo è stato consegnato o ritirato, l'ordine viene impostato sullo stato FULFILLED
.
Se consenti ai clienti di annullare gli ordini, puoi utilizzare lo stato CANCELLED
. Un ordine può essere annullato se si trova in stato CREATED
, CONFIRMED
, IN_PREPARATION
, READY_FOR_PICKUP
o IN_TRANSIT
.
Il servizio end-to-end per l'ordine dovrebbe emettere rimborsi in base al
le norme sugli annullamenti e lo stato dei pagamenti al momento dell'annullamento.
Il tuo servizio end-to-end per gli ordini non deve supportare tutti gli stati disponibili
e transizioni. Tuttavia, lo stato finale dell'ordine deve essere FULFILLED
,
REJECTED
o CANCELLED
.
Specificare un tempo di evasione stimato
Puoi fornire agli utenti un intervallo di tempo stimato per il momento in cui verrà effettuato l'ordine
disponibili per il ritiro (o la consegna). Utilizza il campo estimatedFulfillmentTimeIso8601
di FoodOrderUpdateExtension
per fornire un intervallo di tempo stimato per quando
l'ordine del cliente sarà pronto per il ritiro o la consegna.
Invia estimatedFulfillmentTimeIso8601
al seguente orario:
- Quando il tempo stimato diventa disponibile, idealmente nell'ordine
CREATED
o StatoCONFIRMED
. - Quando l'orario stimato cambia, ad esempio l'aggiornamento del tempo stimato entro il
più preciso quando l'ordine è
IN_TRANSIT
.
Per gestire in modo efficace le aspettative degli utenti, adotta un approccio conservativo nelle stime e fornisci un intervallo di date e ore anziché una data e un'ora fisse. Dovresti quando possibile, tieni conto delle variazioni, ad esempio le condizioni del traffico. Per Ad esempio, puoi inviare una stima delle 12:45 (limite inferiore) alle 13:15 (limite superiore) vincolato) per un ordine in cui il tempo di consegna stimato è pari alle 13:00.
Fornitura di azioni di gestione degli ordini
Quando invii un aggiornamento dell'ordine, puoi fornire ai clienti risorse utili per
possono gestire il proprio ordine sotto forma di OrderManagementAction
. Dopo un
se il cliente effettua un ordine, potrebbe dover contattare te o il ristorante
completare l'ordine per monitorare l'avanzamento, apportare modifiche o annullare l'ordine.
Un OrderManagementAction
consente ai clienti di inviare email, chiamare o collegarsi a un
URL direttamente dal suo dispositivo. Utilizza le stesse informazioni in
OrderManagementAction
come indicato nell'email di conferma dell'ordine che invii alla
utente.
Le azioni di gestione degli ordini includono i seguenti tipi:
CUSTOMER_SERVICE
: fornisci ai clienti un'azione per contattarli completamente gestito di Google Cloud. Questo tipo di azione di gestione è obbligatorio per gli aggiornamenti degli ordini.EMAIL
: fornisci ai clienti un'azione per inviare un'email all'indirizzo fornito .CALL
: fornisci ai clienti un'azione per chiamare il numero di telefono fornito.VIEW_DETAIL
: fornisci ai clienti un'azione per visualizzare i dettagli della loro ordine.
Ogni aggiornamento dell'ordine deve contenere almeno un'azione di gestione degli ordini. Tuttavia,
le azioni di gestione degli ordini fornite possono variare in base allo stato dell'ordine.
Ad esempio, quando un ordine è nello stato CONFIRMED
, il valore CUSTOMER_SERVICE
azione può rimandare al numero di telefono dell'assistenza clienti. Quando lo stato dell'ordine
aggiornamenti a IN_TRANSIT
, l'azione CUSTOMER_SERVICE
può indirizzare
numero di telefono del ristorante che si occupa dell'evasione degli ordini.
Invio di aggiornamenti sugli ordini
Utilizzi il tipo di messaggio AsyncOrderUpdateRequestMessage
per inviare un ordine
al servizio end-to-end Ordine. Google risponde con un
AsyncOrderUpdateResponseMessage
. Ad esempio, se vuoi informare un
che il suo ordine è valido e accettato, puoi inviare un
AsyncOrderUpdateRequestMessage
per modificare lo stato dell'ordine in CONFIRMED
con l'etichetta Accepted by restaurant
.
Impostazione del messaggio di aggiornamento dell'ordine
Quando invii un AsyncOrderUpdateRequestMessage
a Google, devi includere
informazioni sullo stato dell'ordine utilizzando il campo OrderUpdate
.
I seguenti esempi mostrano un esempio di AsyncOrderUpdateRequestMessage
per
ciascuno stato dell'ordine:
CONFERMATA
Questo esempio mostra una richiesta di aggiornamento dell'ordine di esempio che comunica all'utente che l'ordine sia confermato con una ricevuta e una consegna stimata nel tempo.
{ "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" } } } }
RIFIUTATA
Questo esempio mostra una richiesta di aggiornamento dell'ordine di esempio che comunica all'utente che l'ordine viene rifiutato con un motivo di rifiuto.
{ "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." } ] } } } }
CANCELLATO
Questo esempio mostra una richiesta di aggiornamento dell'ordine di esempio che comunica all'utente che l'ordine viene annullato con un motivo di annullamento.
{ "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
Questo esempio mostra una richiesta di aggiornamento dell'ordine di esempio che comunica all'utente che il cibo viene preparato in quel momento.
{ "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
Questo esempio mostra una richiesta di aggiornamento dell'ordine di esempio che comunica all'utente che il cibo sia pronto per essere ritirato.
{ "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
Questo esempio mostra una richiesta di aggiornamento dell'ordine di esempio che comunica all'utente che l'ordine è in transito con i tempi di consegna stimati.
{ "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
Questo esempio mostra una richiesta di aggiornamento dell'ordine di esempio che comunica all'utente che l'ordine viene ritirato o consegnato:
{ "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" } } } ] } } }
Per altri esempi di richieste di aggiornamento degli ordini in diversi casi d'uso, leggi Implementa aggiornamenti avanzati sugli ordini.
Genera il token di autorizzazione e invia il messaggio
Gli aggiornamenti dell'ordine richiedono un token di autorizzazione può verificare che il messaggio provenga dal tuo servizio web end-to-end per gli ordini.
Per implementare gli aggiornamenti dell'ordine per il progetto, segui questi passaggi:
- Genera un token di autorizzazione seguendo questa procedura:
- Utilizza la libreria di autenticazione Google per leggere le credenziali dal servizio dell'account di servizio.
- Richiedi il token utilizzando il seguente ambito API:
https://www.googleapis.com/auth/actions.fulfillment.conversation
- Utilizza questo token per inviare una richiesta POST HTTP autenticata al
seguente endpoint:
https://actions.googleapis.com/v2/conversations:send
- Imposta l'intestazione
Content-Type
suapplication/json
come parte della richiesta.
I seguenti esempi mostrano come implementare gli aggiornamenti degli ordini:
Node.js
Questo codice utilizza la libreria di autenticazione di Google per 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
Questo codice utilizza la libreria di autenticazione di Google per 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
Questo codice utilizza la libreria di autenticazione di Google per 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",); }
Per gli aggiornamenti dell'ordine riusciti senza errori, Google restituisce una risposta HTTP 200 con un payload vuoto. Se si è verificato un problema, ad esempio la rimozione non valido, Google restituisce un errore.