비동기 순서 업데이트

고객이 음식 주문을 제출하면 주문 엔드 투 엔드 서비스에 연락하여 변경사항을 알립니다.

주문 업데이트를 전송하는 일반적인 이유는 다음과 같습니다.

  • 주문의 예상 처리 시간이 가능해지거나 변경됩니다.
  • 주문 상태가 변경됩니다.
  • 더 이상 주문을 처리할 수 없습니다.
  • 주문에 포함된 메뉴 항목의 가격이 변경됨
  • 고객이 고객 지원팀과 같이 주문을 관리할 수 있는 새로운 방법을 사용할 수 있음 음식점 전화번호 등입니다.
  • 주문 영수증이 제공됩니다.

다음 섹션에서는 이러한 다양한 시나리오를 해결하는 방법을 자세히 설명합니다. 주문 업데이트 사용

주문 상태 전환

주문에는 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"
            }
          }
        }
      ]
    }
  }
}
    

다양한 사용 사례의 주문 업데이트 요청 예시를 더 확인하려면 다음을 참고하세요. 고급 주문 업데이트를 구현합니다.

승인 토큰 생성 및 메시지 전송

주문 업데이트에는 주문 엔드 투 엔드 메시지가 주문 엔드 투 엔드 웹 서비스에서 온 것인지 확인할 수 있습니다.

프로젝트의 주문 업데이트를 구현하려면 다음 단계를 따르세요.

  1. 다음 단계에 따라 승인 토큰을 생성합니다. <ph type="x-smartling-placeholder">
      </ph>
    1. Google 인증 라이브러리를 사용하여 서비스에서 사용자 인증 정보 읽기 계정 파일.
    2. 다음 API 범위를 사용하는 요청 토큰: https://www.googleapis.com/auth/actions.fulfillment.conversation
  2. 이 토큰을 사용하여 인증된 HTTP POST 요청을 다음 엔드포인트: https://actions.googleapis.com/v2/conversations:send
  3. 요청의 일부로 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에서 오류를 반환합니다.