고객이 음식 주문을 제출하면 주문 엔드 투 엔드 서비스에 연락하여 변경사항을 알립니다.
주문 업데이트를 전송하는 일반적인 이유는 다음과 같습니다.
- 주문의 예상 처리 시간이 가능해지거나 변경됩니다.
- 주문 상태가 변경됩니다.
- 더 이상 주문을 처리할 수 없습니다.
- 주문에 포함된 메뉴 항목의 가격이 변경됨
- 고객이 고객 지원팀과 같이 주문을 관리할 수 있는 새로운 방법을 사용할 수 있음 음식점 전화번호 등입니다.
- 주문 영수증이 제공됩니다.
다음 섹션에서는 이러한 다양한 시나리오를 해결하는 방법을 자세히 설명합니다. 주문 업데이트 사용
주문 상태 전환
주문에는 6가지 상태가 있습니다. 이러한 상태와 가능한 전환 아래 다이어그램에 요약되어 있습니다.
고객이 주문을 처음 제출하면 주문이
CREATED
, CONFIRMED
또는 REJECTED
입니다. 다음으로 주문 업데이트 메시지를 보낼 수 있습니다.
주문 상태를 업데이트할 수 없습니다. CREATED
상태는 파트너 플랫폼에서 주문을 확인하거나 거부할 수 없는 경우 사용됩니다.
즉시 삭제할 수 있습니다 사용 사례 예시는 고객이 배송을 통해 주문하는 경우입니다.
애그리게이터입니다. 게재 애그리게이터가 Google로부터 게재를 수신하며
애그리게이터가 음식점에 정보를 보냅니다. 음식점이
주문 가능 여부를 확인하면 이제 상태는 CONFIRMED
가 될 수 있습니다. 그렇지 않으면 상태가 CONFIRMED
가 될 수 있습니다.
REJECTED
입니다.
CONFIRMED
상태의 주문은 다음으로 IN_PREPARATION
상태로 이동합니다. 주문의 수령 또는 배달 여부에 따라 READY_FOR_PICKUP
또는 IN_TRANSIT
상태를 사용합니다. 음식이 배달되거나 수령되면 주문이 FULFILLED
상태로 설정됩니다.
고객이 주문 취소를 허용하는 경우 CANCELLED
상태를 사용할 수 있습니다. CREATED
, CONFIRMED
, IN_PREPARATION
, READY_FOR_PICKUP
또는 IN_TRANSIT
상태에서는 주문을 취소할 수 있습니다.
주문 엔드 투 엔드 서비스는
취소 정책 및 취소 시점의 결제 상태
주문 엔드 투 엔드 서비스가 사용 가능한 모든 상태를 지원할 필요는 없습니다.
사용할 수 있습니다. 하지만 주문의 최종 상태는 반드시 FULFILLED
여야 합니다.
REJECTED
또는 CANCELLED
입니다.
예상 처리 시간 제공
사용자에게 주문 상품이 배송될 예상 기간을 제공할 수 있습니다.
수령 준비 완료 (또는 배송 완료) estimatedFulfillmentTimeIso8601
필드 사용
이를 FoodOrderUpdateExtension
로 설정하여
고객의 주문 수령 또는 배송이 준비됩니다.
다음 시점에 estimatedFulfillmentTimeIso8601
를 전송합니다.
- 예상 시간을 사용할 수 있게 되면
CREATED
또는CONFIRMED
상태입니다. - 예상 시간이 변경되는 경우(예: 예상 시간을
IN_TRANSIT
일 때 더 정확합니다.
사용자 기대치를 효과적으로 관리하려면 추정치를 보수적으로 계산해야 합니다. 고정된 날짜 및 시간이 아닌 날짜 및 시간 범위를 제공합니다. 해야 할 일 가능하면 교통상황 등의 변화를 고려하세요. 대상 예를 들어 오후 12시 45분 (하한)을 오후 1시 15분 (상한)으로 예상 배송 시간이 오후 1시인 주문의 경우,
주문 관리 작업 제공
주문 업데이트를 보낼 때 고객에게 주문 업데이트를 전송하는 데 도움이 되는 리소스를
OrderManagementAction
형식으로 주문을 관리합니다.
고객이 주문을 하면 판매자나 음식점에 문의해야 할 수 있습니다.
진행 상황 추적, 변경 또는 취소를 위해 주문을 이행합니다.
OrderManagementAction
를 사용하면 고객이 이메일, 전화 또는 링크를 통해
기기에서 바로 URL을 사용할 수 있습니다. 동일한 정보를
OrderManagementAction
있습니다.
주문 관리 작업에는 다음 유형이 포함됩니다.
CUSTOMER_SERVICE
: 고객에게 연락할 수 있는 작업 제공 있습니다. 주문 업데이트에 이 관리 작업 유형이 필수입니다.EMAIL
: 고객에게 제공된 이메일 주소로 이메일을 보낼 수 있는 작업 제공 이메일 주소를 입력하세요.CALL
: 고객에게 제공된 전화번호로 전화를 걸 수 있는 작업을 제공합니다.VIEW_DETAIL
: 고객에게 세부정보를 볼 수 있는 작업 제공 있습니다.
각 주문 업데이트에는 하나 이상의 주문 관리 작업이 포함되어야 합니다. 하지만
제공된 주문 관리 작업은 주문 상태에 따라 다를 수 있습니다.
예를 들어 주문이 CONFIRMED
상태인 경우 CUSTOMER_SERVICE
액션이 고객 서비스 전화번호를 가리킬 수 있습니다. 주문 상태가
IN_TRANSIT
로 업데이트되는 경우 CUSTOMER_SERVICE
작업은
찾을 수 없습니다.
주문 업데이트 전송
AsyncOrderUpdateRequestMessage
메시지 유형을 사용하여 주문을 전송합니다.
주문 엔드 투 엔드 서비스로 업데이트합니다 Google은
AsyncOrderUpdateResponseMessage
예를 들어
고객에게 주문이 유효하고 수락되었음을 확인한 경우
AsyncOrderUpdateRequestMessage
: 주문 상태를 CONFIRMED
로 변경
라벨이 Accepted by restaurant
인 항목을 찾습니다.
주문 업데이트 메시지 설정
Google에 AsyncOrderUpdateRequestMessage
을 보낼 때 다음을 포함해야 합니다.
주문 상태에 대한 정보를 OrderUpdate
필드를 사용하여 입력합니다.
다음 예는 AsyncOrderUpdateRequestMessage
를 보여주는 샘플입니다.
확인할 수 있습니다.
확정됨
이 예는 사용자에게 주문 업데이트 요청을 알리는 샘플 주문 업데이트 요청입니다. 영수증과 예상 배송일을 통해 주문을 확인할 수 있음 있습니다.
{ "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" } } } ] } } }
IN_PREPARATION
이 예는 사용자에게 주문 업데이트 요청을 알리는 샘플 주문 업데이트 요청입니다. 음식이 현재 준비되고 있습니다.
{ "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" } } } }
배송 중
이 예는 사용자에게 주문 업데이트 요청을 알리는 샘플 주문 업데이트 요청입니다. 주문 상품이 배송 중이며 예상 배송 기간이 표시됩니다.
{ "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" } } } }
완료됨
이 예는 사용자에게 주문 업데이트 요청을 알리는 샘플 주문 업데이트 요청입니다. 주문 상품을 수령하거나 배송했음을 알립니다.
{ "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" } } } ] } } }
다양한 사용 사례의 주문 업데이트 요청 예시를 더 확인하려면 다음을 참고하세요. 고급 주문 업데이트를 구현합니다.
승인 토큰 생성 및 메시지 전송
주문 업데이트에는 주문 엔드 투 엔드 메시지가 주문 엔드 투 엔드 웹 서비스에서 온 것인지 확인할 수 있습니다.
프로젝트의 주문 업데이트를 구현하려면 다음 단계를 따르세요.
- 다음 단계에 따라 승인 토큰을 생성합니다.
<ph type="x-smartling-placeholder">
- </ph>
- Google 인증 라이브러리를 사용하여 서비스에서 사용자 인증 정보 읽기 계정 파일.
- 다음 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용 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",); }
오류 없이 주문이 성공적으로 업데이트되면 Google에서 HTTP 200 응답을 반환합니다. 빈 페이로드가 있습니다 문제가 발생한 경우(예: 업데이트 중 형식이 잘못된 경우 Google에서 오류를 반환합니다.