Gdy klient prześle zamówienie na jedzenie, możesz powiadomić nas o zmianie, wysyłając wiadomość o aktualizacji zamówienia do usługi kompleksowej obsługi zamówień.
Oto kilka najczęstszych przyczyn wysyłania aktualizacji zamówień:
- Przewidywany czas realizacji zamówienia stanie się dostępny lub może ulec zmianie.
- Stan zamówienia ulegnie zmianie.
- Nie można już zrealizować zamówienia.
- Zmieniła się cena pozycji w menu uwzględnionej w zamówieniu.
- Klient ma nowy sposób zarządzania zamówieniami, np. obsługę klienta lub numer telefonu do restauracji.
- Potwierdzenie zamówienia stanie się dostępne.
Kolejne sekcje zawierają szczegółowe informacje o tym, jak zastosować aktualizacje w tych różnych sytuacjach.
Przenoszenie stanów zamówienia
Zamówienie może mieć 6 stanów. Te stany i ich możliwe przejścia przedstawiono na tym diagramie:
Gdy klient po raz pierwszy prześle zamówienie, ma ono stan CREATED
, CONFIRMED
lub REJECTED
. Możesz wysłać wiadomość z aktualizacją stanu zamówienia, o ile zmiana stanu będzie ważna. Stan CREATED
jest używany, gdy platforma partnera nie może od razu potwierdzić ani odrzucić zamówienia. Przykładem może być sytuacja, w której klient składa zamówienie przez pośrednika w dostawie. Agregator dostawy otrzymuje dostawę od Google, a pośrednik przesyła te informacje do restauracji. Gdy restauracja otrzyma
i potwierdzi dostępność zamówienia, stan może teraz wynosić CONFIRMED
. W przeciwnym razie
REJECTED
.
Następnie zamówienie w stanie CONFIRMED
przechodzi do stanu IN_PREPARATION
. W zależności od tego, czy zamówienie dotyczy odbioru czy dostawy, użyj stanu READY_FOR_PICKUP
lub IN_TRANSIT
. Gdy jedzenie zostało dostarczone lub odebrane, stan zamówienia jest ustawiany na FULFILLED
.
Jeśli zezwalasz klientom na anulowanie zamówień, możesz użyć stanu CANCELLED
. Zamówienie można anulować, jeśli jego stan to CREATED
, CONFIRMED
, IN_PREPARATION
, READY_FOR_PICKUP
lub IN_TRANSIT
.
Twoja kompleksowa usługa związana z zamawianiem powinna zwrócić środki w zależności od zasad anulowania i stanu płatności w momencie anulowania.
Kompleksowa usługa składania zamówień nie musi obsługiwać wszystkich dostępnych stanów i przejść. Ostatecznym stanem zamówienia musi być jednak FULFILLED
, REJECTED
lub CANCELLED
.
Podawanie szacowanego czasu realizacji
Możesz podać użytkownikom szacowany czas, kiedy ich zamówienie będzie gotowe do odbioru (lub dostarczonego). Użyj pola estimatedFulfillmentTimeIso8601
w polu FoodOrderUpdateExtension
, aby podać szacowany przedział czasu, w którym zamówienie klienta będzie gotowe do odbioru lub dostawy.
Wyślij estimatedFulfillmentTimeIso8601
w następujących godzinach:
- Kiedy dostępny będzie szacowany czas, najlepiej w kolejności
CREATED
lubCONFIRMED
. - Gdy zmieni się szacowany czas, na przykład zaktualizuje szacowany czas, aby był dokładniejszy, gdy zamówienie będzie
IN_TRANSIT
.
Aby skutecznie rozumieć oczekiwania użytkowników, stosuj ostrożne szacunki. Nie podawaj konkretnej daty ani godziny, podając tylko datę i godzinę. W miarę możliwości uwzględnij odmiany, takie jak warunki na drodze. Możesz na przykład wysłać szacunkową godzinę dostawy do 12:45 (dolna granica) do 13:15 (górna) w przypadku zamówienia, dla którego szacowany czas dostawy to 13:00.
Określanie działań związanych z zarządzaniem zamówieniami
Wysyłając aktualizację zamówienia, możesz udostępnić klientom zasoby, które pomogą im w zarządzaniu zamówieniem w postaci OrderManagementAction
. Gdy klient złoży zamówienie, być może będzie musiał skontaktować się z Tobą lub restauracją realizującą zamówienie, aby śledzić postępy, wprowadzić zmiany lub anulować zamówienie.
OrderManagementAction
pozwala klientom wysyłać e-maile, dzwonić i umieszczać linki do podstron bezpośrednio na urządzeniu. Użyj tych samych informacji w polu OrderManagementAction
co w e-mailu z potwierdzeniem zamówienia, który wysyłasz do użytkownika.
Działania zarządzania zamówieniami obejmują następujące typy:
CUSTOMER_SERVICE
: zachęć klientów do kontaktu z obsługą klienta. Ten typ czynności zarządzania jest wymagany do aktualizacji zamówień.EMAIL
: zachęć klientów do wysłania e-maila na podany adres e-mail.CALL
: zachęć klientów, by zadzwonili pod podany numer telefonu.VIEW_DETAIL
: umożliwia klientom wyświetlenie szczegółów zamówienia.
Każda aktualizacja zamówienia musi zawierać co najmniej jedno działanie związane z zarządzaniem zamówieniami. Dostępne działania związane z zarządzaniem zamówieniami mogą się jednak różnić w zależności od stanu zamówienia.
Jeśli na przykład zamówienie ma stan CONFIRMED
, działanie CUSTOMER_SERVICE
może wskazywać Twój numer telefonu do działu obsługi klienta. Gdy ten stan zamówienia zmieni się na IN_TRANSIT
, działanie CUSTOMER_SERVICE
może wskazywać numer telefonu restauracji realizującej zamówienie.
Wysyłam aktualizacje dotyczące zamówienia
Typ wiadomości AsyncOrderUpdateRequestMessage
służy do wysyłania aktualizacji zamówienia do usługi obejmującej cały proces sortowania. W odpowiedzi Google przesyła AsyncOrderUpdateResponseMessage
. Jeśli na przykład chcesz poinformować klienta, że jego 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 z aktualizacją zamówienia
Wysyłając AsyncOrderUpdateRequestMessage
do Google, musisz podać informacje o stanie zamówienia w polu OrderUpdate
.
W przykładach poniżej pokazujemy przykładowy element AsyncOrderUpdateRequestMessage
dla każdego stanu zamówienia:
POTWIERDZONO
Ten przykład przedstawia przykładowe żądanie aktualizacji zamówienia, w którym informuje użytkownika, że zamówienie zostało potwierdzone za pomocą potwierdzenia i przewidywanego czasu 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 przedstawia przykładowe żądanie aktualizacji zamówienia, które informuje użytkownika, że zamówienie zostało odrzucone z powodu 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 przedstawia przykładowe żądanie aktualizacji zamówienia, które powiadamia użytkownika, że zamówienie zostało anulowane z powodu 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" } } } ] } } }
IN_PREPARATION
Ten przykład przedstawia przykładowe żądanie aktualizacji zamówienia, które informuje użytkownika, ż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" } } } }
READY_FOR_PICKUP
Ten przykład pokazuje przykładowe żądanie aktualizacji zamówienia, które informuje użytkownika, że jedzenie jest gotowe do odbioru.
{ "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
Ten przykład przedstawia przykładowe żądanie aktualizacji zamówienia, które informuje użytkownika, że zamówienie jest w drodze, z przewidywanym czasem 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" } } } }
Zrealizowano
Ten przykład przedstawia przykładowe żądanie aktualizacji zamówienia, które informuje 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 o wdrażaniu zaawansowanych aktualizacji zamówień.
Wygeneruj token autoryzacji i wyślij wiadomość
Aktualizacje zamówień wymagają tokena autoryzacji, aby usługa kompleksowej obsługi zamówień mogła sprawdzić, czy wiadomość pochodzi z Twojej kompleksowej usługi internetowej do obsługi zamówień.
Aby wdrożyć aktualizacje zamówień w projekcie, wykonaj te czynności:
- Wygeneruj token autoryzacji, wykonując te czynności:
- Użyj biblioteki Google Auth Library, aby odczytać dane 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 POST HTTP do tego punktu końcowego:
https://actions.googleapis.com/v2/conversations:send
- W ramach żądania ustaw nagłówek
Content-Type
naapplication/json
.
Poniższe przykłady pokazują, jak wdrożyć aktualizacje zamówienia:
Node.js
Ten kod korzysta z biblioteki uwierzytelniania Google dla ś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
Ten kod korzysta z biblioteki uwierzytelniania Google na potrzeby Javy.
/** * 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 udanej aktualizacji zamówień bez błędów Google zwraca odpowiedź HTTP 200 z pustym ładunkiem. Jeśli wystąpił problem, na przykład nieprawidłowa aktualizacja, Google zwróci błąd.