Prenotazioni di build

Questa guida illustra il processo di sviluppo di un progetto Actions che utilizza l'API Orders per effettuare le prenotazioni.

Flusso delle transazioni

Quando il progetto Actions gestisce le prenotazioni, utilizza il seguente flusso:

  1. (Facoltativo) Convalidare i requisiti delle transazioni: utilizza l'helper dei requisiti delle transazioni all'inizio della conversazione per assicurarti che l'utente sia in grado di effettuare una transazione.
  2. Creare l'ordine: guida l'utente attraverso un "assemblaggio del carrello" in cui crea i dettagli della prenotazione.
  3. Proponi l'ordine: una volta completato il "carrello", proponi "ordine" di prenotazione all'utente in modo che possa confermare che è corretto. Se la prenotazione viene confermata, riceverai una risposta con i dettagli della prenotazione.
  4. Finalizzare l'ordine e inviare una ricevuta: dopo aver confermato l'ordine, aggiorna il sistema di prenotazione e invia una ricevuta all'utente.
  5. Inviare aggiornamenti sull'ordine: nel corso della durata della prenotazione, fornisci all'utente aggiornamenti dello stato di prenotazione inviando richieste PATCH all'API Orders.

Limitazioni e linee guida per le recensioni

Tieni presente che norme aggiuntive si applicano alle azioni che utilizzano le transazioni e l'API Orders. Possono essere necessarie fino a sei settimane per esaminare le azioni con transazioni, quindi tieni conto di questo tempo quando pianifichi la pianificazione della pubblicazione. Per semplificare la procedura di revisione, assicurati di rispettare le norme e linee guida per le transazioni prima di inviare l'Azione per la revisione.

Puoi eseguire il deployment di Actions che utilizzano l'API Orders solo nei seguenti paesi:

Australia
Brasile
Canada
Indonesia
Giappone
Messico
Qatar
Russia
Singapore
Svizzera
Thailandia
Turchia
Regno Unito
Stati Uniti

Crea il tuo progetto

Per un esempio completo di conversazioni transazionali, visualizza il nostro esempio di transazioni in Node.js.

Configurazione

Quando crei l'Azione, devi specificare che vuoi eseguire transazioni nella Console di Actions.

Per configurare il progetto e il fulfillment:

  1. Crea un nuovo progetto o importa un progetto esistente.
  2. Vai a Deployment > Informazioni sulla directory.
  3. In Informazioni aggiuntive > Transazioni > seleziona la casella "Le tue azioni utilizzano l'API Transactions per eseguire transazioni di beni fisici?".

(Facoltativo) Convalida i requisiti della transazione

Non appena l'utente ha indicato di voler configurare una prenotazione, devi verificare di poter richiedere una prenotazione. Ad esempio, quando viene richiamata, l'Azione potrebbe chiedere "Vuoi prenotare un posto?". Se l'utente risponde "sì", assicurati che possa procedere e offrigli l'opportunità di correggere eventuali impostazioni che gli impediscono di continuare la transazione. Per farlo, devi passare a una scena che esegue un controllo dei requisiti di transazione.

Crea scena del controllo dei requisiti di transazione

  1. Dalla scheda Scene, aggiungi una nuova scena con il nome TransactionRequirementsCheck.
  2. In Riempimento slot, fai clic su + per aggiungere una nuova area.
  3. In Seleziona tipo, scegli actions.type.TransactionRequirementsCheckResult come tipo di area.
  4. Nel campo del nome dell'area, assegna all'area il nome TransactionRequirementsCheck.
  5. Attiva la casella di controllo Personalizza il writeback del valore dell'area annuncio (attivata per impostazione predefinita).
  6. Fai clic su Salva.

Un controllo dei requisiti di transazione genera uno dei seguenti risultati:

  • Se i requisiti sono soddisfatti, il parametro sessione viene impostato con una condizione di successo e puoi procedere con la creazione dell'ordine dell'utente.
  • Se uno o più requisiti non possono essere soddisfatti, il parametro sessione viene impostato con una condizione di errore. In questo caso, devi allontanare la conversazione dall'esperienza transazionale o terminare la conversazione.
    • Se gli errori che causano lo stato di errore possono essere corretti dall'utente, gli verrà chiesto di risolverli sul dispositivo. Se la conversazione si svolge su una piattaforma a sola voce, viene avviato un trasferimento al telefono dell'utente.

