Tworzenie rezerwacji

Ten przewodnik przedstawia proces tworzenia projektu w Actions, który używa interfejsu Orders API do składania rezerwacji.

Przepływ transakcji

Gdy projekt Actions obsługuje rezerwacje, korzysta z tego procesu:

  1. Weryfikowanie wymagań dotyczących transakcji (opcjonalnie) – na początku rozmowy skorzystaj z pomocy dotyczącej wymagań dotyczących transakcji, aby sprawdzić, czy użytkownik może zrealizować transakcję.
  2. Stworzenie zamówienia – pokaż użytkownikowi „zestaw koszyka”, w którym tworzy szczegóły rezerwacji.
  3. Zaproponowanie zamówienia – po zakończeniu „koszyka” zaproponuj użytkownikowi zamówienie z rezerwacją, by mógł on potwierdzić, że jest prawidłowy. Jeśli rezerwacja zostanie potwierdzona, otrzymasz odpowiedź ze szczegółami rezerwacji.
  4. Sfinalizuj zamówienie i wyślij potwierdzenie – po potwierdzeniu zamówienia zaktualizuj system rezerwacji i wyślij użytkownikowi potwierdzenie.
  5. Wyślij aktualizacje zamówienia – w trakcie okresu ważności rezerwacji wysyłaj aktualizacje stanu rezerwacji użytkownika, wysyłając żądania PATCH do interfejsu Orders API.

Ograniczenia i wytyczne dotyczące sprawdzania

Pamiętaj, że w przypadku działań, które korzystają z interfejsu API transakcji i interfejsu Orders API, obowiązują dodatkowe zasady. Sprawdzenie działań z transakcjami może nam zająć do 6 tygodni, więc uwzględnij ten czas przy planowaniu harmonogramu publikacji. Aby ułatwić proces sprawdzania, przed przesłaniem akcji do sprawdzenia upewnij się, że przestrzegasz zasad i wytycznych dotyczących transakcji.

Akcje, które używają interfejsu Orders API, możesz wdrażać tylko w tych krajach:

Australia
Brazylia
Kanada
Indonezja
Japonia
Meksyk
Katar
Rosja
Singapur
Szwajcaria
Tajlandia
Turcja
Wielka Brytania
Stany Zjednoczone

Utwórz projekt

Obszerny przykład rozmów transakcyjnych znajdziesz w przykładzie transakcji w Node.js.

Konfiguracja

Podczas tworzenia akcji musisz określić, że chcesz przeprowadzać transakcje w Konsoli Actions.

Aby skonfigurować projekt i realizację:

  1. Utwórz nowy projekt lub zaimportuj istniejący.
  2. Kliknij Wdróż > Informacje z katalogu.
  3. W sekcji Dodatkowe informacje > Transakcje zaznacz pole „Czy Twoje działania używają interfejsu Transaction API do realizacji transakcji towarów fizycznych?”.

Zweryfikuj wymagania dotyczące transakcji (opcjonalnie)

Gdy tylko użytkownik zgłosi, że chce zrobić rezerwację, sprawdź, czy może to zrobić. Po wywołaniu akcja może na przykład zapytać: „Czy chcesz zarezerwować miejsce?” Jeśli użytkownik odpowie „Tak”, upewnij się, że może kontynuować i pozwól mu poprawić ustawienia, które uniemożliwiają kontynuowanie transakcji. Aby to zrobić, należy przejść do sceny, która sprawdza wymagania dotyczące transakcji.

Tworzenie sceny kontroli wymagań transakcji

  1. Na karcie Sceny dodaj nową scenę o nazwie TransactionRequirementsCheck.
  2. W sekcji Wypełnianie przedziałów kliknij +, aby dodać nowe boksy.
  3. W sekcji Wybierz typ wybierz actions.type.TransactionRequirementsCheckResult jako typ boksu.
  4. W polu nazwy boksu nadaj boksowi nazwę TransactionRequirementsCheck.
  5. Zaznacz pole wyboru Dostosuj zapis wartości przedziału (domyślnie włączone).
  6. Kliknij Zapisz.

