Actions SDK を使用して Google アシスタントのアクションを構築する(レベル 2)

Google アシスタントのデベロッパー プラットフォームを使用すると、Google アシスタントのバーチャル パーソナル アシスタント機能を拡張するソフトウェアを作成し、スマート スピーカー、スマートフォン、自動車、テレビ、ヘッドフォンなど 10 億以上のデバイスで公開できます。ユーザーは、Google アシスタントとの会話を通じて、食料品の購入から乗車の予約までさまざまなタスクを実行できます。Google アシスタントのデベロッパー プラットフォームを使用することで、サードパーティ フルフィルメント サービスを開発し、ユーザーとの快適かつ効果的な会話型エクスペリエンスを簡単に作成、管理できます。

この Codelab では、Google アシスタントでの開発に関する中級レベルのコンセプトについて解説し、レベル 1 の Codelab で作成したアクションをベースにより高度なアクションを構築します。このチュートリアルを始める前に、レベル 1 の Codelab を完了することを強くおすすめします。

この Codelab で構築するのは、架空の地「グリフィンバーグ」の冒険に出掛けるユーザーが、旅に持っていくアイテムとして何を選んだかに応じて運勢を伝えるアクションです。

目標

この Codelab では、以下の機能を備えた高度な会話型アクションを構築します。

  • ユーザーからデータを収集し、値に応じて会話のプロンプトを変更する。
  • 会話を続けるためにフォローアップの質問をする。
  • ゲームループを作成し、ユーザーが運勢を聞いた後にアクションとやり取りできるようにする。

構築を開始する前に、公開済みのアクションで会話を試すことができます。Google アシスタント対応デバイスを用意し、「OK Google, talk to Fate and Fortune」(OK Google, 旅の運勢を占う)と話しかけてください。このアクションのデフォルト パスは次のようなやり取りになります。この会話では、ユーザーがアイテムを何度か選び直しています。

dd6f5c61296b8b50.png

eba043f546aa8c51.png

演習内容

  • スロットを使用してユーザーからデータを収集する
  • 条件を使用してシーンにロジックを追加する
  • ゲームループを追加する
  • 補助的なパスを追加する

必要なもの

この Codelab に必要なもの(および前提条件)は以下のとおりです。

  • 任意の IDE またはテキスト エディタ
  • シェルコマンドを実行するためのターミナル(NodeJSnpmgit がインストールされていること)
  • ウェブブラウザ(Google Chrome など)
  • レベル 1 の Codelab を完了し Actions プロジェクトを作成していること

この Codelab のフルフィルメント コードを理解するうえで、JavaScript(ES6)に精通していることを強く推奨しますが、必須ではありません。

サンプルコードを取得する(省略可)

必要に応じて、レベル 1 の完成済みプロジェクト コードはこちらの GitHub リポジトリから、レベル 2 の完成済みプロジェクト コードはこちらの GitHub リポジトリから取得できます。

レベル 1 の Codelab では、1 つのシーン Start のみの簡単な会話型アクションを作成しました。

この Codelab では、レベル 1 で作成したアクションの会話を拡張します。以降のセクションでは、アクションに変更を加えて以下の処理を行えるようにします。

  • ユーザーが運勢を占うことを選択したときに、新しいシーン Fortune に遷移する
  • 旅に持っていくアイテムを選ぶようユーザーに促す
  • ユーザーの選択に応じてカスタマイズされた運勢を返す

Fortune シーンを作成して遷移を定義する

このセクションでは以下を行います。

  • 既存のプロンプト(ユーザーに応答して会話を終了するだけのプロンプト)を Start シーンから削除する
  • Start シーンから Fortune シーンへの遷移を定義する
  • Fortune シーンを作成する

Start シーンに変更を加え、Fortune シーンへの遷移を追加する手順は次のとおりです。

  1. テキスト エディタで、レベル 1 の Codelab の Actions プロジェクトを開きます。
  2. custom/scenes/Start.yaml ファイルを開きます。
  3. yes インテントの handler のコードを、次のスニペットのように変更します。

Start.yaml

intentEvents:
- intent: "yes"
  transitionToScene: Fortune