Gestire il risultato del controllo dei requisiti di transazione

  1. Dalla scheda Scene, seleziona la scena TransactionRequirementsCheck appena creata.
  2. In Condizione, fai clic su + per aggiungere una nuova condizione.
  3. Nel campo di testo, inserisci la seguente sintassi della condizione per verificare la presenza della condizione di esito positivo:

    scene.slots.status == "FINAL" && session.params.TransactionRequirementsCheck.resultType == "CAN_TRANSACT"
    
  4. Passa il mouse sopra la condizione appena aggiunta e fai clic sulla Freccia su per posizionarla prima di if scene.slots.status == "FINAL".

  5. Attiva Invia richieste e fornisci una semplice richiesta per far sapere all'utente che è pronto a effettuare una transazione:

    candidates:
      - first_simple:
          variants:
            - speech: >-
                Looks like you're good to go!.
    
  6. In Transizione, seleziona un'altra scena, consentendo all'utente di continuare la conversazione e di procedere con una transazione.

  7. Seleziona la condizione else if scene.slots.status == "FINAL".

  8. Attiva l'opzione Invia richieste e fornisci una semplice richiesta per far sapere all'utente che non è possibile effettuare una transazione:

    candidates:
      - first_simple:
          variants:
            - speech: Transaction requirements check failed.
    
  9. In Transizione, seleziona Termina conversazione per terminare la conversazione se un utente non è in grado di effettuare transazioni.

Crea l'ordine

Una volta che disponi delle informazioni utente necessarie, crea un'esperienza di "assemblaggio del carrello" che guidi l'utente nella creazione della prenotazione. Ogni azione avrà un flusso di assemblaggio del carrello leggermente diverso in base alle esigenze del servizio.

In un'esperienza di assemblaggio del carrello di base, un utente seleziona da un elenco le opzioni da aggiungere alla prenotazione, anche se puoi progettare la conversazione per semplificare l'esperienza utente. Ad esempio, puoi creare un'esperienza di assemblaggio del carrello che consenta all'utente di pianificare una prenotazione mensile con una semplice domanda sì o no. Puoi anche presentare all'utente un carosello o una scheda elenco di prenotazioni "consigliate".

Ti consigliamo di utilizzare risposte avanzate per presentare visivamente le opzioni dell'utente, ma anche di progettare la conversazione in modo che l'utente possa creare il carrello utilizzando solo la sua voce. Per alcune best practice ed esempi di esperienze di assemblaggio del carrello, consulta le linee guida di progettazione.

Creazione di un ordine

Nel corso della conversazione, raccogli i dettagli della prenotazione dell'utente, quindi crea un oggetto Order.

Come minimo, il tuo Order deve contenere quanto segue:

  • buyerInfo: informazioni sull'utente che effettua l'acquisto.
  • transactionMerchant: informazioni sul commerciante che ha gestito l'ordine.
  • contents. I contenuti effettivi dell'ordine indicato come lineItems.

Per creare il tuo carrello, consulta la documentazione relativa alle risposte di Order. Tieni presente che potrebbe essere necessario includere campi diversi a seconda della prenotazione.

Il codice di esempio riportato di seguito mostra un ordine di prenotazione completo, inclusi i campi facoltativi:

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

Crea opzioni per ordine e presentazione

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

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

Salva i dati degli ordini nel parametro di sessione

Dal evasione degli ordini, salva i dati dell'ordine in un parametro di sessione. L'oggetto ordine verrà utilizzato nelle varie scene per la stessa sessione.

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

Proponi l'ordine

Una volta creato un ordine di prenotazione, devi presentarlo all'utente per confermarlo o rifiutarlo. Per farlo, devi passare a una scena che esegue una decisione di transazione.

Crea scena della decisione della transazione

  1. Dalla scheda Scene, aggiungi una nuova scena con il nome TransactionDecision.
  2. In Riempimento slot, fai clic su + per aggiungere una nuova area.
  3. In Seleziona tipo, scegli actions.type.TransactionDecisionValue come tipo di area.
  4. Nel campo del nome dell'area, assegna all'area il nome TransactionDecision.
  5. Attiva la casella di controllo Personalizza il writeback del valore dell'area annuncio (attivata per impostazione predefinita).
  6. In Configura slot, seleziona Utilizza parametro sessione dal menu a discesa.
  7. In Configura slot,inserisci il nome del parametro di sessione utilizzato per archiviare l'ordine nel campo di testo (ad es. $session.params.order).
  8. Fai clic su Salva.

Nel tentativo di riempire uno slot TransactionDecisionValue, l'assistente avvia un'esperienza integrata in cui i Order che hai passato vengono visualizzati direttamente in una "scheda di anteprima del carrello". L'utente può dire "pianifica prenotazione", rifiutare la transazione o richiedere di modificare i dettagli della prenotazione.

A questo punto, l'utente può anche richiedere modifiche all'ordine. In questo caso, devi assicurarti che l'evasione degli ordini sia in grado di gestire le richieste di modifica dell'ordine dopo aver completato l'esperienza di assemblaggio del carrello.

Gestire il risultato della decisione della transazione

