予約の作成

このガイドでは、Actions プロジェクトの開発プロセスについて説明します。 注文を処理する方法を紹介します

取引の流れ

Actions プロジェクトで予約を処理する際、 次のフローを使用します。

  1. 取引の要件を検証する(省略可) - 取引を使用します。 会話の最初に確認しておくことで、 ユーザーが取引を実行できます。
  2. 注文を作成する - お客様に 「カート アセンブリ」予約の詳細を作成します
  3. 注文を提案する - カート予約「order」を提案しますから 正しいことを確認します。予約が確定すると 予約の詳細を含むレスポンスが返されます。
  4. 注文を確定して領収書を送信する - 注文を確定したら、更新します。 お客様に領収書を送信します
  5. 注文の最新情報を送信する - 予約の存続期間中、 ユーザーの予約状況を更新するには、PATCH リクエストを Orders API です。

制限と審査のガイドライン

追加のポリシーが適用されるのは、 トランザクションと Orders API ですアクションの審査には最大 6 週間かかる トランザクションに伴って発生するデータなので、リリーススケジュールを計画する際にはこの時間を考慮してください。 審査プロセスを容易にするため、 取引に関するポリシーとガイドライン 提出してください。

Orders API を使用するアクションは、次の国でのみデプロイできます。

オーストラリア
ブラジル
カナダ
インドネシア
日本
メキシコ
カタール
ロシア
シンガポール
スイス
タイ
トルコ
英国
米国

プロジェクトのビルド

取引に関する会話の例については、Google の取引履歴 Node.js のサンプル

セットアップ

アクションを作成するときは、取引を実行することを指定する必要があります。 Actions Console を使用します。

プロジェクトとフルフィルメントを設定する手順は次のとおりです。

  1. 新しいプロジェクトを作成するか、既存のプロジェクトをインポートします。
  2. [デプロイ] > [ディレクトリ情報] の順に移動します。
  3. [その他の情報] >トランザクション >[Do your Actions] というチェックボックスをオンにして 「トランザクション API を使用して物理的な商品の取引を実行する」という質問です。

取引要件を確認する(省略可)

ユーザーが予約の意思表示を示したら、すぐに 予約をリクエストできます。たとえば、アクションが呼び出されたときに、そのアクションは 「座席を予約しますか?」と尋ねるユーザーが「はい」と答えたら、 お客様に手続きを進めていただき、必要に応じて設定を修正する機会を提供していただく 取引を続行できないようにしますそのためには、 トランザクション要件チェックを実行するシーンに遷移します。

トランザクション要件チェックシーンを作成する

  1. [Scenes] タブで、名前を指定して新しいシーンを追加します。 TransactionRequirementsCheck
  2. [スロット充填] で [+] をクリックして、新しいスロットを追加します。
  3. [Select type] で [actions.type.TransactionRequirementsCheckResult] を選択します。 選択します
  4. スロット名のフィールドで、スロットに「TransactionRequirementsCheck」という名前を付けます。
  5. [スロット値のライトバックをカスタマイズする] チェックボックスを有効にします(デフォルトで有効になっています)。
  6. [保存] をクリックします。

トランザクション要件の確認では、次のいずれかの結果になります。

  • 要件を満たしている場合、セッション パラメータは「成功」 ユーザーの注文の作成に進むことができます。
  • 1 つ以上の要件を満たせない場合、セッション パラメータは 失敗条件で設定されますこの場合、会話を方向転換して、 会話を終了することもできます。
    • 障害状態の原因となったエラーがユーザーによって修正できる場合は、デバイスにプロンプトが表示され、問題を解決するようユーザーに促します。もし 行われる場合、ハンドオフは ユーザーのスマートフォンで開始される。