Sprawdzenie wymagań dotyczących transakcji może mieć jeden z tych wyników:

  • Jeśli zostaną spełnione wymagania, parametr sesji jest ustawiany jako warunek powodzenia i możesz kontynuować tworzenie zamówienia użytkownika.
  • Jeśli co najmniej 1 z wymagań nie zostanie spełniony, parametr sesji będzie miał warunek niepowodzenia. W takim przypadku należy odwrócić rozmowę od procesu transakcyjnego lub zakończyć rozmowę.
    • Jeśli użytkownik będzie w stanie naprawić błędy, które spowodowały błąd, pojawi się prośba o rozwiązanie tych problemów na urządzeniu. Jeśli rozmowa odbywa się tylko na platformie głosowej, połączenie zostanie zainicjowane w telefonie użytkownika.

Obsługa wyniku kontroli wymagań dotyczących transakcji

  1. Na karcie Sceny wybierz nowo utworzoną scenę TransactionRequirementsCheck.
  2. W sekcji Warunek kliknij +, by dodać nowy warunek.
  3. W polu tekstowym wpisz tę składnię warunku, aby sprawdzić, czy występuje warunek powodzenia:

    scene.slots.status == "FINAL" && session.params.TransactionRequirementsCheck.resultType == "CAN_TRANSACT"
    
  4. Najedź kursorem na dodany warunek i kliknij strzałkę w górę, aby umieścić go przed if scene.slots.status == "FINAL".

  5. Włącz Wyślij potwierdzenia i daj użytkownikowi znać, że jest gotowy do dokonania transakcji:

    candidates:
      - first_simple:
          variants:
            - speech: >-
                Looks like you're good to go!.
    
  6. W sekcji Przejście wybierz inną scenę, aby użytkownik mógł kontynuować rozmowę i dokonać transakcji.

  7. Wybierz warunek else if scene.slots.status == "FINAL".

  8. Włącz Wyślij potwierdzenia i daj użytkownikowi znać, że nie może dokonać transakcji:

    candidates:
      - first_simple:
          variants:
            - speech: Transaction requirements check failed.
    
  9. W sekcji Przenoszenie wybierz Zakończ rozmowę, aby zakończyć rozmowę, jeśli użytkownik nie może dokonać transakcji.

Tworzenie zamówienia

Gdy masz potrzebne informacje o użytkowniku, utwórz proces składania koszyka, by pomógł mu utworzyć rezerwację. W przypadku każdego działania proces składania koszyka będzie przebiegał trochę inaczej, zależnie od usługi.

W prostym procesie składania koszyka użytkownik wybiera z listy opcje, które chce dodać do swojej rezerwacji. Możesz jednak zaprojektować rozmowę w taki sposób, aby zwiększyć wygodę użytkowników. Przykładem może być proces składania koszyka, który pozwala użytkownikowi zaplanować miesięczną rezerwację z prostym pytaniem „tak” lub „nie”. Możesz też pokazać użytkownikowi karuzelę lub kartę listy z rezerwacjami z „rekomendowanymi” rezerwacjami.

Zalecamy stosowanie odpowiedzi rozszerzonych do wizualnego przedstawienia opcji użytkownika, ale także tak opracowanie rozmowy, aby użytkownik mógł utworzyć koszyk tylko za pomocą głosu. Sprawdzone metody i przykłady procesu składania koszyków znajdziesz w wytycznych dotyczących projektowania.

Tworzenie zamówienia

W trakcie rozmowy zbierz szczegóły rezerwacji użytkownika, a następnie utwórz obiekt Order.

Order musi zawierać co najmniej:

  • buyerInfo – informacje o użytkowniku dokonującym zakupu.
  • transactionMerchant – informacje o sprzedawcy, który złożył zamówienie.
  • contents – rzeczywista zawartość zamówienia podana jako lineItems.

Aby utworzyć koszyk, zapoznaj się z dokumentacją odpowiedzi Order. Pamiętaj, że w zależności od rezerwacji konieczne może być dodanie innych pól.

