В этом руководстве рассказывается, как разработать проект Actions, в котором для бронирования используется Orders API.
Процесс транзакции
Когда ваш проект Actions обрабатывает бронирования, он использует следующий процесс:
- Проверка требований к транзакциям (необязательно). Используйте помощник по требованиям к транзакциям в начале разговора, чтобы убедиться, что пользователь может выполнить транзакцию.
- Оформление заказа. Пользователь выбирает детали бронирования.
- Предложите заказ. Когда "корзина" будет заполнена, предложите пользователю "заказ" на бронирование, чтобы он мог подтвердить, что все верно. Если бронирование подтверждено, вы получите ответ со сведениями о бронировании.
- Завершите заказ и отправьте чек. После подтверждения заказа обновите систему бронирования и отправьте пользователю чек.
- Отправка обновлений заказа. На протяжении всего времени действия бронирования отправляйте пользователю обновления статуса бронирования, отправляя запросы PATCH в Orders API.
Ограничения и правила проверки
Обратите внимание, что к действиям, использующим API транзакций и заказов, применяются дополнительные правила. Проверка действий с транзакциями может занять до шести недель, поэтому учитывайте это при планировании графика выпуска. Чтобы упростить процесс проверки, убедитесь, что вы соблюдаете правила и рекомендации по транзакциям, прежде чем отправлять действие на проверку.
Развертывать действия, использующие Orders API, можно только в следующих странах:
|
Австралия Бразилия Индонезия Канада |
Япония Мексика Катар Россия |
Сингапур США Таиланд Турция Швейцария Япония |
Создайте проект
Подробный пример транзакционных разговоров можно найти в примере транзакций в Node.js.
Настройка
При создании действия необходимо указать в консоли Actions, что вы хотите выполнять транзакции.
Чтобы настроить проект и выполнение, сделайте следующее:
- Создайте новый проект или импортируйте существующий.
- Перейдите в раздел Развертывание > Информация для каталога.
В разделе Дополнительная информация > Транзакции установите флажок "Используют ли ваши действия Transactions API для продажи физических товаров?".

Проверка требований к транзакциям (необязательно)
Как только пользователь сообщит, что хочет забронировать столик, проверьте, может ли он это сделать. Например, при вызове действие может спросить: "Хотите забронировать место?" Если пользователь отвечает "да", вы должны убедиться, что он может продолжить, и дать ему возможность исправить любые настройки, мешающие ему продолжить транзакцию. Для этого нужно перейти к сцене, которая выполняет проверку требований к транзакции.
Создание сцены для проверки требований к транзакциям
- На вкладке Сцены добавьте новую сцену с названием
TransactionRequirementsCheck. - В разделе Заполнение слотов нажмите +, чтобы добавить новый слот.
- В разделе Выбрать тип выберите
actions.type.TransactionRequirementsCheckResultв качестве типа рекламного места. - В поле названия укажите
TransactionRequirementsCheck. - Установите флажок Настроить перезапись значения слота (по умолчанию он установлен).
Нажмите Сохранить.

Проверка требований к транзакциям может иметь один из следующих результатов:
- Если требования выполнены, параметр сеанса устанавливается с условием успешного выполнения, и вы можете продолжить оформление заказа пользователя.
- Если одно или несколько требований не выполняются, параметр сеанса устанавливается с условием сбоя. В этом случае вам следует перевести разговор
от транзакционного опыта или завершить разговор.
- Если пользователь может устранить ошибки, которые привели к сбою, ему будет предложено сделать это на устройстве. Если разговор происходит на устройстве, поддерживающем только голосовое взаимодействие, пользователю будет предложено продолжить его на телефоне.
Обработка результатов проверки требований к транзакции
- На вкладке Сцены выберите созданную сцену
TransactionRequirementsCheck. - В разделе Условие нажмите +, чтобы добавить новое условие.
В текстовом поле введите следующий синтаксис условия, чтобы проверить условие успешного выполнения:
scene.slots.status == "FINAL" && session.params.TransactionRequirementsCheck.resultType == "CAN_TRANSACT"Наведите указатель мыши на только что добавленное условие и нажмите на стрелку вверх, чтобы поместить его перед условием
if scene.slots.status == "FINAL".Включите параметр Отправлять подсказки и добавьте простую подсказку, которая сообщит пользователю, что он готов совершить транзакцию.
candidates: - first_simple: variants: - speech: >- Looks like you're good to go!.В разделе Переход выберите другую сцену, чтобы пользователь мог продолжить разговор и совершить транзакцию.

