Crear reservas

En esta guía, se explica el proceso de desarrollo de un proyecto de Actions que usa la API de Orders para realizar reservas.

Flujo de transacción

Cuando tu proyecto de Acciones controla las reservas, usa el siguiente flujo:

  1. Valida los requisitos para las transacciones (opcional): Usa las transacciones. el asistente de requisitos al comienzo de la conversación para asegurarte de que usuario es capaz de realizar una transacción.
  2. Crea el orden: explícale al usuario “montaje de carrito” donde construyen los detalles de su reserva.
  3. Proponer el pedido: Una vez que el "carrito" aparezca esté completo, proponga el "orden" de la reserva a para que el usuario confirme que es correcto. Si la reserva está confirmada, y recibirás una respuesta con detalles de la reserva.
  4. Finalizar el pedido y enviar el recibo: Una vez confirmado el pedido, actualiza a tu sistema de reservas y enviarle un recibo al usuario.
  5. Enviar actualizaciones de pedidos: Durante el ciclo de vida de la reserva, proporcionar al usuario actualizaciones del estado de la reserva enviando solicitudes PATCH al API de Orders.

Restricciones y lineamientos de revisión

Tenga en cuenta que se aplican políticas adicionales a las Acciones que utilizan las transacciones y la API de Orders. La revisión de Acciones puede demorar hasta seis semanas. con las transacciones, así que ten en cuenta ese tiempo cuando planifiques tu programa de lanzamientos. Para facilitar el proceso de revisión, asegúrate de cumplir con las políticas y lineamientos para las transacciones antes de enviar tu Acción para su revisión.

Solo puedes implementar Acciones que usen la API de Orders en los siguientes países:

Australia
Brasil
Canadá
Indonesia
Japón
México
Catar
Rusia
Singapur
Suiza
Tailandia
Türkiye
Reino Unido
Estados Unidos

Cómo compilar un proyecto

Para obtener un ejemplo exhaustivo de las conversaciones transaccionales, consulta la sección Transacciones en Node.js.

Configuración

Cuando crees tu Acción, debes especificar que quieres realizar transacciones en la Consola de Actions.

Para configurar tu proyecto y entrega, haz lo siguiente:

  1. Crea un proyecto nuevo o importa uno existente.
  2. Navega a Implementar > Información del directorio.
  3. En Información adicional > Transacciones > marca la casilla que dice "Realiza tus acciones usar la API de Transactions para realizar transacciones de bienes físicos?".

Valida los requisitos de las transacciones (opcional).

En cuanto el usuario indique que desea configurar una reserva, debes verificar de que pueden solicitar una reserva. Por ejemplo, cuando se invoca, tu Action podría pregunta: "¿Te gustaría reservar un lugar?" Si el usuario dice "sí", deberías asegurarse de que puedan continuar y darles la oportunidad de corregir cualquier configuración lo que evita que continúen con la transacción. Para ello, debes transición a una escena que realice una verificación de los requisitos de la transacción.

Crea una escena de verificación de requisitos de la transacción

  1. En la pestaña Scenes, agrega una escena nueva con el nombre. TransactionRequirementsCheck
  2. En Relleno de ranuras, haz clic en + para agregar un espacio nuevo.
  3. En Seleccionar tipo, selecciona actions.type.TransactionRequirementsCheckResult. como el tipo de ranura.
  4. En el campo del nombre del espacio, asígnale el nombre TransactionRequirementsCheck.
  5. Habilita la casilla de verificación Personalizar la reescritura del valor del espacio (Customize slot value writeback) (habilitada de forma predeterminada).
  6. Haz clic en Guardar.

Una verificación de requisitos de transacción da como resultado uno de los siguientes resultados:

  • Si se cumplen los requisitos, el parámetro de sesión se establece con éxito. y puedes continuar con la creación del orden del usuario.
  • Si no se pueden cumplir uno o más de los requisitos, el parámetro de sesión se con una condición de falla. En este caso, debes reorientar la conversación de la experiencia transaccional o finalizar la conversación.
    • Si el usuario puede corregir algún error que genere el estado de falla, se le solicitará que resuelva esos problemas en su dispositivo. Si el botón conversación sobre una superficie de voz, se realizará un traspaso iniciar en el teléfono del usuario.