トランザクション要件チェック結果の処理

  1. [Scenes] タブで、新しく作成した TransactionRequirementsCheck 個のシーン。
  2. [Condition] で、[+] をクリックして新しい条件を追加します。
  3. テキスト フィールドに次の条件構文を入力して、 成功条件:

    scene.slots.status == "FINAL" && session.params.TransactionRequirementsCheck.resultType == "CAN_TRANSACT"
    
  4. 先ほど追加した条件にカーソルを合わせて、上矢印アイコンをクリックします。 if scene.slots.status == "FINAL" より前に配置する必要があります。

  5. [プロンプトを送信] を有効にし、簡単なプロンプトでユーザーに知らせる 取引を行う準備ができている:

    candidates:
      - first_simple:
          variants:
            - speech: >-
                Looks like you're good to go!.
    
  6. [Transition] で別のシーンを選択し、ユーザーが続行できるようにします。 手続きを進めます

  7. 条件 else if scene.slots.status == "FINAL" を選択します。

  8. [プロンプトを送信] を有効にし、簡単なプロンプトでユーザーに知らせる 取引を行うことができません。

    candidates:
      - first_simple:
          variants:
            - speech: Transaction requirements check failed.
    
  9. [切り替え] で [会話を終了] を選択して、会話を終了します。 ユーザーが取引を行えない場合

注文を作成する

必要なユーザー情報を入手したら、カートを作成します。 組み立てます」ユーザーが予約を構築するためのガイドになります。毎 アクションのカート アセンブリ フローは、ユーザーのニーズに応じて若干異なります。 あります。

基本的なカート アセンブリのエクスペリエンスでは、ユーザーがリストからオプションを選択して追加する 会話を設計することもできますが、 向上させることができますたとえば、カート アセンブリのエクスペリエンスを作成し、 「はい」か「いいえ」で答える簡単な質問で、毎月の予約を申し込むことができます。 ユーザーに「おすすめ」のカルーセルまたはリストカードを表示することもできます。 できます。

リッチ レスポンスを使用して、 ユーザーの選択肢を視覚的に提示するだけでなく、 ユーザーは音声だけでカートを作成できますベスト プラクティスとベスト プラクティスについては、 カート アセンブリの例については、設計ガイドラインをご覧ください。

注文を作成する

会話を通じて、ユーザーの予約の詳細情報を収集し、 Order オブジェクトを作成します。

Order には少なくとも次のものが含まれている必要があります。

  • buyerInfo - 商品を購入しようとしているユーザーに関する情報。
  • transactionMerchant - 注文を処理した販売者に関する情報。
  • contents - lineItems として列挙される注文の実際の内容。
で確認できます。

詳しくは、Order レスポンス ドキュメントをご覧ください。必要に応じて 異なるフィールドを使用します。

次のサンプルコードは、省略可能なフィールドを含む完全な予約注文を示しています。

const order = {
   createTime: '2019-09-24T18:00:00.877Z',
   lastUpdateTime: '2019-09-24T18:00:00.877Z',
   merchantOrderId: orderId, // A unique ID String for the order
   userVisibleOrderId: orderId,
   transactionMerchant: {
     id: 'http://www.example.com',
     name: 'Example Merchant',
   },
   contents: {
     lineItems: [
       {
         id: 'LINE_ITEM_ID',
         name: 'Dinner reservation',
         description: 'A world of flavors all in one destination.',
         reservation: {
           status: 'PENDING',
           userVisibleStatusLabel: 'Reservation is pending.',
           type: 'RESTAURANT',
           reservationTime: {
             timeIso8601: '2020-01-16T01:30:15.01Z',
           },
           userAcceptableTimeRange: {
             timeIso8601: '2020-01-15/2020-01-17',
           },
           partySize: 6,
           staffFacilitators: [
             {
               name: 'John Smith',
             },
           ],
           location: {
             zipCode: '94086',
             city: 'Sunnyvale',
             postalAddress: {
               regionCode: 'US',
               postalCode: '94086',
               administrativeArea: 'CA',
               locality: 'Sunnyvale',
               addressLines: [
                 '222, Some other Street',
               ],
             },
           },
         },
       },
     ],
   },
   buyerInfo: {
     email: 'janedoe@gmail.com',
     firstName: 'Jane',
     lastName: 'Doe',
     displayName: 'Jane Doe',
   },
   followUpActions: [
     {
       type: 'VIEW_DETAILS',
       title: 'View details',
       openUrlAction: {
         url: 'http://example.com',
       },
     },
     {
       type: 'CALL',
       title: 'Call us',
       openUrlAction: {
         url: 'tel:+16501112222',
       },
     },
     {
       type: 'EMAIL',
       title: 'Email us',
       openUrlAction: {
         url: 'mailto:person@example.com',
       },
     },
   ],
   termsOfServiceUrl: 'http://www.example.com'
 };