Przykładowy kod poniżej pokazuje pełne zamówienie rezerwacji z opcjonalnymi polami:

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

Opcje tworzenia kolejności i prezentacji

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

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

Zapisz dane zamówienia w parametrze sesji

Na stronie realizacji zamówienia zapisz dane zamówienia w parametrze sesji. Obiekt zamówienia będzie używany w różnych scenach w tej samej sesji.

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

Zaproponuj zamówienie

Po utworzeniu zamówienia rezerwacji musisz przedstawić je użytkownikowi, aby mógł je potwierdzić lub odrzucić. Aby to zrobić, należy przejść do sceny, w której przeprowadza się decyzję o transakcji.

Tworzenie sceny podejmowania decyzji o transakcji

  1. Na karcie Sceny dodaj nową scenę o nazwie TransactionDecision.
  2. W sekcji Wypełnianie przedziałów kliknij +, aby dodać nowe boksy.
  3. W sekcji Wybierz typ wybierz actions.type.TransactionDecisionValue jako typ boksu.
  4. W polu nazwy boksu nadaj boksowi nazwę TransactionDecision.
  5. Zaznacz pole wyboru Dostosuj zapis wartości przedziału (domyślnie włączone).
  6. W sekcji Skonfiguruj przedział wybierz z menu Użyj parametru sesji.
  7. W sekcji Skonfiguruj przedział wpisz w polu tekstowym nazwę parametru sesji,który służy do przechowywania zamówienia (np. $session.params.order).
  8. Kliknij Zapisz.

Próbując wypełnić boks TransactionDecisionValue, Asystent inicjuje wbudowane środowisko, w którym przekazywana wartość Order jest renderowana bezpośrednio na „karcie podglądu koszyka”. Użytkownik może powiedzieć „Zaplanuj rezerwację”, odrzucić transakcję lub poprosić o zmianę szczegółów rezerwacji.

W tym momencie użytkownik może też poprosić o zmianę zamówienia. W takim przypadku upewnij się, że po zakończeniu procesu składania zamówień realizacja zamówień może być obsługiwana przez prośby o zmianę zamówienia.

Obsługa wyniku decyzji o transakcji

Po wypełnieniu boksu TransactionDecisionValue odpowiedź użytkownika na decyzję o transakcji zostanie zapisana w parametrze sesji. Ta wartość obejmuje te elementy:

  • ORDER_ACCEPTED,
  • ORDER_REJECTED,
  • CART_CHANGE_REQUESTED
  • USER_CANNOT_TRANSACT.

Aby obsługiwać wynik decyzji o transakcji:

  1. Na karcie Sceny wybierz nowo utworzoną scenę TransactionDecision.
  2. W sekcji Warunek kliknij +, by dodać nowy warunek.
  3. W polu tekstowym wpisz tę składnię warunku, aby sprawdzić, czy występuje warunek powodzenia:

    scene.slots.status == "FINAL" && session.params.TransactionDecision.transactionDecision == "ORDER_ACCEPTED"
    
  4. Najedź kursorem na dodany warunek i kliknij strzałkę w górę, aby umieścić go przed if scene.slots.status == "FINAL".

  5. Włącz Wysyłanie potwierdzeń i wyświetlaj proste powiadomienie informujące użytkownika o zakończeniu rezerwacji:

    candidates:
      - first_simple:
          variants:
            - speech: >-
                Transaction completed! Your reservation
                $session.params.TransactionDecision.order.merchantOrderId is all
                set!
    
  6. W sekcji Przenoszenie wybierz Zakończ rozmowę, aby zakończyć rozmowę.

  7. W sekcji Warunek kliknij +, by dodać nowy warunek.

  8. W polu tekstowym wpisz tę składnię warunku, aby sprawdzić, czy nie wystąpił błąd:

      scene.slots.status == "FINAL" && session.params.TransactionDecision.transactionDecision == "ORDER_REJECTED"
    
  9. Najedź kursorem na dodany warunek i kliknij strzałkę w górę, aby umieścić go przed if scene.slots.status == "FINAL".

  10. Włącz Wyślij potwierdzenia i podaj użytkownikowi prostą wiadomość, która poinformuje użytkownika o odrzuceniu zamówienia:

    candidates:
      - first_simple:
          variants:
            - speech: Looks like you don't want to set up a reservation. Goodbye.
    
  11. W sekcji Przenoszenie wybierz Zakończ rozmowę, aby zakończyć rozmowę.

  12. Wybierz warunek else if scene.slots.status == "FINAL".

  13. Włącz Wysyłanie potwierdzeń i wyświetlaj proste powiadomienie informujące użytkownika, że nie może dokonać transakcji:

    candidates:
      - first_simple:
          variants:
            - speech: >-
                Transaction failed with status
                $session.params.TransactionDecision.transactionDecision
    
  14. W sekcji Przenoszenie wybierz Zakończ rozmowę, aby zakończyć rozmowę, jeśli użytkownik nie może dokonać transakcji.

