Gdy klient przesyła zamówienie jedzenia, możesz wysłać do niego wiadomość o aktualizacji zamówienia, aby powiadomić nas o zmianie.
Oto kilka częstych przyczyn wysyłania aktualizacji zamówień:
- Szacowany czas realizacji zamówienia będzie dostępny lub się zmieni.
- Zmieni się stan zamówienia.
- Nie można już zrealizować zamówienia.
- Zmieniła się cena dania w menu dołączonego do zamówienia.
- Klient ma nowy sposób zarządzania zamówieniami, np. obsługę klienta czy numer telefonu do restauracji.
- Potwierdzenie zamówienia zostanie udostępnione.
W kolejnych sekcjach znajdziesz szczegółowe informacje o tym, jak rozwiązywać te problemy przy użyciu aktualizacji zamówień.
Przejściowe stany zamówień
Zamówienie może mieć 6 stanów. Te stany i ich możliwe przejście zostały opisane na tym diagramie:
Gdy klient przesyła zamówienie po raz pierwszy, zamówienie rozpoczyna się od CREATED
, CONFIRMED
lub REJECTED
. Możesz wysłać wiadomość o aktualizacji zamówienia, aby zaktualizować jego stan, o ile migracja stanu jest prawidłowa. Stan CREATED
jest używany, gdy platforma partnera nie może potwierdzić ani odrzucić zamówienia. Przykładem może być sytuacja, gdy klient zamawia za pomocą agregatora dostaw. Agregator odbierający dostarcza dane z Google i agregator wysyła je do restauracji. Gdy restauracja otrzyma i potwierdzi dostępność zamówienia, stan będzie się zmieniał na CONFIRMED
, w przeciwnym razie – REJECTED
.
Zamówienie w stanie CONFIRMED
przechodzi później do stanu IN_PREPARATION
. W zależności od tego, czy zamówienie obejmuje odbiór czy dostawę, zastosuj stan READY_FOR_PICKUP
lub IN_TRANSIT
. Po dostarczeniu lub odebraniu jedzenia zamówienie ma stan FULFILLED
.
Jeśli zezwalasz klientom na anulowanie zamówień, możesz używać stanu CANCELLED
. Zamówienie można anulować, jeśli ma stan CREATED
, CONFIRMED
, IN_PREPARATION
, READY_FOR_PICKUP
lub IN_TRANSIT
.
Zwrot środków za pomocą usługi Zamów przez Google powinien być zależny od zasad anulowania zamówień i stanu płatności w momencie anulowania.
Usługa Zamów przez Google nie musi obsługiwać wszystkich dostępnych stanów i procesów przenoszenia. Ostatnim stanem zamówienia musi być FULFILLED
, REJECTED
lub CANCELLED
.
Podawanie szacowanego czasu realizacji
Możesz podać użytkownikom szacowany przedział czasu, w którym ich zamówienie będzie gotowe do odbioru (lub dostarczenia). W polu estimatedFulfillmentTimeIso8601
w polu FoodOrderUpdateExtension
podaj szacowany przedział czasu, w którym zamówienie klienta będzie gotowe do odbioru lub dostawy.
Wyślij estimatedFulfillmentTimeIso8601
w następujących momentach:
- Gdy szacowany czas będzie dostępny, najlepiej w kolejności
CREATED
lubCONFIRMED
. - gdy szacowany czas się zmieni, np. zaktualizuje szacowany czas, aby zwiększyć dokładność, gdy zamówienie jest
IN_TRANSIT
.
Aby wydajnie zarządzać oczekiwaniami użytkowników, zachowawczo ustal szacunki i podawaj daty oraz godziny, a nie stałe daty i godziny. Jeśli to możliwe, uwzględniaj różne odmiany, np. warunki na drodze. Na przykład szacowaną godzinę 12:45 (dolną granicę) możesz wysłać do 13:15 (górna granica) w przypadku zamówienia, w przypadku którego szacowany czas dostawy to 13:00.
Wykonywanie działań związanych z zarządzaniem zamówieniami
Wysyłając aktualizację zamówienia, możesz udostępnić zasoby klientom, aby pomóc im w zarządzaniu zamówieniami w formie OrderManagementAction
. Gdy klient złoży zamówienie, może potrzebować kontaktu z Tobą lub z restauracją, która realizuje zamówienie, aby śledzić postęp, wprowadzić zmiany lub anulować zamówienie.
OrderManagementAction
pozwala klientom wysyłać e-maile, dzwonić i dodawać linki do adresów URL bezpośrednio z urządzenia. Podaj te same informacje w OrderManagementAction
, które znajdziesz w e-mailu z potwierdzeniem zamówienia wysłanym do użytkownika.
Do działań związanych z zarządzaniem zamówieniami należą:
CUSTOMER_SERVICE
: zachęcenie klientów do skontaktowania się z obsługą klienta. Ten typ zarządzania jest wymagany do aktualizowania zamówień.EMAIL
: przekaż klientom działanie, aby wysłać e-maila na podany adres.CALL
: wyświetlaj klientom działanie, które pozwala zadzwonić pod podany numer telefonu.VIEW_DETAIL
: przekaż klientom działanie, aby wyświetlić szczegóły zamówienia.
Każda aktualizacja zamówienia musi zawierać co najmniej jedno działanie zarządzania zamówieniem. Podane czynności zarządzania zamówieniami mogą się jednak różnić w zależności od stanu zamówienia.
Jeśli np. zamówienie ma stan CONFIRMED
, działanie CUSTOMER_SERVICE
może wskazywać numer telefonu do obsługi klienta. Gdy stan zamówienia zmieni się na IN_TRANSIT
, działanie CUSTOMER_SERVICE
może wskazywać numer telefonu restauracji realizacji.
Wysyłam aktualizacje zamówień
Typ wiadomości AsyncOrderUpdateRequestMessage
służy do wysyłania aktualizacji zamówień do usługi Zamów przez Google. Odpowiedź Google zawiera odpowiedź AsyncOrderUpdateResponseMessage
. Jeśli na przykład chcesz poinformować klienta, że zamówienie jest prawidłowe i zaakceptowane, możesz wysłać AsyncOrderUpdateRequestMessage
, aby zmienić stan zamówienia na CONFIRMED
z etykietą Accepted by restaurant
.
Ustawianie komunikatu o aktualizacji zamówienia
Przesyłając AsyncOrderUpdateRequestMessage
do Google, w polu OrderUpdate
musisz podać informacje o stanie zamówienia.
W tych przykładach widać przykładowe AsyncOrderUpdateRequestMessage
dla każdego stanu zamówienia:
POTWIERDZONO
Ten przykład pokazuje żądanie aktualizacji zamówienia, które informuje użytkownika o potwierdzeniu zamówienia wraz z szacowanym czasem dostawy.
{ "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" } } } }
ODRZUCONO
Ten przykład pokazuje żądanie aktualizacji zamówienia powiadamiające użytkownika o odrzuceniu zamówienia z przyczyną odrzucenia.
{ "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." } ] } } } }
ANULOWANY
Ten przykład pokazuje żądanie aktualizacji zamówienia, które informuje użytkownika o anulowaniu zamówienia z powodu jego anulowania.
{ "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" } } } ] } } }
W_PRZYPADKU
Ten przykład pokazuje żądanie aktualizacji zamówienia, które powiadamia użytkownika o tym, że jedzenie jest obecnie przygotowywane.
{ "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" } } } }
GOTOWE_DO_ODBIORU
Ten przykład pokazuje żądanie aktualizacji zamówienia, które informuje użytkownika, że jedzenie można odebrać.
{ "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" } } } }
Transport publiczny
Ten przykład pokazuje żądanie aktualizacji zamówienia, które informuje użytkownika o tym, że zamówienie jest w drodze, oraz szacowanego czasu dostawy.
{ "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" } } } }
SPEŁNIONE
W tym przykładowym żądaniu aktualizacji zamówienia powiadamiamy użytkownika, że zamówienie zostało odebrane lub dostarczone:
{ "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" } } } ] } } }
Więcej przykładów żądań aktualizacji zamówień w różnych przypadkach użycia znajdziesz w artykule Implementowanie zaawansowanych aktualizacji zamówień.
Wygeneruj token autoryzacji i wyślij wiadomość
Aktualizacje zamówień wymagają tokena autoryzacji, aby usługa Order with Google mogła zweryfikować, czy wiadomość pochodzi z usługi internetowej Zamów przez Google.
Aby wdrożyć aktualizacje zamówienia w projekcie, wykonaj te czynności:
- Wygeneruj token autoryzacji, wykonując te czynności:
- Użyj biblioteki uwierzytelniania Google do odczytania danych logowania z pliku konta usługi.
- Poproś o token, używając tego zakresu interfejsu API:
https://www.googleapis.com/auth/actions.fulfillment.conversation
- Użyj tego tokena, aby wysłać uwierzytelnione żądanie HTTP POST do tego punktu końcowego:
https://actions.googleapis.com/v2/conversations:send
- W żądaniu ustaw nagłówek
Content-Type
naapplication/json
.
Poniższe przykłady pokazują, jak wdrożyć aktualizacje zamówień:
Node.js
W tym kodzie używana jest biblioteka uwierzytelniania Google na potrzeby środowiska 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
Ten kod korzysta z biblioteki uwierzytelniania Google na potrzeby Pythona.
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
W tym kodzie używana jest biblioteka uwierzytelniania Google.
/** * 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",); }
W przypadku pomyślnych aktualizacji zamówień bez błędów Google zwraca odpowiedź HTTP 200 z pustym ładunkiem. Jeśli wystąpił problem, np. nieprawidłowa aktualizacja aktualizacji, Google zwróci błąd.