Criar reservas

Este guia explica o processo de desenvolvimento de um projeto do Actions que usa a API Orders para fazer reservas.

Fluxo de transações

Quando seu projeto do Actions processa reservas, usa este fluxo:

  1. Validar os requisitos de transação (opcional): use as transações. o assistente de requisitos no início da conversa para garantir que usuário é capaz de realizar uma transação.
  2. Elaborar o pedido: oriente o usuário durante um "montagem do carrinho" onde constroem os detalhes da reserva.
  3. Propor o pedido: assim que o "carrinho" for concluído, proponha o "pedido" da reserva para para que o usuário possa confirmar se está correta. Se a reserva estiver confirmada, receber uma resposta com os detalhes da reserva.
  4. Finalizar o pedido e enviar um recibo: com o pedido confirmado, atualize seu sistema de reservas e enviar um comprovante ao usuário.
  5. Enviar atualizações do pedido: durante a vida útil da reserva, atualize o status de reserva do usuário enviando solicitações PATCH ao API Orders.

Restrições e diretrizes de avaliações

Políticas adicionais se aplicam a ações que usam o transações e API Orders. A revisão das Ações pode levar até seis semanas com as transações, então considere esse tempo ao planejar a programação de lançamentos. Para facilitar o processo de análise, verifique se você está em conformidade com políticas e diretrizes para transações antes de enviar sua Ação para revisão.

Só é possível implantar ações que usam a API Orders nos seguintes países:

Austrália
Brasil
Canadá
Indonésia
Japão
México
Catar
Rússia
Singapura
Suíça
Tailândia
Turquia
Reino Unido
Estados Unidos

Criar o projeto

Para ver um exemplo abrangente de conversas sobre transações, consulte Transações em Node.js.

Configuração

Ao criar sua ação, especifique que você quer realizar transações no Console do Actions.

Para configurar o projeto e o fulfillment, faça o seguinte:

  1. Crie um novo projeto ou importe um existente.
  2. Acesse Implantar > informações do diretório.
  3. Em Informações adicionais > Transações > marque a caixa que diz "Faça suas ações usar a API Transactions para realizar transações de produtos físicos?".

Valide os requisitos da transação (opcional)

Assim que o usuário indicar que quer configurar uma reserva, marque que eles podem solicitar uma reserva. Por exemplo, quando invocada, sua ação pode pergunte: "Quer reservar um assento?" Se o usuário disser “sim”, você deverá garantir que ele possa prosseguir e dar a ele a oportunidade de corrigir as configurações impedindo que ele prossiga com a transação. Para isso, você deve para uma cena que verifica os requisitos da transação.

Criar requisitos de transação Verificar cenário

  1. Na guia Cenas, adicione uma nova cena com o nome dela. TransactionRequirementsCheck
  2. Em Preenchimento de slot, clique em + para adicionar um novo slot.
  3. Em Selecionar tipo, selecione actions.type.TransactionRequirementsCheckResult. como o tipo de slot.
  4. No campo de nome do slot, dê o nome TransactionRequirementsCheck ao slot.
  5. Marque a caixa de seleção Personalizar o writeback do valor do slot (ativada por padrão).
  6. Clique em Salvar.

Uma verificação de requisitos de transação resulta em um dos seguintes resultados:

  • Se os requisitos forem atendidos, o parâmetro de sessão será definido com sucesso e prosseguir com a criação do pedido do usuário.
  • Se um ou mais requisitos não puderem ser atendidos, o parâmetro session será com uma condição de falha. Nesse caso, você deve dinamizar a conversa da experiência transacional ou encerrar a conversa.
    • Se os erros que resultam no estado de falha puderem ser corrigidos pelo usuário, ele receberá uma solicitação para resolver esses problemas no dispositivo. Se o conversa ocorrendo em uma plataforma somente de voz, uma transferência no smartphone do usuário.

