Aktualizacja zamówienia asynchronicznego

Gdy klient prześle zamówienie jedzenia, możesz wysłać na adres kompleksowej usługi Ordering w celu powiadomienia nas o zmianie.

Oto kilka najczęstszych przyczyn wysyłania aktualizacji zamówień:

  • Szacowany czas realizacji zamówienia stanie się dostępny lub zmieni się.
  • Stan zamówienia się zmienia.
  • Nie można już zrealizować tego zamówienia.
  • Zmieniła się cena pozycji menu uwzględnionej w zamówieniu.
  • Klient ma nowy sposób zarządzania zamówieniem, na przykład obsługę klienta czy numer telefonu do restauracji.
  • Pojawi się potwierdzenie zamówienia.

Kolejne sekcje zawierają szczegółowe informacje na temat tego, jak poradzić sobie w tych różnych sytuacjach. za pomocą aktualizacji zamówień.

Przenoszenie stanów zamówień przeniesienia

Zamówienie może mieć 6 stanów. Te stany i ich możliwe przejścia przedstawiono na tym diagramie:

Przejścia stanu zamówienia

Gdy klient po raz pierwszy przesyła zamówienie, zaczyna się ono od CREATED, CONFIRMED lub REJECTED. Wiadomość z aktualizacją zamówienia możesz wysłać na adres aktualizują stan zamówienia, dopóki przejście między stanami jest prawidłowe. CREATED jest używany, gdy platforma partnera nie może potwierdzić ani odrzucić zamówienia natychmiast. Przykładem użycia jest sytuacja, w której klient składa zamówienie w dostawie agregatorowi treści. Agregator dostaw otrzymuje dostawę od Google, a agregator wysyła je do restauracji. Gdy restauracja otrzyma i potwierdzono dostępność zamówienia, stan może być teraz ustawiony na CONFIRMED, w przeciwnym razie REJECTED

Zamówienie o 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 zostanie dostarczone lub odebrane, stan zamówienia zostanie ustawiony na FULFILLED.

Jeśli zezwalasz klientom na anulowanie zamówień, możesz użyć stanu CANCELLED. Zamówienie można anulować w stanie CREATED, CONFIRMED, IN_PREPARATION, READY_FOR_PICKUP lub IN_TRANSIT. Kompleksowa usługa obsługi zamówień powinna zwracać środki w zależności od zasady anulowania oraz stan płatności w momencie anulowania.

Twoja kompleksowa usługa zamawiania nie musi obsługiwać wszystkich dostępnych stanów i przejścia. Ostatecznym stanem zamówienia musi być jednak FULFILLED, REJECTED, czy CANCELLED.

Podawanie szacunkowego czasu realizacji

Możesz podać użytkownikom szacowany czas realizacji zamówienia gotowe do odbioru (lub dostarczone). Korzystanie z pola estimatedFulfillmentTimeIso8601 FoodOrderUpdateExtension, aby wskazać szacowany zakres czasowy zamówienie klienta będzie gotowe do odbioru lub dostarczone.

Wyślij estimatedFulfillmentTimeIso8601 o tych godzinach:

  • Gdy będzie dostępny szacowany czas, najlepiej w takiej kolejności: CREATED lub CONFIRMED stan.
  • Gdy zmieni się szacowany czas, na przykład gdy zaktualizujesz szacunkowy czas dokładniejsze jest, jeśli zamówienie ma wartość IN_TRANSIT.

Aby skutecznie zarządzać oczekiwaniami użytkowników, ostrożnie traktuj szacunki i podaj zakres dat i godzin zamiast stałej daty i godziny. Zalecenia uwzględniania w miarę możliwości zmian, takich jak warunki na drodze. Dla: np. około 12:45 (dolna granica) możesz wysłać do 13:15 (górna granica) ) w przypadku zamówienia, którego przewidywany czas dostawy to 13:00.

Dostarczanie działań związanych z zarządzaniem zamówieniami

Wysyłając aktualizację dotyczącą zamówienia, możesz udostępnić klientom materiały, które pomogą zarządza swoim zamówieniem za pomocą karty OrderManagementAction. Po klient składa zamówienie, być może będzie musiał skontaktować się z Tobą lub restauracją zrealizowania zamówienia, aby śledzić postępy, wprowadzić zmiany lub anulować zamówienie.

OrderManagementAction umożliwia klientom wysłanie e-maila, nawiązanie połączenia lub wysłanie linku do bezpośrednio z urządzenia. Użyj tych samych informacji w: OrderManagementAction zgodnie z e-mailem z potwierdzeniem zamówienia, który wysyłasz do użytkownika.

