お客様が料理の注文を送信した後、Order with Google サービスに注文更新メッセージを送信して、Google に変更を通知できます。
注文の更新を送信する一般的な理由は次のとおりです。
- 注文の配送予定時間が利用可能になるか、変わる。
- 注文の状態は変わります。
- ご注文の処理はできなくなりました。
- 注文に含まれるメニュー項目の価格が変更されました。
- 顧客は、カスタマー サポートやレストランの電話番号など、注文を管理する新しい方法を利用できます。
- 注文の領収書が利用できるようになります。
以降のセクションでは、注文の更新を使用してこれらのさまざまなシナリオに対処する方法について説明します。
移行状態
注文には次の 6 つのステータスがあります。次の図は、これらの状態と可能な遷移の概要を示しています。
お客様が初めて注文を送信すると、その注文のステータスは CREATED
、CONFIRMED
、または REJECTED
から始まります。状態遷移が有効である限り、注文更新メッセージを送信して注文の状態を更新できます。CREATED
状態は、パートナーのプラットフォームが注文をすぐに確認または拒否できない場合に使用します。ユースケースの例としては、顧客がデリバリー アグリゲータを使用して注文する場合が挙げられます。配送アグリゲータは Google から配信を受け取り、その情報をアグリゲータがレストランに送信します。レストランが注文の受け付けと確認が完了すると、状態は CONFIRMED
になります。それ以外の場合は REJECTED
になります。
次に、CONFIRMED
状態の注文は IN_PREPARATION
状態に移行します。注文の受け取りと受け取りのどちらのタイプにするかに応じて、READY_FOR_PICKUP
か IN_TRANSIT
のいずれかのステータスを使用します。料理が配達または集荷されると、注文のステータスは FULFILLED
に設定されます。
購入者が注文をキャンセルできるようにしている場合は、CANCELLED
ステータスを使用できます。CREATED
、CONFIRMED
、IN_PREPARATION
、READY_FOR_PICKUP
、または IN_TRANSIT
の状態の間は、注文をキャンセルできます。Order with Google サービスは、キャンセルのポリシーとキャンセル時の支払い状況に応じて払い戻しを行います。
Order with Google サービスは、使用可能なすべての状態と移行をサポートしている必要はありません。ただし、注文の最終状態は FULFILLED
、REJECTED
、CANCELLED
である必要があります。
フルフィルメントの目安をお届けする
注文した商品の受け取り(または配送)の準備が整うまでの推定所要時間をユーザーに提示できます。FoodOrderUpdateExtension
の estimatedFulfillmentTimeIso8601
フィールドを使用して、お客様の注文の受け取りと配送の準備が整うまでのおおよその期間を指定します。
次の時間に estimatedFulfillmentTimeIso8601
を送信します。
- 予定時刻が利用可能になったら、
CREATED
またはCONFIRMED
の順序ですることをおすすめします。 - 注文が
IN_TRANSIT
のときに、より正確な推定時刻を更新するなど、推定時刻が変化した場合。
ユーザーの期待を効果的に管理するには、予測を慎重に行い、固定された日付と時刻ではなく、日付と時刻の範囲を指定します。可能な限り、交通状況などの変動を考慮してください。たとえば、目安のお届け日数が午後 1 時である場合、見積もりの見積もりを午後 12 時 45 分(下限)から午後 1 時 15 分(上限)まで送信できます。
注文管理アクションを提供する
注文の更新を送信する際に、OrderManagementAction
の形式で注文を管理できるリソースを顧客に提供できます。注文後、注文の追跡や変更、キャンセルを行うには、注文を行ったショップやレストランに連絡する必要がある場合があります。
OrderManagementAction
を使用すると、デバイスでメール、通話、または URL へのリンクを直接行えます。OrderManagementAction
には、ユーザーに送信する注文確認と同じ情報を使用します。
注文管理の操作には次のタイプがあります。
CUSTOMER_SERVICE
: カスタマー サービスに問い合わせるアクションをお客様に提供します。注文を更新する場合は、この管理アクション タイプが必須です。EMAIL
: 指定されたメールアドレスにメールを送信するアクションをお客様に提供します。CALL
: 指定の電話番号に電話をかけるためのアクションをユーザーに示します。VIEW_DETAIL
: 注文の詳細を表示するアクションをお客様に提供します。
各注文更新には、少なくとも 1 つの注文管理アクションが含まれている必要があります。ただし、提供される注文管理アクションは、注文の状態によって異なります。
たとえば、注文のステータスが CONFIRMED
の場合、CUSTOMER_SERVICE
アクションでカスタマー サービスの電話番号を指定できます。注文ステータスが IN_TRANSIT
に更新されると、CUSTOMER_SERVICE
アクションでフルフィルメント レストランの電話番号を指定できます。
注文の更新を送信しています
Order with Google サービスに注文の更新を送信するには、AsyncOrderUpdateRequestMessage
メッセージ タイプを使用します。Google は AsyncOrderUpdateResponseMessage
で応答します。たとえば、注文が有効で受理されたことをお客様に伝えたい場合、AsyncOrderUpdateRequestMessage
ラベルを送信して、注文の状態をCONFIRMED
「Accepted by restaurant
」に変更できます。
注文更新メッセージの設定
AsyncOrderUpdateRequestMessage
を Google に送信する際は、OrderUpdate
フィールドを使用して注文の状態に関する情報を含める必要があります。
次の例は、注文状態ごとの AsyncOrderUpdateRequestMessage
の例を示しています。
CONFIRMED
この例は、領収書と配送予定日で注文が確定されたことをユーザーに通知する注文更新リクエストのサンプルです。
{ "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" } } } }
棄却
次の例は、注文が拒否されたことをユーザーに知らせる、注文更新リクエストのサンプルです。
{ "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." } ] } } } }
CANCELLED
この例では、注文がキャンセルされた理由をお客様に通知する注文更新リクエストの例を示しています。
{ "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" } } } ] } } }
準備中
この例は、現在料理の準備が進行中であることをユーザーに通知する注文更新リクエストのサンプルです。
{ "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(受け取り / 受け取り)
次の例は、料理の受け取り準備ができたことをユーザーに通知する注文更新リクエストのサンプルです。
{ "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
次の例は、注文が配送中であることをユーザーに伝える通知で、配送予定日を示しています。
{ "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
次の例は、注文が集荷または配達されたことをユーザーに通知する注文更新リクエストの例です。
{ "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" } } } ] } } }
さまざまなユースケースでの注文更新リクエストの例については、注文の高度な更新を実装するをご覧ください。
認証トークンを生成してメッセージを送信する
注文の更新には、Order with Google サービスが Google の Order with Google ウェブサービスから送信されたメッセージであることを確認するために、認証トークンが必要です。
プロジェクトの注文更新を実装する手順は次のとおりです。
- 次の手順で認証トークンを生成します。
- Google Auth ライブラリを使用して、サービス アカウント ファイルから認証情報を読み取ります。
- 次の API スコープを使用してトークンをリクエストします。
https://www.googleapis.com/auth/actions.fulfillment.conversation
- このトークンを使用して、認証済みの HTTP POST リクエストを次のエンドポイントに送信します。
https://actions.googleapis.com/v2/conversations:send
- リクエストの一部として、
Content-Type
ヘッダーをapplication/json
に設定します。
次の例は、注文の更新を実装する方法を示しています。
Node.js
このコードは、Node.js 用の Google 認証ライブラリを使用します。
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
このコードは、Python 用の Google 認証ライブラリを使用します。
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
このコードは、Java 用の 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",); }
注文が正常に更新されるとエラーがない場合は、ペイロードが空の HTTP 200 レスポンスが返されます。アップデートの形式が正しくないなどの問題があると、Google はエラーを返します。