Processar o resultado da verificação de requisitos de transação

  1. Na guia Cenas, selecione o filme que você acabou de criar. TransactionRequirementsCheck cena.
  2. Em Condição, clique em + para adicionar uma nova condição.
  3. No campo de texto, digite a seguinte sintaxe de condição para verificar os condição de sucesso:

    scene.slots.status == "FINAL" && session.params.TransactionRequirementsCheck.resultType == "CAN_TRANSACT"
    
  4. Passe o cursor sobre a condição que você acabou de adicionar e clique na seta para cima. para posicioná-lo antes de if scene.slots.status == "FINAL".

  5. Ative Enviar solicitações e forneça um comando simples informando ao usuário. ele está pronto para fazer uma transação:

    candidates:
      - first_simple:
          variants:
            - speech: >-
                Looks like you're good to go!.
    
  6. Em Transição, selecione outra cena que permita ao usuário continuar a conversa e prosseguir com a transação.

  7. Selecione a condição else if scene.slots.status == "FINAL".

  8. Ative Enviar solicitações e forneça um comando simples informando ao usuário. ele não consegue fazer uma transação:

    candidates:
      - first_simple:
          variants:
            - speech: Transaction requirements check failed.
    
  9. Em Transição, selecione Encerrar conversa para encerrar a conversa. caso um usuário não consiga fazer transações.

Criar o pedido

Depois de ter as informações de usuário necessárias, crie um "carrinho" assembly" que orienta o usuário na criação da reserva. Todas A ação terá um fluxo de montagem de carrinho ligeiramente diferente, conforme apropriado para serviço.

Em uma experiência básica de montagem de carrinho, o usuário seleciona as opções de uma lista para adicionar para a reserva, embora você possa projetar a conversa para simplificar a experiência do usuário. Por exemplo, crie uma experiência de montagem de carrinho que permita ao faça uma reserva mensal com uma simples pergunta de "sim" ou "não". Também é possível apresentar ao usuário um carrossel ou card de lista de "recomendado" reservas.

Recomendamos o uso de respostas detalhadas para apresentar as opções do usuário visualmente, mas também projetar a conversa para que o usuário pode criar o carrinho usando apenas a voz. Para algumas práticas recomendadas e exemplos de experiências de montagem de carrinho, consulte as Diretrizes de design.

Criar um pedido

Ao longo da conversa, colete os detalhes da reserva do usuário e, em seguida, construa um objeto Order.

Seu Order precisa conter pelo menos o seguinte:

  • buyerInfo: informações sobre o usuário que fez a compra.
  • transactionMerchant – Informações sobre o comerciante que facilitou o pedido.
  • contents: o conteúdo real do pedido listado como lineItems.
.

Consulte o Order documentação de resposta para criar seu carrinho. Pode ser necessário incluir campos diferentes dependendo da reserva.

O exemplo de código abaixo mostra um pedido de reserva completo, incluindo campos opcionais:

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

Criar opções de ordem e apresentação

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

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

Salvar dados do pedido no parâmetro da sessão

No fulfillment, salve os dados do pedido em um parâmetro de sessão. O pedido será usado em vários cenários na mesma sessão.

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

Propor o pedido

Depois de criar um pedido de reserva, é necessário apresentá-lo ao usuário para confirmar ou rejeitar. Para isso, faça a transição para uma cena que realize uma transação. decisão.

Criar cenário de decisão da transação

  1. Na guia Cenas, adicione uma cena chamada TransactionDecision.
  2. Em Preenchimento de slot, clique em + para adicionar um novo slot.
  3. Em Selecionar tipo, selecione actions.type.TransactionDecisionValue como o tipo de slot.
  4. No campo de nome do slot, dê o nome TransactionDecision ao slot.
  5. Marque a caixa de seleção Personalizar o writeback do valor do slot (ativada por padrão).
  6. Em Configurar slot, selecione Usar parâmetro de sessão no menu suspenso.
  7. Em Configurar slot,insira o nome do parâmetro da sessão usado para armazene o pedido no campo de texto (ou seja, $session.params.order).
  8. Clique em Salvar.

Na tentativa de preencher um slot TransactionDecisionValue, o Google Assistente inicia uma experiência integrada em que o Order transmitido é renderizado diretamente no "Card de visualização do carrinho". O usuário pode dizer "agendar reserva", recusar a transação, ou solicitar a alteração dos detalhes da reserva.

Nesse momento, o usuário também pode solicitar alterações no pedido. Nesse caso, precisa garantir que o atendimento processe as solicitações de alteração do pedido após para finalizar a experiência de montagem do carrinho.

Processar o resultado da decisão de transação