Quando uno slot TransactionDecisionValue viene riempito, la risposta dell'utente alla decisione sulla transazione viene archiviata in un parametro sessione. Questo valore contiene quanto segue:

  • ORDER_ACCEPTED,
  • ORDER_REJECTED,
  • CART_CHANGE_REQUESTED
  • USER_CANNOT_TRANSACT.

Per gestire il risultato di una decisione relativa a una transazione:

  1. Dalla scheda Scene, seleziona la scena TransactionDecision appena creata.
  2. In Condizione, fai clic su + per aggiungere una nuova condizione.
  3. Nel campo di testo, inserisci la seguente sintassi della condizione per verificare la presenza della condizione di esito positivo:

    scene.slots.status == "FINAL" && session.params.TransactionDecision.transactionDecision == "ORDER_ACCEPTED"
    
  4. Passa il cursore sulla condizione appena aggiunta e fai clic sulla Freccia su per posizionarla prima di if scene.slots.status == "FINAL".

  5. Attiva Invia richieste e fornisci un semplice messaggio per informare l'utente che la prenotazione è stata completata:

    candidates:
      - first_simple:
          variants:
            - speech: >-
                Transaction completed! Your reservation
                $session.params.TransactionDecision.order.merchantOrderId is all
                set!
    
  6. In Transizione, seleziona Termina conversazione per terminare la conversazione.

  7. In Condizione, fai clic su + per aggiungere una nuova condizione.

  8. Nel campo di testo, inserisci la seguente sintassi della condizione per verificare le condizioni di errore:

      scene.slots.status == "FINAL" && session.params.TransactionDecision.transactionDecision == "ORDER_REJECTED"
    
  9. Passa il cursore sulla condizione appena aggiunta e fai clic sulla Freccia su per posizionarla prima di if scene.slots.status == "FINAL".

  10. Attiva Invia richieste e fornisci un semplice messaggio per informare l'utente che l'ordine è stato rifiutato:

    candidates:
      - first_simple:
          variants:
            - speech: Looks like you don't want to set up a reservation. Goodbye.
    
  11. In Transizione, seleziona Termina conversazione per terminare la conversazione.

  12. Seleziona la condizione else if scene.slots.status == "FINAL".

  13. Attiva Invia richieste e fornisci una semplice richiesta per far sapere all'utente che non è possibile effettuare una transazione:

    candidates:
      - first_simple:
          variants:
            - speech: >-
                Transaction failed with status
                $session.params.TransactionDecision.transactionDecision
    
  14. In Transizione, seleziona Termina conversazione per terminare la conversazione se un utente non è in grado di effettuare transazioni.

Finalizza la prenotazione e invia una ricevuta

Quando lo slot TransactionDecisionValue restituisce un risultato ORDER_ACCEPTED, devi eseguire immediatamente l'elaborazione richiesta per pianificare la prenotazione, ad esempio per ripristinarla nel tuo database.

Invia una semplice risposta per mantenere viva la conversazione. L'utente riceve una "scheda di ricevuta compressa" insieme alla tua risposta.

Per inviare un aggiornamento iniziale dell'ordine:

  1. Dalla scheda Scene, seleziona la tua scena TransactionDecision.
  2. In Condizione, seleziona la condizione che verifica il risultato positivo, ORDER_ACCEPTED:

    scene.slots.status == "FINAL" && session.params.TransactionDecision.transactionDecision == "ORDER_ACCEPTED"
    
  3. Per questa condizione, attiva Chiama il webhook e fornisci un nome per il gestore dell'intent, ad esempio update_order.

  4. Nel codice webhook, aggiungi un gestore di intent per l'invio di un aggiornamento iniziale dell'ordine:

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

Invia aggiornamenti sull'ordine

Lo stato di prenotazione cambia nel corso della sua durata. Invia all'API Orders gli aggiornamenti dell'ordine di prenotazione con richieste HTTP PATCH, contenenti lo stato e i dettagli dell'ordine.

Configurare le richieste asincrone all'API Orders

Le richieste di aggiornamento degli ordini all'API Orders sono autorizzate da un token di accesso. Per eseguire il PATCH di un aggiornamento di un ordine all'API Orders, scarica una chiave dell'account di servizio JSON associata al tuo progetto Actions Console, quindi scambia la chiave dell'account di servizio con un token di connessione che può essere trasmesso all'intestazione Authorization della richiesta HTTP.

Per recuperare la chiave dell'account di servizio, segui questi passaggi:

  1. Nella console Google Cloud, vai a Menu Activate > API e servizi > Credenziali > Crea credenziali > Chiave dell'account di servizio.
  2. In Service Account (Account di servizio), seleziona New Service Account (Nuovo account di servizio).
  3. Imposta l'account di servizio su service-account.
  4. Imposta Ruolo su Progetto > Proprietario.
  5. Imposta il tipo di chiave su JSON.
  6. Seleziona Crea.
  7. Verrà scaricata sulla macchina locale una chiave JSON privata dell'account di servizio.