Resultado de la verificación de requisitos de la transacción

  1. En la pestaña Scenes, selecciona Escena TransactionRequirementsCheck.
  2. En Condición, haz clic en + para agregar una condición nueva.
  3. En el campo de texto, ingresa la siguiente sintaxis de condición para comprobar la condición de éxito:

    scene.slots.status == "FINAL" && session.params.TransactionRequirementsCheck.resultType == "CAN_TRANSACT"
    
  4. Coloca el cursor sobre la condición que acabas de agregar y haz clic en la flecha hacia arriba. para colocarla antes de if scene.slots.status == "FINAL".

  5. Habilita la opción Send prompts y proporciona un mensaje simple para informar al usuario. que están listos para realizar una transacción:

    candidates:
      - first_simple:
          variants:
            - speech: >-
                Looks like you're good to go!.
    
  6. En Transition, selecciona otra escena para que el usuario continúe. de la conversación y continuar con la transacción.

  7. Selecciona la condición else if scene.slots.status == "FINAL".

  8. Habilita la opción Send prompts y proporciona un mensaje simple para informar al usuario. no pueden realizar una transacción:

    candidates:
      - first_simple:
          variants:
            - speech: Transaction requirements check failed.
    
  9. En Transición, selecciona Finalizar conversación para finalizarla. si un usuario no puede realizar transacciones.

Crea el pedido

Una vez que tengas la información del usuario que necesitas, crea un carrito ensamblado" experiencia que guía al usuario a crear su reserva. Cada La acción tendrá un flujo de ensamblaje de carro ligeramente diferente según corresponda para su servicio.

En una experiencia básica de armado de carritos, un usuario selecciona opciones de una lista para agregarlas a su reserva, aunque puedes diseñar la conversación para simplificar el la experiencia del usuario. Por ejemplo, crea una experiencia de ensamblado de carritos que permita la que el usuario programe una reserva mensual con una simple pregunta de sí o no. También puedes presentar al usuario un carrusel o una tarjeta con la lista de recomendaciones reservas.

Recomendamos usar respuestas enriquecidas para presentar las opciones del usuario visualmente, sino también diseñar la conversación para que el usuario puede construir su carrito solo con su voz. Para ver algunas prácticas recomendadas ejemplos de experiencias de ensamblado de carritos, consulta los lineamientos de diseño.

Crea un pedido

Durante la conversación, reúne los detalles de la reserva del usuario y, luego, construir un objeto Order.

Como mínimo, tu Order debe contener lo siguiente:

  • buyerInfo: Es la información sobre el usuario que realiza la compra.
  • transactionMerchant: Información sobre el comercio que facilitó el pedido.
  • contents: Es el contenido real del pedido que aparece como lineItems.

Consulta Order. la documentación de respuesta para construir tu carrito. Ten en cuenta que posiblemente debas incluir diferentes campos según la reserva.

En el código de muestra que aparece a continuación, se muestra un pedido de reserva completo, incluidos los campos opcionales:

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'
 };

Crear opciones de orden y presentación

const orderOptions = {
      'requestDeliveryAddress': false,
    };

const presentationOptions = {
      'actionDisplayName': 'RESERVE'
    };

Guardar datos del pedido en el parámetro de sesión

Desde tu entrega, guarda los datos del pedido en un parámetro de sesión. El pedido se usará en varias escenas de la misma sesión.

conv.session.params.order = {
    '@type': 'type.googleapis.com/google.actions.transactions.v3.TransactionDecisionValueSpec',
    order: order,
    orderOptions: orderOptions,
    presentationOptions: presentationOptions
};

Proponer el pedido

Una vez que hayas creado un pedido de reserva, debes presentárselo al usuario confirmar o rechazar. Para ello, debes pasar a una escena que realice una transacción decisión.

Crea una escena de decisión de la transacción

  1. En la pestaña Scenes, agrega una escena nueva con el nombre TransactionDecision.
  2. En Relleno de ranuras, haz clic en + para agregar un espacio nuevo.
  3. En Seleccionar tipo, selecciona actions.type.TransactionDecisionValue como el tipo de ranura.
  4. En el campo del nombre del espacio, asígnale el nombre TransactionDecision.
  5. Habilita la casilla de verificación Personalizar la reescritura del valor del espacio (Customize slot value writeback) (habilitada de forma predeterminada).
  6. En Configurar ranura, selecciona Usar parámetro de sesión en el menú desplegable.
  7. En Configura el espacio,ingresa el nombre del parámetro de la sesión que se usará para lo siguiente: almacenas el pedido en el campo de texto (es decir, $session.params.order).
  8. Haz clic en Guardar.

Para llenar un espacio de TransactionDecisionValue, Asistente inicia una experiencia integrada en la que el Order que pasaste se renderiza directamente en una "tarjeta de vista previa del carrito". El usuario puede decir “programar reserva”, rechazar la transacción o solicita cambiar los detalles de la reserva.

En este punto, el usuario también puede solicitar cambios en el pedido. En este caso, debe asegurarse de que su entrega pueda controlar las solicitudes de cambio de pedidos después la experiencia de armado del carrito.