注文オプションとプレゼンテーション オプションを作成する

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

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

注文データをセッション パラメータに保存する

フルフィルメントから、注文データをセッション パラメータに保存します。注文 同じセッションのシーンを越えて使用されます。

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

注文内容を表示する

予約注文を作成したら、ユーザーにその注文を提示する必要があります。 確認または拒否します。そのためには、トランザクションを実行するシーンに移行する必要があります。 判断します

取引決定シーンを作成する

  1. [Scenes] タブで、TransactionDecision という名前の新しいシーンを追加します。
  2. [スロット充填] で [+] をクリックして、新しいスロットを追加します。
  3. [Select type] で、actions.type.TransactionDecisionValue を選択します。 スロットタイプを指定します。
  4. スロット名のフィールドで、スロットに「TransactionDecision」という名前を付けます。
  5. [スロット値のライトバックをカスタマイズする] チェックボックスを有効にします(デフォルトで有効になっています)。
  6. [スロットの設定] で、プルダウンから [セッション パラメータを使用] を選択します。
  7. [スロットの設定] で、使用するセッション パラメータの名前を入力します。 注文をテキスト フィールド($session.params.order)に保存します。
  8. [保存] をクリックします。

TransactionDecisionValue スロットを埋めようとすると、アシスタントは次の処理を開始します。 渡した Order が直接レンダリングされる、組み込みのエクスペリエンス カートのプレビューカード「予約」と言ってから取引を拒否し、 予約の詳細の変更をリクエストできます。

ユーザーはこの時点で注文内容の変更をリクエストできます。今回は 変更後は、フルフィルメントが注文変更リクエストを処理できるように カートの組み立て作業を完了します

取引判断の結果を処理する

TransactionDecisionValue スロットがいっぱいになると、ユーザーの応答は、 トランザクションの決定はセッション パラメータに格納されます。この値に含まれるもの 次のとおりです。

  • ORDER_ACCEPTED
  • ORDER_REJECTED
  • CART_CHANGE_REQUESTED
  • USER_CANNOT_TRANSACT

トランザクションの決定結果を処理するには:

  1. [Scenes] タブで、新しく作成した TransactionDecision シーンを選択します。
  2. [Condition] で、[+] をクリックして新しい条件を追加します。
  3. テキスト フィールドに次の条件構文を入力して、 成功条件:

    scene.slots.status == "FINAL" && session.params.TransactionDecision.transactionDecision == "ORDER_ACCEPTED"
    
  4. 先ほど追加した条件にカーソルを合わせて、上矢印アイコンをクリックします。 if scene.slots.status == "FINAL" より前に配置する必要があります。

  5. [プロンプトを送信] を有効にし、簡単なプロンプトでユーザーに知らせる 予約が完了しています。

    candidates:
      - first_simple:
          variants:
            - speech: >-
                Transaction completed! Your reservation
                $session.params.TransactionDecision.order.merchantOrderId is all
                set!
    
  6. [切り替え] で [会話を終了] を選択して、会話を終了します。

  7. [Condition] で、[+] をクリックして新しい条件を追加します。

  8. テキスト フィールドに次の条件構文を入力して、 失敗条件:

      scene.slots.status == "FINAL" && session.params.TransactionDecision.transactionDecision == "ORDER_REJECTED"
    
  9. 先ほど追加した条件にカーソルを合わせて、上矢印アイコンをクリックします。 if scene.slots.status == "FINAL" より前に配置する必要があります。

  10. [プロンプトを送信] を有効にし、簡単なプロンプトで、 承認されなかった場合:

    candidates:
      - first_simple:
          variants:
            - speech: Looks like you don't want to set up a reservation. Goodbye.
    
  11. [切り替え] で [会話を終了] を選択して、会話を終了します。

  12. 条件 else if scene.slots.status == "FINAL" を選択します。

  13. [プロンプトを送信] を有効にし、簡単なプロンプトでユーザーに知らせる 取引を行うことができません。

    candidates:
      - first_simple:
          variants:
            - speech: >-
                Transaction failed with status
                $session.params.TransactionDecision.transactionDecision
    
  14. [切り替え] で [会話を終了] を選択して、会話を終了します。 ユーザーが取引を行えない場合