- handler:
    staticPrompt:
      candidates:
      - promptResponse:
          firstSimple:
            variants:
            - speech: I understand, stranger. Best of luck on your quest! Farewell.
  intent: "no"
  transitionToScene: actions.scene.END_CONVERSATION
  1. ファイルを保存します。

Fortune という新しいシーンを作成する手順は次のとおりです。

  1. ターミナルで Codelab レベル 1 の Actions プロジェクトに移動します。
  2. Fortune.yaml という新しいファイルを scenes ディレクトリに作成します。
touch custom/scenes/Fortune.yaml

このファイルは次のセクションで編集します。

Fortune シーンの会話ロジックを定義する

この Codelab では Fortune シーンに変更を加え、ユーザーに「What do you choose to help you on your quest, a dragon, a translator, or a compass?」(冒険に持っていくアイテムを選んでください。ドラゴン、翻訳機、コンパスの中から選べます)と尋ねられるようにします。ユーザーから前もって必要な情報を収集するため、「スロットフィル」という機能を使用します。

このアクションでは、冒険に持っていくアイテムとして選べる dragon(ドラゴン)、translator(翻訳機)、compass(コンパス)のそれぞれに応じた 3 種類の運勢を用意します。アクションに変更を加え、ユーザー入力からこれら 3 つの選択肢を識別できるようにするには、新しい「型」を作成する必要があります。

シーンのスロットフィル ステージでは、この型を使用してユーザーから収集する情報を定義します。NLU エンジンは、ユーザー入力内に一致するスロットを検出すると、そのスロットを型付きパラメータとして抽出します。取得した値は、シーン内でロジックの実行に使用できます。

available_options 型を作成する

このセクションでは、available_options という新しい型を作成します。この型は、プロンプトへの応答においてユーザーが選択できる 3 種類の選択肢(dragon、translator、compass)を指定するために使用します。また、ユーザーが選択肢の類義語を言った場合に備え、それぞれに似ている言葉もいくつか定義しておきます。後のセクションで available_options 型をスロットに追加し、ユーザーの選択肢を取得できるようにします。

available_options 型を作成する手順は次のとおりです。

  1. types という新しいディレクトリを作成します。
mkdir custom/types
  1. available_options.yaml という新しいファイルを types ディレクトリに作成します。
touch custom/types/available_options.yaml
  1. テキスト エディタで custom/types/available_options.yaml を開きます。

型は、情報の Key-Value ペアとして設定されます。Key は型の名前、Value はその Key の同義語です。Key を定義すると、それ自体が自動的に値として追加されます。Actions SDK では、Key を entities、Value を synonyms と呼びます。

ユーザーの 3 つの選択肢を追加する手順は次のとおりです。

  1. available_options.yaml ファイルに次の entitiessynonyms を追加します。

available_options.yaml

synonym:
  entities:
    dragon:
      synonyms:
      - dragon
      - hydra
      - lizard
    translator:
      synonyms:
      - translator
      - communicator
      - machine
      - decoder
      - translate
    compass:
      synonyms:
      - compass
      - direction
      - guide
      - navigator
  matchType: EXACT_MATCH
  1. ファイルを保存します。

これで、available_options が dragon、translator、compass であることをアクションが理解し、それぞれに対応するいくつかの類義語を認識できるようになりました。

スロットフィルを設定する

次に、Fortune シーンにスロットフィルを設定する必要があります。スロットフィル ロジックを設定する手順は次のとおりです。

  1. テキスト エディタで custom/scenes/Fortune.yaml を開きます。
  2. 次の slots データを Fortune.yaml ファイルに追加します。

Fortune.yaml

slots:
- commitBehavior:
    writeSessionParam: chosenOptions
  name: chosenOptions
  promptSettings:
    initialPrompt:
      staticPrompt:
        candidates:
        - promptResponse:
            firstSimple:
              variants:
              - speech: What do you choose to help you on your quest, a dragon, a translator, or a compass?
            suggestions:
            - title: Dragon
            - title: Translator
            - title: Compass
  required: true
  type:
    name: available_options
  1. ファイルを保存します。