Resultado de la decisión de la transacción del controlador

Cuando se llena un espacio de TransactionDecisionValue, la respuesta del usuario al la decisión de transacción se almacenará en un parámetro de sesión. Este valor contiene lo siguiente:

  • ORDER_ACCEPTED,
  • ORDER_REJECTED
  • CART_CHANGE_REQUESTED
  • USER_CANNOT_TRANSACT.

Para controlar el resultado de una decisión de transacción, haz lo siguiente:

  1. En la pestaña Scenes, selecciona la escena TransactionDecision que acabas de crear.
  2. En Condición, haz clic en + para agregar una condición nueva.
  3. En el campo de texto, ingresa la siguiente sintaxis de condición para comprobar la condición de éxito:

    scene.slots.status == "FINAL" && session.params.TransactionDecision.transactionDecision == "ORDER_ACCEPTED"
    
  4. Coloca el cursor sobre la condición que acabas de agregar y haz clic en la flecha hacia arriba. para colocarla antes de if scene.slots.status == "FINAL".

  5. Habilita la opción Send prompts y proporciona un mensaje simple para informar al usuario. cuando se completa su reserva:

    candidates:
      - first_simple:
          variants:
            - speech: >-
                Transaction completed! Your reservation
                $session.params.TransactionDecision.order.merchantOrderId is all
                set!
    
  6. En Transición, selecciona Finalizar conversación para finalizarla.

  7. En Condición, haz clic en + para agregar una condición nueva.

  8. En el campo de texto, ingresa la siguiente sintaxis de condición para comprobar la condiciones de falla:

      scene.slots.status == "FINAL" && session.params.TransactionDecision.transactionDecision == "ORDER_REJECTED"
    
  9. Coloca el cursor sobre la condición que acabas de agregar y haz clic en la flecha hacia arriba. para colocarla antes de if scene.slots.status == "FINAL".

  10. Habilita la opción Send prompts y proporciona un mensaje simple para que el usuario conozca pedido fue rechazado:

    candidates:
      - first_simple:
          variants:
            - speech: Looks like you don't want to set up a reservation. Goodbye.
    
  11. En Transición, selecciona Finalizar conversación para finalizarla.

  12. Selecciona la condición else if scene.slots.status == "FINAL".

  13. Habilita la opción Send prompts y proporciona un mensaje simple para informar al usuario. no pueden realizar una transacción:

    candidates:
      - first_simple:
          variants:
            - speech: >-
                Transaction failed with status
                $session.params.TransactionDecision.transactionDecision
    
  14. En Transición, selecciona Finalizar conversación para finalizarla. si un usuario no puede realizar transacciones.

Finaliza la reserva y envía un recibo

Cuando el espacio TransactionDecisionValue muestra un resultado de ORDER_ACCEPTED, debe realizar de inmediato el procesamiento necesario para programar la reservada (como conservarla en tu propia base de datos).

Envía una respuesta simple para mantener la conversación. El usuario recibe un "tarjeta de recibo contraída" junto con tu respuesta.

Para enviar una actualización inicial del pedido, sigue estos pasos:

  1. En la pestaña Scenes, selecciona tu escena TransactionDecision.
  2. En Condición, selecciona la condición que verifica que el resultado sea correcto. ORDER_ACCEPTED:

    scene.slots.status == "FINAL" && session.params.TransactionDecision.transactionDecision == "ORDER_ACCEPTED"
    
  3. Para esta condición, habilita Llamar a tu webhook y proporciona un intent nombre del controlador, como update_order.

  4. En el código de tu webhook, agrega un controlador de intents para enviar una actualización inicial del pedido:

    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'
      }));
    });
    

Cómo enviar actualizaciones de pedidos

El estado de la reserva cambia en el transcurso de su vida útil. Envía al usuario pedidos de reservación con solicitudes PATCH HTTP a la API de Orders, que contienen el estado y los detalles del pedido.

Configura solicitudes asíncronas para la API de Orders

Las solicitudes de actualización de pedidos a la API de Orders están autorizadas por un usuario token. Para realizar PATCH en la actualización de un pedido en la API de Orders, descarga un archivo JSON clave de la cuenta de servicio asociada a tu proyecto de la Consola de Actions y, luego, intercambiar la clave de la cuenta de servicio para un token del portador que se puede pasar al Encabezado Authorization de la solicitud HTTP.