Quando um slot TransactionDecisionValue é preenchido, a resposta do usuário ao a decisão da transação será armazenada em um parâmetro de sessão. Esse valor contém o seguinte:

  • ORDER_ACCEPTED,
  • ORDER_REJECTED,
  • CART_CHANGE_REQUESTED
  • USER_CANNOT_TRANSACT.

Para processar o resultado de uma decisão de transação:

  1. Na guia Cenas, selecione a cena TransactionDecision recém-criada.
  2. Em Condição, clique em + para adicionar uma nova condição.
  3. No campo de texto, digite a seguinte sintaxe de condição para verificar os condição de sucesso:

    scene.slots.status == "FINAL" && session.params.TransactionDecision.transactionDecision == "ORDER_ACCEPTED"
    
  4. Passe o cursor sobre a condição que você acabou de adicionar e clique na seta para cima. para posicioná-lo antes de if scene.slots.status == "FINAL".

  5. Ative Enviar solicitações e forneça um comando simples informando ao usuário. a reserva for concluída:

    candidates:
      - first_simple:
          variants:
            - speech: >-
                Transaction completed! Your reservation
                $session.params.TransactionDecision.order.merchantOrderId is all
                set!
    
  6. Em Transição, selecione Encerrar conversa para encerrar a conversa.

  7. Em Condição, clique em + para adicionar uma nova condição.

  8. No campo de texto, digite a seguinte sintaxe de condição para verificar os condições de falha:

      scene.slots.status == "FINAL" && session.params.TransactionDecision.transactionDecision == "ORDER_REJECTED"
    
  9. Passe o cursor sobre a condição que você acabou de adicionar e clique na seta para cima. para posicioná-lo antes de if scene.slots.status == "FINAL".

  10. Ative Enviar solicitações e forneça um prompt simples informando ao usuário o pedido for rejeitado:

    candidates:
      - first_simple:
          variants:
            - speech: Looks like you don't want to set up a reservation. Goodbye.
    
  11. Em Transição, selecione Encerrar conversa para encerrar a conversa.

  12. Selecione a condição else if scene.slots.status == "FINAL".

  13. Ative Enviar solicitações e forneça um comando simples informando ao usuário. ele não consegue fazer uma transação:

    candidates:
      - first_simple:
          variants:
            - speech: >-
                Transaction failed with status
                $session.params.TransactionDecision.transactionDecision
    
  14. Em Transição, selecione Encerrar conversa para encerrar a conversa. caso um usuário não consiga fazer transações.

Finalizar a reserva e enviar um comprovante

Quando o slot TransactionDecisionValue retorna um resultado de ORDER_ACCEPTED, execute imediatamente o processamento necessário para programar a reserva (como a persistência deles em seu próprio banco de dados).

Envie uma resposta simples para manter a conversa rolando. O usuário recebe uma "cartão de recibo recolhido" junto com sua resposta.

Para enviar uma atualização inicial do pedido:

  1. Na guia Cenas, selecione a cena TransactionDecision.
  2. Em Condição, selecione a condição que verifica o resultado bem-sucedido. ORDER_ACCEPTED:

    scene.slots.status == "FINAL" && session.params.TransactionDecision.transactionDecision == "ORDER_ACCEPTED"
    
  3. Para essa condição, ative Chamar seu webhook e forneça uma intent nome do gerenciador, como update_order.

  4. No código do webhook, adicione um gerenciador de intent para enviar uma atualização inicial do 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'
      }));
    });
    

Enviar atualizações de pedidos

O status da reserva muda ao longo do ciclo de vida. Enviar o usuário atualizações de pedidos de reserva com solicitações HTTP PATCH para a API Orders, contendo o status e os detalhes do pedido.

Configurar solicitações assíncronas para a API Orders

As solicitações de atualização de pedidos para a API Orders são autorizadas por um acesso com base no token correto anterior. Para PATCH uma atualização de pedido para a API Orders, faça o download de um arquivo JSON chave da conta de serviço associada ao seu projeto do Console do Actions e, em seguida, trocar a chave da conta de serviço para um token do portador que pode ser passado ao Cabeçalho Authorization da solicitação HTTP.