これで available_options 型をスロットに追加できました。このスロットを使用することで、会話を進める前にユーザーから収集する必要のある情報(ユーザーがどのアイテムを選択したか)をアクションに伝えることができます。スロット内にプロンプトを設定しておき、ユーザーがシーンのスロットフィル ステージに達したときに、そのプロンプトをプロンプト キューに追加することもできます。

スロットの名前を chosenOptions にすると、writeSessionsParam フィールドが同じ名前で更新されます($session.params.chosenOptions)。このパラメータには、クライアント ライブラリを通じて、プロンプトやフルフィルメントからこの名前でアクセスできます。

条件を追加する

ユーザーがアイテムを選択するためのスロットを追加したら、会話を進める前にスロット データを取得できたかどうかを確認するための「条件」を追加します。

このセクションでは、条件 scene.slots.status == "FINAL" を追加して、スロットフィルが完了したかどうかをチェックします。すべてのスロットが埋まると、プロンプト(You picked $session.params.chosenOptions.)がプロンプト キューに追加されます。

scene.slots.status == "FINAL" 条件を設定構成する手順は次のとおりです。

  1. テキスト エディタで custom/scenes/Fortune.yaml を開きます。
  2. Fortune.yaml ファイルの先頭に、conditionalEvents データを追加します。

Fortune.yaml

conditionalEvents:
- condition: scene.slots.status == "FINAL"
  handler:
    staticPrompt:
      candidates:
      - promptResponse:
          firstSimple:
            variants:
            - speech: You picked $session.params.chosenOptions.
  1. ファイルを保存します。

シミュレータでアクションをテストする

ここまでの変更により、スロットフィルにおいてユーザーが選ぶアイテムを定義できました。ユーザーからこの情報を入手した後、選択肢に応じてプロンプトが返されるはずです。

次の手順でアクションをテストしてみましょう。

  1. ターミナルで次のコマンドを実行します。
gactions deploy preview

次のような出力が表示されます。

✔ Done. You can now test your changes in Simulator with this URL: http://console.actions.google.com/project/{project-id}/simulator?disableAutoPreview
  1. 表示された URL をコピーしてブラウザに貼り付けます。
  2. Talk to my test app をクリックまたは入力欄に入力し、Enter キーを押します。
  3. 入力欄に「Yes」と入力し、Enter キーを押します。代わりに、候補ワードの [Yes] をクリックすることもできます。

a899d45c542668f6.png

  1. dragon」をクリック、入力、または音声入力します。「You picked dragon」(ドラゴンを選択しました)というメッセージが返されます。

次のセクションでは、ユーザーが選択できるアイテムごとのプロンプトをカスタマイズします。

条件を使用してプロンプトをカスタマイズする

このセクションでは、ユーザーに示す選択肢ごとに条件を追加し、それぞれの条件に応じたカスタム プロンプトを追加します。

dragon の運勢をカスタマイズする

条件を追加し、ユーザーが「dragon」を選択した場合のプロンプトをカスタマイズする手順は次のとおりです。

  1. テキスト エディタで custom/scenes/Fortune.yaml を開きます。
  2. Fortune.yaml ファイルの conditionalEvents データを次のスニペットで置き換えます。

Fortune.yaml

conditionalEvents:
- condition: scene.slots.status == "FINAL" && session.params.chosenOptions == "dragon"
  handler:
    staticPrompt:
      candidates:
      - promptResponse:
          firstSimple:
            variants:
            - speech: The people of Gryffinberg will be awestruck by the beauty and
                power of the ancient dragon. Much to your dismay, the townspeople
                fall into dispute over who will receive the honor of riding the dragon
                first. You return home from your quest without everlasting glory or
                a dragon.
  1. ファイルを保存します。

これで、ユーザーが「dragon」またはその類義語を言ったときに、その選択に応じた運勢を返せるようになりました。次に、残りの選択肢 2 つの運勢を追加します。

translatorcompass の運勢をカスタマイズする

ユーザーが「translator」または「compass」を選択したときのために、条件を追加してプロンプトをカスタマイズする手順は次のとおりです。

  1. custom/scenes/Fortune.yaml ファイルの dragon 条件に、新たに次の 2 つの条件を追加します。

Fortune.yaml