Выберите условие
else if scene.slots.status == "FINAL".Включите параметр Send prompts (Отправлять подсказки) и добавьте простую подсказку, которая будет сообщать пользователю, что он не может выполнить транзакцию:
candidates: - first_simple: variants: - speech: Transaction requirements check failed.В разделе Переход выберите Завершить разговор, чтобы завершить разговор, если пользователь не может совершать транзакции.

Создание заказа
Получив нужную информацию о пользователе, создайте интерфейс, который поможет ему оформить бронирование. Процесс сборки корзины может немного отличаться в зависимости от сервиса.
В базовом варианте пользователь выбирает варианты из списка, чтобы добавить их в бронирование. Однако вы можете упростить процесс, разработав специальный диалог. Например, создайте процесс сборки корзины, который позволит пользователю запланировать ежемесячное бронирование с помощью простого вопроса "да" или "нет". Вы также можете показать пользователю карусель или список рекомендуемых бронирований.
Рекомендуем использовать подробные ответы, чтобы наглядно представить пользователю доступные варианты, но при этом построить диалог так, чтобы пользователь мог собрать корзину, используя только голос. Рекомендации и примеры оформления корзины можно найти в руководстве по дизайну.
Как создать заказ
В ходе разговора соберите информацию о бронировании и создайте объект Order.
В Order должны быть указаны следующие сведения:
buyerInfo– информация о пользователе, совершающем покупку.transactionMerchant– информация о продавце, который выполнил заказ.contents– фактическое содержимое заказа, указанное какlineItems.
Чтобы создать корзину, ознакомьтесь с документацией по ответу Order. Обратите внимание, что в зависимости от типа бронирования вам может потребоваться включить разные поля.
Ниже приведен образец кода для полного заказа бронирования, включая необязательные поля.
const order = {
createTime: '2019-09-24T18:00:00.877Z',
lastUpdateTime: '2019-09-24T18:00:00.877Z',
merchantOrderId: orderId, // A unique ID String for the order
userVisibleOrderId: orderId,
transactionMerchant: {
id: 'http://www.example.com',
name: 'Example Merchant',
},
contents: {
lineItems: [
{
id: 'LINE_ITEM_ID',
name: 'Dinner reservation',
description: 'A world of flavors all in one destination.',
reservation: {
status: 'PENDING',
userVisibleStatusLabel: 'Reservation is pending.',
type: 'RESTAURANT',
reservationTime: {
timeIso8601: '2020-01-16T01:30:15.01Z',
},
userAcceptableTimeRange: {
timeIso8601: '2020-01-15/2020-01-17',
},
partySize: 6,
staffFacilitators: [
{
name: 'John Smith',
},
],
location: {
zipCode: '94086',
city: 'Sunnyvale',
postalAddress: {
regionCode: 'US',
postalCode: '94086',
administrativeArea: 'CA',
locality: 'Sunnyvale',
addressLines: [
'222, Some other Street',
],
},
},
},
},
],
},
buyerInfo: {
email: 'janedoe@gmail.com',
firstName: 'Jane',
lastName: 'Doe',
displayName: 'Jane Doe',
},
followUpActions: [
{
type: 'VIEW_DETAILS',
title: 'View details',
openUrlAction: {
url: 'http://example.com',
},
},
{
type: 'CALL',
title: 'Call us',
openUrlAction: {
url: 'tel:+16501112222',
},
},
{
type: 'EMAIL',
title: 'Email us',
openUrlAction: {
url: 'mailto:person@example.com',
},
},
],
termsOfServiceUrl: 'http://www.example.com'
};
Как создать заказ и настроить его показ
const orderOptions = {
'requestDeliveryAddress': false,
};
const presentationOptions = {
'actionDisplayName': 'RESERVE'
};
Сохранять данные о заказах в параметре сеанса
Сохраните данные заказа в параметре сеанса. Объект order будет использоваться в разных сценах одного сеанса.
conv.session.params.order = {
'@type': 'type.googleapis.com/google.actions.transactions.v3.TransactionDecisionValueSpec',
order: order,
orderOptions: orderOptions,
presentationOptions: presentationOptions
};
Предложите заказ
После создания заказа на бронирование вы должны представить его пользователю для подтверждения или отклонения. Для этого нужно перейти к сцене, которая принимает решение о транзакции.
Создание сцены Transaction Decision
- На вкладке Сцены добавьте новую сцену с названием
TransactionDecision. - В разделе Заполнение слотов нажмите +, чтобы добавить новый слот.
- В разделе Select type (Выбрать тип) выберите
actions.type.TransactionDecisionValueв качестве типа слота. - В поле названия укажите
TransactionDecision. - Установите флажок Настроить перезапись значения слота (по умолчанию он установлен).
- В разделе Настройка ячейки выберите в раскрывающемся списке Использовать параметр сеанса.
- В разделе Настройка слота введите в текстовое поле название параметра сеанса, который используется для хранения заказа (например,
$session.params.order). Нажмите Сохранить.