Para recuperar a chave da conta de serviço, siga estas etapas:

  1. No console do Google Cloud, Ir para Menu ☰ > APIs e Serviços > Credenciais > Criar credenciais > Chave da conta de serviço.
  2. Em Conta de serviço, selecione Nova conta de serviço.
  3. Defina a conta de serviço como service-account.
  4. Defina o Papel como Projeto > proprietário.
  5. Defina o tipo de chave como JSON.
  6. Selecione Criar.
  7. Será feito o download de uma chave privada da conta de serviço JSON para sua máquina local.

No seu código de atualizações do pedido, troque sua chave de serviço por um token do portador usando a biblioteca de cliente das APIs do Google e a Escopo "https://www.googleapis.com/auth/actions.order.developer". Você pode encontrar etapas de instalação e exemplos na biblioteca de cliente da API Página do GitHub.

Consulte order-update.js na nossa amostra de Node.js em um exemplo de troca de chaves.

Enviar atualizações de pedidos

Depois de trocar a chave da sua conta de serviço por um token do portador OAuth, envie atualizações de pedidos como solicitações PATCH autorizadas para a API Orders.

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

Forneça os seguintes cabeçalhos na solicitação:

  • "Authorization: Bearer token" pelo token do portador OAuth pela qual você trocou a chave da conta de serviço.
  • "Content-Type: application/json".

A solicitação PATCH precisa ter um corpo JSON no seguinte formato:

{ "orderUpdate": OrderUpdate }

O OrderUpdate consiste nos seguintes campos de nível superior:

  • updateMask: os campos do pedido que você está atualizando. Para atualizar o o status da reserva, Defina o valor como reservation.status, reservation.userVisibleStatusLabel.
  • order: o conteúdo da atualização. Se você estiver atualizando a conteúdo da reserva, defina o valor do objeto Order atualizado. Se você estiver apenas atualizando o status da reserva (por exemplo, de "PENDING" a "FULFILLED"), o objeto contém o seguintes campos:

    • merchantOrderId: o mesmo ID definido no objeto Order.
    • lastUpdateTime: carimbo de data/hora da atualização.
    • purchase: um objeto que contém o seguinte:
      • status: o status do pedido como um ReservationStatus, como "CONFIRMED" ou "CANCELLED".
      • userVisibleStatusLabel: um rótulo voltado para o usuário com detalhes sobre o status do pedido, como "Sua reserva foi confirmada".
  • userNotification (opcional): A userNotification que pode ser exibido no dispositivo do usuário quando essa atualização é enviada. Observação que a inclusão deste objeto não garante que uma notificação seja exibida no dispositivo do usuário.

O exemplo de código a seguir mostra um exemplo de OrderUpdate que atualiza a do pedido de reserva para 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}`);
}

Definir o status da reserva

ReservationStatus de uma atualização de pedido deve descrever o estado atual do pedido. No order.ReservationStatus da sua atualização , use um dos seguintes valores:

  • PENDING: a reserva foi "criada" pela sua Ação, mas exige processamento adicional em seu back-end.
  • CONFIRMED: a reserva é confirmada no seu back-end de programação.
  • CANCELLED: o usuário cancelou a reserva.
  • FULFILLED: a reserva do usuário foi atendida pelo serviço.
  • CHANGE_REQUESTED: o usuário solicitou uma alteração na reserva, e a alteração é que estão sendo processados.
  • REJECTED: se não foi possível processar ou de outra forma confirme a reserva.

Envie atualizações de pedidos para cada status relevante para seu reserva. Por exemplo, se a reserva exigir o processamento manual para Confirmar a reserva depois de ser solicitada, enviar uma atualização do pedido PENDING até que um processamento adicional seja feito. Nem toda reserva exige todos os valores de status.

Testar seu projeto

Ao testar seu projeto, você pode ativar o modo sandbox no Console do Actions para testar a ação sem fazer cobranças na forma de pagamento. Para ativar o modo sandbox, siga estas etapas:

  1. No Console do Actions, clique em Testar na navegação.
  2. Clique em Configurações.
  3. Ative a opção Sandbox de desenvolvimento.

Para transações físicas, também é possível definir o campo isInSandbox como true em para sua amostra. Esta ação equivale a ativar a configuração do modo sandbox no Console do Actions. Para conferir um snippet de código que usa isInSandbox, consulte a seção Enviar atualizações de pedidos.

Solução de problemas

Se você tiver problemas durante o teste, leia as etapas de solução de problemas. para transações.