- condition: scene.slots.status == "FINAL" && session.params.chosenOptions == "translator"
  handler:
    staticPrompt:
      candidates:
      - promptResponse:
          firstSimple:
            variants:
            - speech: With the help of the translator, the rival factions in Gryffinberg
                are finally able to communicate with each other and resolve their
                disputes. You will complete your quest to restore peace in the town.
                The translator will be used on many other journeys across the
                earth. After its work is done, it retires honorably to a premier location
                in the Gryffinberg History Museum.
- condition: scene.slots.status == "FINAL" && session.params.chosenOptions == "compass"
  handler:
    staticPrompt:
      candidates:
      - promptResponse:
          firstSimple:
            variants:
            - speech: The compass will help you find the mystical and ancient Library
                of Gryffinberg. Among its infinite stacks of dusty books, you find
                one entitled "Wisdom of the Ages". By the time you've read the 50,000-page
                tome, the townspeople have forgotten their problems. You will write
                a second edition of "Wisdom of the Ages", but have limited commercial
                success.
  1. ファイルを保存します。

シミュレータでアクションをテストする

ここまでの変更により、ユーザーの選択に応じてカスタマイズされた運勢を返せるようになりました。

次の手順でアクションをテストしてみましょう。

  1. ターミナルで次のコマンドを実行します。
gactions deploy preview

次のような出力が表示されます。

✔ Done. You can now test your changes in Simulator with this URL: http://console.actions.google.com/project/{project-id}/simulator?disableAutoPreview
  1. 表示された URL をコピーしてブラウザに貼り付けます。
  2. 入力欄に「Talk to my test app」と入力し、Enter キーを押します。
  3. 入力欄に「Yes」と入力し、Enter キーを押します。代わりに、候補ワードの [Yes] をクリックすることもできます。
  4. Translator」をクリック、入力、または音声入力します。

29e17f950bd0dd71.png

「translator」を選択した場合の運勢が返されます。

このセクションでは、ユーザーが別のアイテムを選び直せるようにアクションを変更し、選び直した後に別の運勢が返されるようにします。この変更は、ゲームの最後に表示される「もう一度プレイしますか?」というメッセージに似ています。このループを作成するには、以前に作成した yes インテントと no インテントを、Again という新しいシーンに追加します。

Again シーンを作成する

このセクションでは、新しい Again シーンを作成し、別のアイテムを選ぶかどうかを確認するメッセージを追加します。

Again シーンを作成して設定する手順は次のとおりです。

  1. Again.yaml という新しいファイルを scenes ディレクトリに作成します。
touch custom/scenes/Again.yaml
  1. テキスト エディタで custom/scenes/Again.yaml を開きます。
  2. 次の onEnter データを Again.yaml に追加します。

Again.yaml

onEnter:
  staticPrompt:
    candidates:
    - promptResponse:
        firstSimple:
          variants:
          - speech: That is what I see for you. Would you like to choose a different option and explore another future?
        suggestions:
        - title: "Yes"
        - title: "No"
  1. ファイルを保存します。

Fortune シーンから Again シーンへの遷移を追加する

ユーザーに運勢を伝えたら、会話を新しい Again シーンに遷移させる必要があります。

Fortune から Again へのシーンの遷移を追加する手順は次のとおりです。

  1. テキスト エディタで custom/scenes/Fortune.yaml を開きます。
  2. 次のスニペットのように、各条件に transitionToScene: Again を追加します。

Fortune.yaml

conditionalEvents:
- condition: scene.slots.status == "FINAL" && session.params.chosenOptions == "dragon"
  handler:
    staticPrompt:
      candidates:
      - promptResponse:
          firstSimple:
            variants:
            - speech: The people of Gryffinberg will be awestruck by the beauty and
                power of the ancient dragon. Much to your dismay, the townspeople
                fall into dispute over who will receive the honor of riding the dragon
                first. You return home from your quest without everlasting glory or
                a dragon.
  transitionToScene: Again
- condition: scene.slots.status == "FINAL" && session.params.chosenOptions == "translator"
  handler:
    staticPrompt:
      candidates:
      - promptResponse:
          firstSimple:
            variants:
            - speech: With the help of the translator, the rival factions in Gryffinberg
                are finally able to communicate with each other and resolve their
                disputes. You will complete your quest to restore peace in the town.
                The translator will be used on many other journeys across the
                earth. After its work is done, it retires honorably to a premier location
                in the Gryffinberg History Museum.
  transitionToScene: Again