Dokończ rezerwację i wyślij rachunek

Gdy przedział TransactionDecisionValue zwraca wynik funkcji ORDER_ACCEPTED, musisz od razu przeprowadzić przetwarzanie wymagane do zaplanowania rezerwacji (np. zachować ją w Twojej własnej bazie danych).

Wyślij prostą odpowiedź, aby podtrzymać rozmowę. Użytkownik otrzymuje „zwiniętą kartę potwierdzenia” wraz z Twoją odpowiedzią.

Aby wysłać wstępną aktualizację zamówienia:

  1. Na karcie Sceny wybierz scenę TransactionDecision.
  2. W sekcji Warunek wybierz warunek, który ma sprawdzić powodzenie:ORDER_ACCEPTED

    scene.slots.status == "FINAL" && session.params.TransactionDecision.transactionDecision == "ORDER_ACCEPTED"
    
  3. W przypadku tego warunku włącz Wywołaj webhooka i podaj nazwę modułu obsługi intencji, np. update_order.

  4. W kodzie webhooka dodaj moduł obsługi intencji, który służy do wysyłania początkowej aktualizacji zamówienia:

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

Wysyłanie aktualizacji zamówienia

Stan rezerwacji zmienia się w trakcie jej życia. Wysyła do interfejsu Orders API aktualizacje dotyczące zamówień rezerwacji użytkownika wraz z żądaniami HTTP PATCH wraz z informacjami o stanie i szczegółach zamówienia.

Konfigurowanie żądań asynchronicznych kierowanych do interfejsu Orders API

Żądania aktualizacji zamówień wysyłane do interfejsu Orders API są autoryzowane przez token dostępu. Aby ŁATWIĆ aktualizację zamówienia do interfejsu Orders API, pobierz klucz konta usługi JSON powiązany z projektem w Actions Console, a następnie wymień klucz konta usługi na token okaziciela, który można przekazać do nagłówka Authorization żądania HTTP.

Aby pobrać klucz konta usługi, wykonaj te czynności:

  1. W konsoli Google Cloud wybierz Menu />< > Interfejsy API i usługi > Dane logowania > Utwórz dane logowania > Klucz konta usługi.
  2. W sekcji Service Account (Konto usługi) wybierz New Service Account (Nowe konto usługi).
  3. Ustaw konto usługi na service-account.
  4. Ustaw Rolę na Projekt > Właściciel.
  5. Ustaw typ klucza na JSON.
  6. Wybierz Utwórz.
  7. Na Twój komputer zostanie pobrany prywatny klucz konta usługi JSON.

W kodzie aktualizacji zamówienia wymień klucz usługi na token okaziciela, korzystając z biblioteki klienta interfejsów API Google i zakresu "https://www.googleapis.com/auth/actions.order.developer". Instrukcje instalacji i przykłady znajdziesz na stronie w GitHubie w bibliotece klienta interfejsu API.

Przykład wymiany kluczy znajdziesz w przykładzie Node.js, w którym znajdziesz odniesienia do order-update.js.

Wysyłanie aktualizacji zamówienia