予約を確定して領収書を送る

TransactionDecisionValue スロットが ORDER_ACCEPTED の結果を返す場合、 スケジュールに必要な処理は すぐに行う必要があります (独自のデータベースでの永続化など)。

シンプルな返信文を送信して会話を続けます。ユーザーは 「折りたたまれた領収書カード」回答が表示されます

最初の注文の更新情報を送信するには:

  1. [Scenes] タブから、TransactionDecision シーンを選択します。
  2. [Condition] で、成功の結果を確認する条件を選択します。 ORDER_ACCEPTED:

    scene.slots.status == "FINAL" && session.params.TransactionDecision.transactionDecision == "ORDER_ACCEPTED"
    
  3. この条件に対して [Call your webhook] を有効にし、インテントを指定します。 ハンドラ名(例: update_order

  4. Webhook のコードで、最初の注文更新を送信するためのインテント ハンドラを追加します。

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

注文の更新情報を送信する

予約のステータスは、存続期間中に変化します。お客様を送信する Orders API への HTTP PATCH リクエストによる予約注文の更新( 注文ステータスと詳細が表示されます

Orders API に非同期リクエストを設定する

Orders API への注文更新リクエストはアクセス権によって承認される あります。Orders API で注文の更新を PATCH するには、JSON をダウンロードしてください。 サービス アカウント キーを使用して ID を交換し、 サービス アカウント キーに、署名なしトークンの HTTP リクエストの Authorization ヘッダー。

サービス アカウント キーを取得するには、次の手順に従います。

  1. Google Cloud コンソールで次の操作を行います。 メニュー 💻? > に移動API とサービス >クルデンシャル >認証情報を作成 >サービス アカウント キー
  2. [サービス アカウント] で [新しいサービス アカウント] を選択します。
  3. サービス アカウントを service-account に設定します。
  4. [役割] を [プロジェクト] > [オーナー] に設定します。
  5. キータイプを [JSON] に設定します。
  6. [作成] を選択します。
  7. 非公開の JSON サービス アカウント キーがローカルマシンにダウンロードされます。

注文更新コードでサービスキーを署名なしトークンと交換します Google API クライアント ライブラリと "https://www.googleapis.com/auth/actions.order.developer" スコープ。詳しくは、 API クライアント ライブラリのインストール手順と例 GitHub ページ

Node.js サンプルorder-update.js を参照する 鍵交換の例をご覧ください。

注文の更新情報を送信する

サービス アカウント キーを OAuth 署名なしトークンと交換したら、 承認済みの PATCH リクエストとして Orders API に送ります。

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

リクエストに次のヘッダーを指定します。

  • "Authorization: Bearer token" は、OAuth 署名なしトークンに置き換えます サービス アカウント キーを交換した場所。
  • "Content-Type: application/json"

PATCH リクエストは、次の形式の JSON 本文を使用します。

{ "orderUpdate": OrderUpdate }

OrderUpdate オブジェクトは、次のトップレベル フィールドで構成されています。

  • updateMask - 更新する注文のフィールド。更新するには、 予約ステータス、 値を reservation.status, reservation.userVisibleStatusLabel に設定します。
  • order - 更新の内容。Deployment を更新する場合は、 予約の内容を確認するには、値を更新後の Order オブジェクトに設定します。 予約のステータスを更新するだけの場合(たとえば、 "PENDING" から "FULFILLED" など)、オブジェクトには 次のフィールドがあります。

    • merchantOrderId - Order オブジェクトで設定したのと同じ ID。
    • lastUpdateTime - この更新のタイムスタンプ。
    • purchase - 以下を含むオブジェクト。 <ph type="x-smartling-placeholder">
        </ph>
      • status - ReservationStatus としての注文のステータス。 例: 「CONFIRMED」または「CANCELLED」。
      • userVisibleStatusLabel - 詳細情報を提供するユーザー向けのラベル 注文ステータス(「予約が確定しました」など)
  • userNotification (省略可) - A userNotification この更新の送信時にユーザーのデバイスに表示できるオブジェクトです。備考 このオブジェクトを含めても、通知が アクセスします。

次のサンプルコードは、バージョンを更新する OrderUpdate の例を示しています。 予約注文のステータスを FULFILLED に送信します。

// Import the 'googleapis' module for authorizing the request.
const {google} = require('googleapis');
// Import the 'request-promise' module for sending an HTTP POST request.
const request = require('request-promise');
// Import the OrderUpdate class from the client library.
const {OrderUpdate} = require('@assistant/conversation');

// Import the service account key used to authorize the request.
// Replacing the string path with a path to your service account key.
// i.e. const serviceAccountKey = require('./service-account.json')

// Create a new JWT client for the Actions API using credentials
// from the service account key.
let jwtClient = new google.auth.JWT(
   serviceAccountKey.client_email,
   null,
   serviceAccountKey.private_key,
   ['https://www.googleapis.com/auth/actions.order.developer'],
   null,
);

// Authorize the client
let tokens = await jwtClient.authorize();

// Declare the ID of the order to update.
const orderId = '<UNIQUE_MERCHANT_ORDER_ID>';

// Declare order update
const orderUpdate = new OrderUpdate({
   updateMask: {
     paths: [
       'contents.lineItems.reservation.status',
       'contents.lineItems.reservation.userVisibleStatusLabel'
     ]
   },
   order: {
     merchantOrderId: orderId, // Specify the ID of the order to update
     lastUpdateTime: new Date().toISOString(),
     contents: {
       lineItems: [
         {
           reservation: {
             status: 'FULFILLED',
             userVisibleStatusLabel: 'Reservation fulfilled',
           },
         }
       ]
     },
   },
   reason: 'Reservation status was updated to fulfilled.',
});

// Set up the PATCH request header and body,
// including the authorized token and order update.
let options = {
 method: 'PATCH',
 uri: `https://actions.googleapis.com/v3/orders/${orderId}`,
 auth: {
   bearer: tokens.access_token,
 },
 body: {
   header: {
     isInSandbox: true,
   },
   orderUpdate,
 },
 json: true,
};

// Send the PATCH request to the Orders API.
try {
 await request(options);
} catch (e) {
 console.log(`Error: ${e}`);
}

予約ステータスを設定する

注文の更新の ReservationStatus 注文の現在の状態を示す必要がありますアップデートの order.ReservationStatus 次のいずれかの値を使用します。

  • PENDING - 予約は作成されました指定することもできますが、 バックエンドで追加の処理を行えます
  • CONFIRMED - 予約がスケジューリング バックエンドで確認されました。
  • CANCELLED - ユーザーが予約をキャンセルしました。
  • FULFILLED - ユーザーの予約がサービスによって履行されました。
  • CHANGE_REQUESTED - ユーザーが予約の変更をリクエストし、変更が あります。
  • REJECTED - 処理できなかった場合 予約を確認します。

お客様に関連するステータスごとに できます。たとえば、予約で手動処理が必要な場合に、 リクエスト後に予約を確定したら、PENDING の注文更新情報を送信します。期限: 追加の処理が行われます。すべての予約でステータス値が必要になるとは限りません。

プロジェクトをテストする

プロジェクトをテストする際に、Actions Console でサンドボックス モードを有効にできます。 支払い方法に請求せずにアクションをテストできます。 サンドボックス モードを有効にする手順は次のとおりです。

  1. Actions Console で、ナビゲーションの [Test](テスト)をクリックします。
  2. [設定] をクリックします。
  3. [Development Sandbox] オプションを有効にします。

現物取引の場合は、isInSandbox フィールドを true に設定することもできます。 選択できます。この操作は、 アクセスすることもできます。isInSandbox を使用するコード スニペットについては、以下をご覧ください。 [注文の最新情報を送信する] セクション。

トラブルシューティング

テスト中に問題が発生した場合は、トラブルシューティングの手順をご覧ください。 提供しています