- condition: scene.slots.status == "FINAL" && session.params.chosenOptions == "compass"
  handler:
    staticPrompt:
      candidates:
      - promptResponse:
          firstSimple:
            variants:
            - speech: The compass will help you find the mystical and ancient Library
                of Gryffinberg. Among its infinite stacks of dusty books, you find
                one entitled "Wisdom of the Ages". By the time you've read the 50,000-page
                tome, the townspeople have forgotten their problems. You will write
                a second edition of "Wisdom of the Ages", but have limited commercial
                success.
  transitionToScene: Again
  1. ファイルを保存します。

シミュレータでアクションをテストする

ここまでの変更により、ユーザーに運勢を伝えた後に「That is what I see for you. Would you like to choose a different option and explore another future?」(これが私に見えるあなたの運勢です。違うアイテムを選んで、別の運勢を占ってみますか?)というプロンプトを返せるようになりました。

次の手順でアクションをテストしてみましょう。

  1. ターミナルで次のコマンドを実行します。
gactions deploy preview

次のような出力が表示されます。

✔ Done. You can now test your changes in Simulator with this URL: http://console.actions.google.com/project/{project-id}/simulator?disableAutoPreview
  1. 表示された URL をコピーしてブラウザに貼り付けます。
  2. 入力欄に「Talk to my test app」と入力し、Enter キーを押します。
  3. 入力欄に「Yes」と入力し、Enter キーを押します。代わりに、候補ワードの [Yes] をクリックすることもできます。
  4. dragon」をクリック、入力、または音声入力します。

b299e9fed9aedb69.png

dragon を選んだ場合の運勢と Again プロンプトが返されます。

インテントと Again シーンへの遷移を追加する

このセクションでは、yes インテントと no インテントを Again シーンに追加します。これにより、ユーザーがアイテムを選び直したいかどうかを確認できます。また、yes インテントと no インテントに適切な遷移を追加します。yes インテントは Fortune シーンに、no インテントはシステム シーン End conversation に遷移するようにします。

インテントと Again シーンへの遷移を追加する手順は次のとおりです。

  1. テキスト エディタで custom/scenes/Again.yaml を開きます。
  2. Again.yaml ファイルの先頭にある OnEnter の上に intentEvents データを追加します。

Again.yaml

intentEvents:
- intent: "yes"
  transitionToScene: Fortune
- handler:
    staticPrompt:
      candidates:
      - promptResponse:
          firstSimple:
            variants:
            - speech: It pleases me that you are satisfied with your choice. Best
                of luck on your quest. Farewell.
  intent: "no"
  transitionToScene: actions.scene.END_CONVERSATION
  1. ファイルを保存します。

シミュレータでアクションをテストする

ここまでの変更により、ユーザーがアイテムを選び直したいかどうか、会話を終了したいかどうかを確認できるようになりました。

次の手順で yes インテントをテストしてみましょう。

  1. ターミナルで次のコマンドを実行します。
gactions deploy preview

次のような出力が表示されます。

✔ Done. You can now test your changes in Simulator with this URL: http://console.actions.google.com/project/{project-id}/simulator?disableAutoPreview
  1. 表示された URL をコピーしてブラウザに貼り付けます。
  2. 入力欄に「Talk to my test app」と入力し、Enter キーを押します。
  3. 入力欄に「Yes」と入力し、Enter キーを押します。代わりに、候補ワードの [Yes] をクリックすることもできます。
  4. 選択肢をクリック、入力、または音声入力します。
  5. 入力欄に「Yes」と入力し、Enter キーを押します。

5d0690332efe2e29.png

「What do you choose to help you on your quest, a dragon, a translator, or a compass?」というプロンプトが返されます。

次の手順で no インテントをテストしてみましょう。

  1. 選択肢をクリック、入力、または音声入力します。
  2. 入力欄に「No」と入力し、Enter キーを押します。