При попытке заполнить слот TransactionDecisionValue Ассистент запускает встроенную функцию, в которой переданный вами объект Order отображается непосредственно на карточке предварительного просмотра корзины. Пользователь может сказать "Забронируй", отказаться от транзакции или попросить изменить сведения о бронировании.
На этом этапе пользователь также может запросить изменения в заказе. В этом случае убедитесь, что ваш сервис выполнения заказов может обрабатывать запросы на изменение заказа после завершения сборки корзины.
Обработка результата Transaction Decision
Когда слот TransactionDecisionValue будет заполнен, ответ пользователя на вопрос о решении по транзакции будет сохранен в параметре сеанса. Это значение содержит следующее:
ORDER_ACCEPTED,ORDER_REJECTED,CART_CHANGE_REQUESTEDUSER_CANNOT_TRANSACT.
Чтобы обработать результат решения о транзакции, выполните следующие действия:
- На вкладке Сцены выберите созданную сцену
TransactionDecision. - В разделе Условие нажмите +, чтобы добавить новое условие.
В текстовом поле введите следующий синтаксис условия, чтобы проверить условие успешного выполнения:
scene.slots.status == "FINAL" && session.params.TransactionDecision.transactionDecision == "ORDER_ACCEPTED"Наведите указатель мыши на только что добавленное условие и нажмите на стрелку вверх, чтобы поместить его перед условием
if scene.slots.status == "FINAL".Включите параметр Отправлять подсказки и добавьте простую подсказку, которая сообщит пользователю, что бронирование завершено.
candidates: - first_simple: variants: - speech: >- Transaction completed! Your reservation $session.params.TransactionDecision.order.merchantOrderId is all set!В разделе Переход выберите Завершить разговор.

В разделе Условие нажмите +, чтобы добавить новое условие.
В текстовом поле введите следующий синтаксис условия, чтобы проверить условия сбоя:
scene.slots.status == "FINAL" && session.params.TransactionDecision.transactionDecision == "ORDER_REJECTED"Наведите указатель мыши на только что добавленное условие и нажмите на стрелку вверх, чтобы поместить его перед условием
if scene.slots.status == "FINAL".Включите параметр Отправлять подсказки и добавьте простую подсказку, которая сообщит пользователю, что заказ отклонен.
candidates: - first_simple: variants: - speech: Looks like you don't want to set up a reservation. Goodbye.В разделе Переход выберите Завершить разговор.
Выберите условие
else if scene.slots.status == "FINAL".Включите параметр Отправлять подсказки и добавьте простую подсказку, которая будет сообщать пользователю, что он не может совершить транзакцию.
candidates: - first_simple: variants: - speech: >- Transaction failed with status $session.params.TransactionDecision.transactionDecisionВ разделе Переход выберите Завершить разговор, чтобы завершить разговор, если пользователь не может совершать транзакции.