Para recuperar la clave de tu cuenta de servicio, sigue estos pasos:

  1. En la consola de Google Cloud, ve a Menú ☰ > APIs y Servicios > Credenciales > Crear credenciales > Clave de cuenta de servicio.
  2. En Cuenta de servicio, selecciona Nueva cuenta de servicio.
  3. Configura la cuenta de servicio como service-account.
  4. Configura el Rol como Proyecto > Propietario:
  5. Establece el tipo de clave en JSON.
  6. Selecciona Crear.
  7. Se descargará una clave privada de cuenta de servicio JSON en tu máquina local.

En el código de actualizaciones de tu pedido, intercambia tu clave de servicio por un token del portador. con la biblioteca cliente de las APIs de Google y la "https://www.googleapis.com/auth/actions.order.developer". Puedes encontrar pasos de instalación y ejemplos en la biblioteca cliente de la API Página de GitHub.

Haz referencia a order-update.js en nuestra muestra de Node.js. de un intercambio de claves de ejemplo.

Cómo enviar actualizaciones de pedidos

Una vez que hayas intercambiado tu clave de cuenta de servicio por un token del portador de OAuth, envía actualizaciones de pedidos como solicitudes PATCH autorizadas a la API de Orders.

URL de la API de Orders: PATCH https://actions.googleapis.com/v3/orders/${orderId}

Proporciona los siguientes encabezados en tu solicitud:

  • "Authorization: Bearer token" por el token del portador de OAuth por la que intercambiaste la clave de tu cuenta de servicio.
  • "Content-Type: application/json".

La solicitud PATCH debe tomar un cuerpo JSON con el siguiente formato:

{ "orderUpdate": OrderUpdate }

La OrderUpdate consta de los siguientes campos de nivel superior:

  • updateMask: son los campos del pedido que actualizas. Para actualizar el estado de la reserva, establece el valor en reservation.status, reservation.userVisibleStatusLabel.
  • order: el contenido de la actualización. Si quieres actualizar contenidos de la reserva, establece el valor en el objeto Order actualizado. Si solo actualizas el estado de la reserva (por ejemplo, de "PENDING" a "FULFILLED"), el objeto contiene el siguientes campos:

    • merchantOrderId: Es el mismo ID que estableciste en tu objeto Order.
    • lastUpdateTime: Es la marca de tiempo de esta actualización.
    • purchase: Un objeto que contiene lo siguiente:
      • status: Es el estado del pedido como ReservationStatus. como "CONFIRMED" o "CANCELLED".
      • userVisibleStatusLabel: Es una etiqueta para el usuario que proporciona detalles sobre el estado del pedido, como "Se confirmó tu reserva".
  • userNotification (opcional) - A userNotification que se puede mostrar en el dispositivo del usuario cuando se envía esta actualización. Nota que incluir este objeto no garantiza que una notificación aparezca en el dispositivo del usuario.

En el siguiente código de muestra, se observa un OrderUpdate de ejemplo que actualiza la estado del pedido de reserva a 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}`);
}

Establece el estado de la reserva

El ReservationStatus de una actualización de pedido debe describir el estado actual del pedido. En el order.ReservationStatus de tu actualización utiliza uno de los siguientes valores:

  • PENDING: Se "creó" la reserva. por tu acción, pero requiere procesamiento adicional en el backend.
  • CONFIRMED: La reserva se confirmó en el backend de programación.
  • CANCELLED: El usuario canceló su reserva.
  • FULFILLED: el servicio completó la reserva del usuario.
  • CHANGE_REQUESTED: El usuario solicitó un cambio en la reserva, y el cambio se realiza mientras se procesan.
  • REJECTED, si no se pudo procesar o de alguna otra forma confirmar la reserva.

Envía actualizaciones de pedidos para cada estado que sea relevante para tu reserva. Por ejemplo, si tu reserva requiere procesamiento manual para confirma la reserva después de que se solicita y envía una actualización del pedido de PENDING hasta de que se realice un procesamiento adicional. No todas las reservas requieren todos los valores de estado.

Cómo probar tu proyecto

Cuando pruebes tu proyecto, puedes habilitar el modo de zona de pruebas en la Consola de Actions para probar tu Acción sin cobrar una forma de pago. Para habilitar el modo de zona de pruebas, sigue estos pasos:

  1. En la Consola de Actions, haz clic en Test, en el menú de navegación.
  2. Haz clic en Configuración.
  3. Habilita la opción Zona de pruebas de desarrollo.

Para las transacciones físicas, también puedes establecer el campo isInSandbox en true, en tu muestra. Esta acción equivale a habilitar el parámetro de configuración del modo de zona de pruebas en en la Consola de Actions. Para ver un fragmento de código que usa isInSandbox, consulta la Sección Envía actualizaciones de pedidos.

Soluciona problemas

Si tienes algún problema durante la prueba, consulta nuestros pasos para solucionar problemas. para las transacciones.