Nel codice di aggiornamento dell'ordine, scambia la chiave di servizio con un token di connessione utilizzando la libreria client delle API di Google e l'ambito "https://www.googleapis.com/auth/actions.order.developer". Puoi trovare la procedura di installazione e gli esempi nella pagina GitHub della libreria client API.

Fai riferimento a order-update.js nel nostro esempio Node.js per uno scambio di chiavi di esempio.

Invia aggiornamenti sull'ordine

Dopo aver scambiato la chiave dell'account di servizio con un token di connessione OAuth, invia gli aggiornamenti degli ordini come richieste PATCH autorizzate all'API Orders.

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

Fornisci le seguenti intestazioni nella richiesta:

  • "Authorization: Bearer token" con il token di connessione OAuth per cui hai scambiato la chiave dell'account di servizio.
  • "Content-Type: application/json".

La richiesta PATCH deve avere un corpo JSON con il seguente formato:

{ "orderUpdate": OrderUpdate }

L'oggetto OrderUpdate è costituito dai seguenti campi di primo livello:

  • updateMask. I campi dell'ordine che stai aggiornando. Per aggiornare lo stato della prenotazione, imposta il valore su reservation.status, reservation.userVisibleStatusLabel.
  • order: i contenuti dell'aggiornamento. Se aggiorni i contenuti della prenotazione, imposta il valore sull'oggetto Order aggiornato. Se stai solo aggiornando lo stato della prenotazione (ad esempio da "PENDING" a "FULFILLED"), l'oggetto contiene i seguenti campi:

    • merchantOrderId: lo stesso ID impostato nell'oggetto Order.
    • lastUpdateTime: il timestamp di questo aggiornamento.
    • purchase: un oggetto contenente i seguenti elementi:
      • status: lo stato dell'ordine come ReservationStatus, ad esempio "CONFIRMED" o "CANCELLED".
      • userVisibleStatusLabel: un'etichetta rivolta agli utenti che fornisce dettagli sullo stato dell'ordine, ad esempio "La prenotazione è confermata".
  • userNotification che può essere visualizzato sul dispositivo dell'utente quando viene inviato questo aggiornamento. Tieni presente che l'inclusione di questo oggetto non garantisce che venga visualizzata una notifica sul dispositivo dell'utente.

Il seguente codice campione mostra un esempio OrderUpdate che aggiorna lo stato dell'ordine di prenotazione 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}`);
}

Impostare lo stato della prenotazione

Il valore ReservationStatus di un aggiornamento dell'ordine deve descrivere lo stato attuale dell'ordine. Nel campo order.ReservationStatus dell'aggiornamento, utilizza uno dei seguenti valori:

  • PENDING: la prenotazione è stata "creata" dall'Azione, ma richiede un'ulteriore elaborazione nel tuo backend.
  • CONFIRMED - La prenotazione è confermata nel back-end della programmazione.
  • CANCELLED: l'utente ha annullato la prenotazione.
  • FULFILLED: la prenotazione dell'utente è stata evasa dal servizio.
  • CHANGE_REQUESTED: l'utente ha richiesto una modifica alla prenotazione ed è in corso l'elaborazione della modifica.
  • REJECTED - Se non sei riuscito a elaborare o confermare in altro modo la prenotazione.

Invia aggiornamenti sull'ordine per ogni stato pertinente alla tua prenotazione. Ad esempio, se la prenotazione richiede l'elaborazione manuale per confermare la prenotazione dopo la richiesta, invia un aggiornamento dell'ordine PENDING fino al completamento dell'elaborazione aggiuntiva. Non tutte le prenotazioni richiedono ogni valore di stato.

Testare il progetto

Durante il test del progetto, puoi attivare la modalità sandbox nella console Actions per testare l'Azione senza addebitare alcun metodo di pagamento. Per attivare la modalità sandbox, segui questi passaggi:

  1. Nella console di Actions, fai clic su Test nel menu di navigazione.
  2. Fai clic su Impostazioni.
  3. Attiva l'opzione Sandbox per lo sviluppo.

Per le transazioni fisiche, puoi anche impostare il campo isInSandbox su true nel campione. Questa azione equivale all'attivazione dell'impostazione della modalità sandbox nella console di Actions. Per visualizzare uno snippet di codice che utilizza isInSandbox, consulta la sezione Invia aggiornamenti sull'ordine.

Risolvere i problemi

Se riscontri problemi durante il test, consulta la nostra procedura per la risoluzione dei problemi relativa alle transazioni.