Działania związane z zarządzaniem zamówieniami obejmują te rodzaje:

  • CUSTOMER_SERVICE: zachęć klientów do skontaktowania się z nim posprzedażna. Ten typ działania dotyczącego zarządzania jest wymagany do aktualizacji zamówienia.
  • EMAIL: zaoferuj klientom działanie, aby wysłać e-maila na podany adres adresu e-mail.
  • CALL: zachęć klientów, by zadzwonili pod podany numer telefonu.
  • VIEW_DETAIL: zachęć klientów do działania, aby wyświetlić szczegóły dotyczące zamówienie.

Każda aktualizacja zamówienia musi zawierać co najmniej 1 działanie związane z zarządzaniem zamówieniem. Pamiętaj jednak: podane działania związane z zarządzaniem zamówieniem mogą się różnić w zależności od jego stanu. Na przykład gdy zamówienie ma stan CONFIRMED, definicja CUSTOMER_SERVICE działanie może wskazywać numer telefonu obsługi klienta. Gdy ten stan zamówienia aktualizacji do IN_TRANSIT, działanie CUSTOMER_SERVICE może wskazywać numer telefonu restauracji świadczącej usługi.

Wysyłam aktualizacje dotyczące zamówienia

Do wysyłania zamówienia używasz wiadomości typu AsyncOrderUpdateRequestMessage aktualizację do kompleksowej usługi Ordering. W odpowiedzi Google przesyła AsyncOrderUpdateResponseMessage Jeśli na przykład chcesz poinformować ż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.

Schemat aktualizacji zamówienia

Ustawianie komunikatu o aktualizacji zamówienia

Wysyłając AsyncOrderUpdateRequestMessage do Google, musisz uwzględnić informacje o stanie zamówienia za pomocą pola OrderUpdate.

Poniższe przykłady pokazują przykład AsyncOrderUpdateRequestMessage dla: każdy stan zamówienia:

POTWIERDZONO

Ten przykład przedstawia przykładowe żądanie aktualizacji zamówienia, które powiadamia użytkownika że zamówienie jest potwierdzone za pomocą rachunku i szacowanej dostawy; obecnie się znajdujesz.

{
  "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"
      }
    }
  }
}
    

ODRZUCONE

Ten przykład przedstawia przykładowe żądanie aktualizacji zamówienia, które powiadamia 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."
        }
      ]
      }
    }
  }
}
    

ANULOWANO

Ten przykład przedstawia przykładowe żądanie aktualizacji zamówienia, które powiadamia użytkownika o tym, ż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 powiadamia użytkownika że żywność jest obecnie przygotowywana.

{
  "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 przedstawia przykładowe żądanie aktualizacji zamówienia, które powiadamia 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 powiadamia użytkownika że zamówienie jest w drodze, z szacowanym 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"
      }
    }
  }
}
  

FULFILLED

Ten przykład przedstawia przykładowe żądanie aktualizacji zamówienia, które powiadamia 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ówienia w różnych przypadkach użycia znajdziesz w artykule Wprowadź zaawansowane aktualizacje zamówień.

Wygeneruj token autoryzacji i wyślij wiadomość

Aktualizacje zamówienia wymagają tokena autoryzacji, aby kompleksowe zamówienie może sprawdzić, czy wiadomość pochodzi z Twojej kompleksowej usługi do składania zamówień.

Aby wdrożyć aktualizacje zamówień w projekcie, wykonaj te czynności:

  1. Aby wygenerować token autoryzacji:
    1. Odczytuj dane logowania z usługi za pomocą biblioteki uwierzytelniania Google konta.
    2. Poproś o token, używając tego zakresu interfejsu API: https://www.googleapis.com/auth/actions.fulfillment.conversation
  2. Użyj tego tokena, aby wysłać uwierzytelnione żądanie HTTP POST do ten punkt końcowy: https://actions.googleapis.com/v2/conversations:send
  3. W ramach żądania ustaw nagłówek Content-Type na application/json.
.

Poniższe przykłady pokazują, jak wdrożyć aktualizacje zamówienia:

Node.js

Ten kod korzysta z biblioteki uwierzytelniania Google dla 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 dla 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 dla języka 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",);
}
    

W przypadku pomyślnej aktualizacji zamówienia bez błędów Google zwraca odpowiedź HTTP 200. z pustym ładunkiem. Jeśli wystąpił problem, na przykład aktualizacja nieprawidłowy format, Google zwraca błąd.