End conversation プロンプト(「It pleases me that you are satisfied with your choice. Best of luck on your quest. Farewell」(お気に召されたようで何よりです。旅の幸運を祈ります。それでは)が返されます。

ここまでの変更により、このアクションでほとんどのユーザーが選択するメインパスを作成できました。しかし、Fortune シーンのプロンプト「What do you choose to help you on your quest, a dragon, a translator, or a compass?」に対して、選択肢にないものを答えるユーザーがいるかもしれません。

このセクションではアクションにさらに変更を加え、ユーザーが「magic」(魔法)、「money」(お金)、「horse」(馬)、「phone」(スマートフォン)などと答えたことを認識し、既定の 3 つの選択肢から選ぶようユーザーに促せるようにします。このロジックを設定するには、選択できないアイテムを含む新しい type と、ユーザーがそれらのアイテムを選んだ場合に一致する新しいインテント other_option を作成する必要があります。また、「インテント パラメータ」を識別して抽出するには、other_option インテント内のトレーニング フレーズに「アノテーション」を付ける必要があります。

アシスタントの NLU エンジンは、ユーザー入力内に一致するパラメータを検出すると、その値を型付きパラメータとして抽出します。取得した値は、シーン内でロジックの実行に使用できます。この Codelab では、ユーザーが選択したアイテムを抽出し、その選択をプロンプト内で参照できるようにします。

unavailable_options 型を作成する

これで、さまざまなアイテムを含む unavailable_options 型を作成し、ユーザー入力内のデータを識別するための準備が整いました。

unavailable_options 型を作成する手順は次のとおりです。

  1. unavailable_options.yaml という新しいファイルを types ディレクトリに作成します。
touch custom/types/unavailable_options.yaml
  1. テキスト エディタで custom/types/unavailable_options.yaml を開きます。
  2. 次の synonyms データを unavailable_options.yaml ファイルに追加します。

unavailable_options.yaml

synonym:
  entities:
    money:
      synonyms:
      - money
      - cash
      - gold
    horse:
      synonyms:
      - horse
      - stallion
      - steed
    magic:
      synonyms:
      - magic
      - enchanted
      - spells
    phone:
      synonyms:
      - phone
      - cell
      - apps
  matchType: EXACT_MATCH
  1. ファイルを保存します。

other_option インテントを作成する

次に、other_option というインテントを作成し、unavailable_options 型のアイテムを含むトレーニング フレーズを追加します。ユーザーが unavailable_options 型に含まれるアイテムを選ぶと、このインテントに一致します。

other_option インテントを作成して設定する手順は次のとおりです。

  1. other_option.yaml という新しいファイルを intents ディレクトリに作成します。
touch custom/intents/other_option.yaml
  1. テキスト エディタで custom/intents/other_option.yaml を開きます。
  2. 次の parameters データと trainingPhrases データを other_option.yaml ファイルに追加します。

other_option.yaml

parameters:
- name: chosenUnavailableOption
  type:
    name: unavailable_options
trainingPhrases:
- I want to use ($chosenUnavailableOption 'spells' auto=true)
- I really really want to use a ($chosenUnavailableOption 'phone' auto=true)
- ($chosenUnavailableOption 'magic' auto=true)!
- ($chosenUnavailableOption 'cash' auto=true)
- I want to ride a ($chosenUnavailableOption 'horse' auto=true)

ここでは、前のセクションで指定した選択できないアイテムのトレーニング フレーズに、手動でアノテーションを付けます。インテント パラメータ chosenUnavailableOption を使用すると、アイテムの名前を抽出してプロンプトで使用できます。プロンプトの実行は次のセクションで行います。

  1. ファイルを保存します。

other_option インテントを Fortune シーンに追加する

これで、ユーザーが選択肢にないアイテムを選んだ場合に対応できるインテント other_option を作成できました。このセクションでは、この other_option インテントを Fortune シーンに追加します。ユーザー入力に基づいてプロンプトをカスタマイズするには、インテント パラメータを使用します。

other_option インテントを Fortune シーンに追加する手順は次のとおりです。

  1. テキスト エディタで custom/scenes/Fortune.yaml を開きます。
  2. conditionalEvents データと slots データの間に、次の intentEvents データを追加します。

Fortune.yaml

intentEvents:
- handler:
    staticPrompt:
      candidates:
      - promptResponse:
          firstSimple:
            variants:
            - speech:  I have seen the future and a $intent.params.chosenUnavailableOption.original will not aid you on your journey.
  intent: other_option
  1. ファイルを保存します。

$intent.params.chosenUnavailableOption はインテント パラメータ オブジェクト、$intent.params.chosenUnavailableOption.original はそのオブジェクトの値です。original プロパティは、ユーザーが指定した未加工の入力です。

Fortune シーンでユーザーが unavailable_options 型のアイテムを選択すると、other_option インテントに一致してプロンプトがプロンプト キューに追加されます。遷移が指定されていないため、条件ステージを再評価することによってシーンの実行ループを続行しています。その後、chosenOptions スロットによってプロンプトがプロンプト キューに追加され、プロンプト キューがユーザーに配信されます。

シミュレータでアクションをテストする

ここまでの変更により、ユーザーが unavailable_options 型のアイテムを選択するとアクションが適切に応答し、ユーザーがどのアイテムを選択したかを識別できるようになりました。また、ユーザーに元々の選択肢(dragon、translator、compass)のいずれかを選択するようユーザーに促すことができるようになりました。

シミュレータでプロジェクトをテストする手順は次のとおりです。

  1. ターミナルで次のコマンドを実行します。
gactions deploy preview

次のような出力が表示されます。

✔ Done. You can now test your changes in Simulator with this URL: http://console.actions.google.com/project/{project-id}/simulator?disableAutoPreview
  1. 表示された URL をコピーしてブラウザに貼り付けます。
  2. 入力欄に「Talk to my test app」と入力し、Enter キーを押します。
  3. 入力欄に「Yes」と入力し、Enter キーを押します。代わりに、候補ワードの [Yes] をクリックすることもできます。
  4. 入力欄に「magic」と入力し、Enter キーを押します。

3a42c33eca435f32.png

ユーザーが選択した「magic」の前に冠詞「a」が付いているのは、文法的に正しくないようです。以降のセクションでは、この問題に対処する方法を説明します。

unavailable_options ハンドラを追加する

unavailable_options 型から選択したアイテムの前に必要な場合だけ冠詞「a」を挿入するには、フルフィルメント ロジック内のイベント ハンドラを使用して、ユーザーが選択したオプションの前に「a」が必要かどうかを確認します。まず、アクションに変更を加え、このハンドラが Fortune シーンから呼び出されるようにする必要があります。

unavailable_options ハンドラを Fortune シーンに追加する手順は次のとおりです。

  1. テキスト エディタで custom/scenes/Fortune.yaml を開きます。
  2. 次の intentEvents データで Fortune.yaml ファイルを更新します。

Fortune.yaml

intentEvents:
- handler:
    webhookHandler: unavailable_options
  intent: other_option
  1. ファイルを保存します。

フルフィルメントを更新してデプロイする

これで、unavailable_options イベント ハンドラが呼び出されるように設定できたので、フルフィルメント内のハンドラを更新してデプロイします。

フルフィルメントを更新する手順は次のとおりです。

  1. テキスト エディタで webhooks/ActionsOnGoogleFulfillment/index.js を開きます。
  2. 次のコードを greeting ハンドラの index.js に追加します。

index.js

app.handle('unavailable_options', conv => {
  const option = conv.intent.params.chosenUnavailableOption.original;
  const optionKey = conv.intent.params.chosenUnavailableOption.resolved;
  let message = 'I have seen the future and ';
  if(optionsNeedA.has(optionKey)){
    message = message + 'a ';
  }
  message = message + `${option} will not aid you on your journey. `;
  conv.add(message);
});
  1. const app = conversation({debug:true}); の下に次のコードを追加します。

index.js

const optionsNeedA = new Set();
optionsNeedA.add('horse').add('phone');
  1. ファイルを保存します。

コードを理解する

unavailable_options ハンドラは以下の処理を行います。

  • conv オブジェクトから option データを取得し、optionoriginal プロパティに割り当てる(ユーザーからの未加工の入力)
  • optionKeyresolved プロパティに割り当てる(unavailable_options 型のキー)
  • optionKey が「a」を必要とするアイテムかどうかをチェックし、該当する場合はメッセージの先頭に「a」を追加する
  • conv.add(message) でメッセージを追加する

ハンドラを更新する

アクションで unavailable_options を使用できるようにするには、unavailable_options ハンドラを webhooks/ActionsOnGoogleFulfillment.yaml に追加します。

  1. unavailable_options ハンドラの名前を ActionsOnGoogleFulfillment.yaml に追加します。

ActionsOnGoogleFulfillment.yaml

handlers:
- name: greeting
- name: unavailable_options
inlineCloudFunction:
  executeFunction: ActionsOnGoogleFulfillment
  1. ファイルを保存します。

シミュレータでアクションをテストする

ここまでの変更により、ユーザーが unavailable_options 型から選択したアイテムに冠詞「a」が必要かどうかに応じて、プロンプトを調整できるようになりました。

次の手順でアクションをテストしてみましょう。

  1. ターミナルで次のコマンドを実行します。
gactions deploy preview

次のような出力が表示されます。

✔ Done. You can now test your changes in Simulator with this URL: http://console.actions.google.com/project/{project-id}/simulator?disableAutoPreview
  1. 表示された URL をコピーしてブラウザに貼り付けます。
  2. Talk to my test app をクリックまたは入力欄に入力し、Enter キーを押します。
  3. 入力欄に「Yes」と入力し、Enter キーを押します。代わりに、候補ワードの [Yes] をクリックすることもできます。
  4. 入力欄に「magic」と入力し、Enter キーを押します。次に、入力欄に「horse」と入力し、Enter キーを押します。

54ee24c5c3c56e.png

「horse」を選択した場合はその前に冠詞「a」が追加され、「magic」を選択した場合は冠詞「a」なしでプロンプトが生成されます。

Actions SDK は、Actions Console に統合されている Actions Builder というウェブベース IDE との相互運用が可能です。gactions push コマンドを使用してローカル ファイル システムをアクションのドラフトにプッシュすると、アクションの設定を Actions Console で視覚的に表現できます。この視覚表現は開発に役立てるためのもので、テストに使用するバージョンのアクションには影響しません。

Actions プロジェクトをプッシュして Actions Console で表示する手順は次のとおりです。

  1. ターミナルで、次のコマンドを実行してプロジェクトを Actions Console にプッシュします。
gactions push

次のような出力が表示されます。

✔ Done. Files were pushed to Actions Console, and you can now view your project with this URL: https://console.actions.google.com/project/{project-id}/overview. If you want to test your changes, run "gactions deploy preview", or navigate to the Test section in the Console.
  1. 表示された URL をコピーしてブラウザに貼り付けます。
  2. Actions Console で、上部ナビゲーション バーの [Develop](開発)をクリックします。
  3. [Scenes](シーン)の横にあるプルダウン矢印をクリックして [Start](開始)をクリックします。次のスクリーンショットのように、アクションの Start シーンが視覚的に表現されます。

cae526c647f8d40f.png

これで完了です

この Codelab では、Actions SDK を使用して Google アシスタントのアクションを構築するために必要な、中級レベルのスキルについて学びました。

学習した内容

  • Node.js フルフィルメント ライブラリを使用して会話型アクションを開発する
  • スロットを使用してユーザーからデータを収集する
  • 条件を使用してシーンにロジックを追加する
  • ゲームループを追加する
  • 補助的なパスを追加する

その他の学習リソース

Google アシスタントのアクションの構築については、以下のリソースをご覧ください。

Twitter で @ActionsOnGoogle をフォローして最新情報をチェックしてください。また、作成したアクションについて、ハッシュタグ #AoGDevs でツイートしてください。

プロジェクトをクリーンアップする(推奨)

料金が発生するのを避けるため、使用していないプロジェクトは削除することをおすすめします。この Codelab で作成したプロジェクトを削除する手順は次のとおりです。

  1. Cloud プロジェクトとリソースを削除する手順については、プロジェクトのシャットダウン(削除)をご覧ください。
  1. 省略可: プロジェクトを Actions Console からすぐに削除したい場合は、プロジェクトの削除の手順を完了してください。この手順で削除していないプロジェクトは、約 30 日後に自動的に削除されます。

アンケート

最後に、簡単なアンケートにご協力ください。