Завершите бронирование и отправьте квитанцию
Если слот TransactionDecisionValue возвращает результат ORDER_ACCEPTED, вы должны немедленно выполнить все необходимые действия, чтобы запланировать бронирование (например, сохранить его в своей базе данных).
Отправьте простой ответ, чтобы продолжить разговор. Пользователь получит свернутую карточку чека вместе с вашим ответом.
Чтобы отправить первое обновление заказа, выполните следующие действия:
- На вкладке Сцены выберите сцену
TransactionDecision. В разделе Условие выберите условие, которое проверяет успешный результат,
ORDER_ACCEPTED:scene.slots.status == "FINAL" && session.params.TransactionDecision.transactionDecision == "ORDER_ACCEPTED"Для этого условия включите параметр Call your webhook (Вызвать вебхук) и укажите название обработчика намерений, например
update_order.
В коде вебхука добавьте обработчик намерений для отправки первоначального обновления заказа:
app.handle('update_order', conv => { const currentTime = new Date().toISOString(); let order = conv.session.params.TransactionDecision.order; conv.add(new OrderUpdate({ 'updateMask': { 'paths': [ 'reservation.status', 'reservation.user_visible_status_label', 'reservation.confirmation_code' ] }, 'order': { 'merchantOrderId': order.merchantOrderId, 'lastUpdateTime': currentTime, 'reservation': { 'status': 'CONFIRMED', 'userVisibleStatusLabel': 'Reservation confirmed', 'confirmationCode': '123ABCDEFGXYZ', }, }, 'reason': 'Reason string' })); });
Отправлять обновления заказов
Статус резервирования меняется в течение его жизненного цикла. Отправьте пользователю обновленные данные о бронировании с помощью HTTP-запросов PATCH к Orders API, содержащих статус и сведения о заказе.
Как настроить асинхронные запросы к Orders API
Запросы на обновление заказов, отправляемые в Orders API, авторизуются с помощью токена доступа. Чтобы отправить запрос PATCH в Orders API, скачайте ключ сервисного аккаунта JSON, связанный с вашим проектом в консоли Actions, а затем обменяйте его на токен на предъявителя, который можно передать в заголовке Authorization HTTP-запроса.
Чтобы получить ключ сервисного аккаунта, выполните следующие действия:
- В консоли Google Cloud выберите Меню ☰ > API и сервисы > Учетные данные > Создать учетные данные > Ключ сервисного аккаунта.
- В разделе Service Account (Сервисный аккаунт) выберите New Service Account (Новый сервисный аккаунт).
- Установите для сервисного аккаунта значение
service-account. - В поле Role (Роль) выберите Project (Проект) > Owner (Владелец).
- В качестве типа ключа выберите JSON.
- Нажмите Создать.
- Закрытый ключ сервисного аккаунта в формате JSON будет скачан на ваш компьютер.
В коде обновления заказов обменяйте ключ сервиса на токен на предъявителя, используя клиентскую библиотеку API Google и область действия "https://www.googleapis.com/auth/actions.order.developer". Инструкции по установке и примеры можно найти на странице клиентской библиотеки API-клиента в GitHub.
Пример обмена ключами можно найти в примере кода Node.js (см. order-update.js).
Отправлять уведомления о заказах
После того как вы обменяете ключ сервисного аккаунта на токен на предъявителя OAuth, отправьте обновления заказов в виде авторизованных запросов PATCH в Orders API.
URL Orders API:
PATCH https://actions.googleapis.com/v3/orders/${orderId}
В запросе укажите следующие заголовки:
"Authorization: Bearer token"токеном на предъявителя OAuth, на который вы обменяли ключ сервисного аккаунта."Content-Type: application/json".
Запрос PATCH должен содержать тело JSON следующего формата:
{ "orderUpdate": OrderUpdate }Объект OrderUpdate состоит из следующих полей верхнего уровня:
updateMask– поля заказа, которые вы обновляете. Чтобы обновить статус бронирования, укажите значениеreservation.status, reservation.userVisibleStatusLabel.order– содержимое обновления. Если вы обновляете содержимое бронирования, задайте значение для обновленного объектаOrder. Если вы просто обновляете статус бронирования (например, с"PENDING"на"FULFILLED"), объект содержит следующие поля:merchantOrderId– тот же идентификатор, который вы указали в объектеOrder.lastUpdateTime– временная метка обновления.purchase– объект, содержащий следующие элементы:status– статус заказа в видеReservationStatus, например "CONFIRMED" или "CANCELLED".userVisibleStatusLabel– пользовательский ярлык с информацией о состоянии заказа, например "Ваше бронирование подтверждено".
userNotification(необязательно) – объектuserNotification, который может показываться на устройстве пользователя при отправке этого обновления. Обратите внимание, что включение этого объекта не гарантирует, что уведомление появится на устройстве пользователя.
В приведенном ниже образце кода показано, как OrderUpdate обновляет статус заказа на бронирование до FULFILLED:
// Import the 'googleapis' module for authorizing the request.
const {google} = require('googleapis');
// Import the 'request-promise' module for sending an HTTP POST request.
const request = require('request-promise');
// Import the OrderUpdate class from the client library.
const {OrderUpdate} = require('@assistant/conversation');
// Import the service account key used to authorize the request.
// Replacing the string path with a path to your service account key.
// i.e. const serviceAccountKey = require('./service-account.json')
// Create a new JWT client for the Actions API using credentials
// from the service account key.
let jwtClient = new google.auth.JWT(
serviceAccountKey.client_email,
null,
serviceAccountKey.private_key,
['https://www.googleapis.com/auth/actions.order.developer'],
null,
);
// Authorize the client
let tokens = await jwtClient.authorize();
// Declare the ID of the order to update.
const orderId = '<UNIQUE_MERCHANT_ORDER_ID>';
// Declare order update
const orderUpdate = new OrderUpdate({
updateMask: {
paths: [
'contents.lineItems.reservation.status',
'contents.lineItems.reservation.userVisibleStatusLabel'
]
},
order: {
merchantOrderId: orderId, // Specify the ID of the order to update
lastUpdateTime: new Date().toISOString(),
contents: {
lineItems: [
{
reservation: {
status: 'FULFILLED',
userVisibleStatusLabel: 'Reservation fulfilled',
},
}
]
},
},
reason: 'Reservation status was updated to fulfilled.',
});
// Set up the PATCH request header and body,
// including the authorized token and order update.
let options = {
method: 'PATCH',
uri: `https://actions.googleapis.com/v3/orders/${orderId}`,
auth: {
bearer: tokens.access_token,
},
body: {
header: {
isInSandbox: true,
},
orderUpdate,
},
json: true,
};
// Send the PATCH request to the Orders API.
try {
await request(options);
} catch (e) {
console.log(`Error: ${e}`);
}
Как задать статус резервирования
Значение ReservationStatus в обновлении заказа должно описывать текущее состояние заказа. В поле order.ReservationStatus укажите одно из следующих значений:
PENDING– бронирование создано действием, но требуется дополнительная обработка на сервере.CONFIRMED– бронирование подтверждено в вашей системе планирования.CANCELLED– пользователь отменил бронирование.FULFILLED– бронирование пользователя было выполнено сервисом.CHANGE_REQUESTED– пользователь запросил изменение бронирования, и запрос обрабатывается.REJECTED– если вы не смогли обработать или иным образом подтвердить бронирование.
Отправляйте обновления заказа для каждого статуса, который относится к вашему бронированию. Например, если для подтверждения бронирования требуется ручная обработка, отправьте обновление заказа PENDING, пока она не будет завершена. Не для каждого бронирования требуются все значения статуса.
Протестируйте проект
При тестировании проекта вы можете включить режим тестовой среды в консоли Actions, чтобы проверить работу Действия без списания средств со способа оплаты. Чтобы включить режим тестовой среды, выполните следующие действия:
- В консоли Actions нажмите Test (Тестирование) на панели навигации.
- Нажмите Настройки.
- Включите параметр Тестовая среда для разработки.
Для физических транзакций вы также можете задать для поля isInSandbox значение true в своем образце. Это действие эквивалентно включению режима тестовой среды в консоли Actions. Фрагмент кода с использованием isInSandbox приведен в разделе Отправка обновлений заказа.
Устранение неполадок
Если во время тестирования у вас возникнут проблемы, ознакомьтесь с инструкциями по устранению неполадок.