Po wymianie klucza konta usługi na token okaziciela OAuth przesyłaj aktualizacje zamówień jako autoryzowane żądania PATCH do interfejsu Orders API.

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

Podaj te nagłówki w żądaniu:

  • "Authorization: Bearer token" z tokenem okaziciela OAuth, na który wymieniono klucz konta usługi.
  • "Content-Type: application/json".

Żądanie PATCH powinno mieć treść JSON w tym formacie:

{ "orderUpdate": OrderUpdate }

Obiekt OrderUpdate składa się z tych pól najwyższego poziomu:

  • updateMask – pola zamówienia, które aktualizujesz. Aby zaktualizować stan rezerwacji, ustaw wartość na reservation.status, reservation.userVisibleStatusLabel.
  • order – zawartość aktualizacji. Jeśli aktualizujesz zawartość rezerwacji, ustaw wartość na zaktualizowany obiekt Order. Jeśli tylko aktualizujesz stan rezerwacji (na przykład z "PENDING" na "FULFILLED"), obiekt zawiera te pola:

    • merchantOrderId – identyfikator ustawiony w obiekcie Order.
    • lastUpdateTime – sygnatura czasowa aktualizacji.
    • purchase – obiekt zawierający:
      • status – stan zamówienia to ReservationStatus, np. „CONFIRMED” lub „CANCELLED”.
      • userVisibleStatusLabel – widoczna dla użytkowników etykieta ze szczegółowymi informacjami o stanie zamówienia, np. „Twoja rezerwacja została potwierdzona”.
  • userNotification, który może się wyświetlać na urządzeniu użytkownika po wysłaniu tej aktualizacji. Pamiętaj, że uwzględnienie tego obiektu nie gwarantuje, że powiadomienie pojawi się na urządzeniu użytkownika.

Poniżej znajduje się przykładowy kod OrderUpdate, który aktualizuje stan zamówienia rezerwacji na 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}`);
}

Ustawianie stanu rezerwacji

Pole ReservationStatus aktualizacji zamówienia musi zawierać opis jego bieżącego stanu. W polu order.ReservationStatus aktualizacji użyj jednej z tych wartości:

  • PENDING – rezerwacja została „utworzona” przez akcję, ale wymaga dodatkowego przetwarzania przez backend.
  • CONFIRMED – rezerwacja została potwierdzona w backendzie harmonogramu.
  • CANCELLED – użytkownik anulował rezerwację.
  • FULFILLED – rezerwacja użytkownika została zrealizowana przez usługę.
  • CHANGE_REQUESTED – użytkownik poprosił o zmianę rezerwacji, a zmiana jest przetwarzana.
  • REJECTED – jeśli nie udało Ci się przetworzyć rezerwacji lub potwierdzić ją w inny sposób.

Wysyłaj aktualizacje zamówień o każdym stanie, który ma znaczenie dla Twojej rezerwacji. Jeśli na przykład rezerwacja wymaga ręcznego przetworzenia w celu potwierdzenia rezerwacji po jej przesłaniu, wysyłaj aktualizację zamówienia PENDING do czasu zakończenia dodatkowego przetwarzania. Nie każda rezerwacja wymaga każdej wartości stanu.

Testowanie projektu

Podczas testowania projektu możesz włączyć tryb piaskownicy w Konsoli Actions, aby testować akcję bez obciążania formy płatności. Aby włączyć tryb piaskownicy, wykonaj te czynności:

  1. W panelu nawigacyjnym w Konsoli Actions kliknij Przetestuj.
  2. Kliknij Ustawienia.
  3. Włącz opcję Piaskownica dla programistów.

W przypadku transakcji fizycznych możesz też ustawić w polu isInSandbox wartość true w próbce. To działanie odpowiada włączeniu ustawienia trybu piaskownicy w konsoli Actions. Aby zobaczyć fragment kodu, który używa isInSandbox, zapoznaj się z sekcją Wysyłanie aktualizacji zamówień.

Rozwiązywanie problemów

Jeśli podczas testowania napotkasz jakieś problemy, przeczytaj nasze instrukcje rozwiązywania problemów z transakcjami.