これで準備はできた。ハンバーガーボタンをクリックして、メニューから[Integrations]を選択しよう。
一番上の[Google Assistant]カードをクリックすると、以下のダイアログが表示される。
一番下にある[TEST]ボタンをクリックすると、シミュレーターが起動されるので、ここで実際に動作を確認してみよう。
Googleアシスタントアプリに接続すると(ここでは「Insider.NETにつないで」と入力。特に設定をしていなければ「テスト用アプリにつないで」となる)、テストバージョンが起動するので、続けて「ラジオを消して」などと入力してみよう。
「承知しました」という返事にあまり意味はない(エラーとならないようにしているだけ)。重要なのは、Functionsアプリの関数がログに残したデータだ。
このままの出力は見にくいので、このデータがどんなものかを簡単に見てみよう。
Dialogflowから外部サービスに渡されるデータをログに残すようにしたが、実際にFunctionsアプリに渡されたデータを分かりやすく展開したものが以下のコードだ。
{
  "originalRequest":
  {
    // もともとのリクエストに関する情報
  },
  "id":"idの値",
  "timestamp":"タイムスタンプ",
  "lang":"言語(jaなど)",
  "result":
  {
    "source":"agent",
    "resolvedQuery":"ラジオを消して",
    "speech":"",
    "action":"",
    "actionIncomplete":false,
    "parameters":
    {
      "verb":"Off",
      "objective":"ラジオ"
    },
    "contexts":
    [
      // コンテキスト関連のデータ
    ],
    "metadata":
    {
      // メタデータ
    },
    "fulfillment":
    {
      // フルフィルメント関連のデータ
    },
    "score":スコア(1.0など)
  },
  "status":
  {
    // ステータス情報
  },
  "sessionId":"セッションID"
}
ここで重要なのは、result.parametersプロパティだ。ここに自然言語処理の結果、verbとobjectiveの2つのエンティティに割り当てられた値が保存されている。よって、このプロパティの値を使って、Functionsアプリの中で適切な処理を行えるということだ。
これを実際に行うようにしたコードを以下に示す。
#r "Newtonsoft.Json"
using System.Net;
using Newtonsoft.Json;
public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
  log.Info("C# HTTP trigger function processed a request.");
  dynamic data = await req.Content.ReadAsStringAsync();
  var json = JsonConvert.DeserializeObject<ReqBody>(data as string);
  var verb = json.result.parameters["verb"];
  var objective = json.result.parameters["objective"];
  var op = verb == "On" ? "入れました" : "消しました";
  var message = $"{objective}を{op}";
  var response = new Response()
  {
    speech = message,
    displayText = message,
  };
  var result = req.CreateResponse(HttpStatusCode.OK, response);
  result.Headers.Add("ContentType", "application/json");
  return result;
}
public class ReqBody
{
  public Result result { get; set; }
}
public class Result
{
  public string resolvedQuery { get; set; }
  public Dictionary<string, string> parameters { get; set; }
}
public class Response
{
  public string speech { get; set; }
  public string displayText { get; set; }
  public string source { get; set; }
}
ここでは上で見たJSONデータから今回必要とする部分だけをモデル化したクラスを作成して、Newtonsoft.Jsonパッケージが提供するメソッドを使って取り出している。その後、objectiveエンティティとverbエンティティの値に応じて適宜メッセージを作成し、それをDialogflow側に返送するようにしてある。
この状態で、シミュレーターで動作を確認してみると次のようになる。入力に対して、適切な返答が得られているのが分かる。
これはサンプルなので、もちろん実際にテレビを点けることはしない(そうした機能はGoogle Homeとスマートホームデバイスがあれば既に利用可能)。とはいえ、前回見たような単純な受け答えではなく、スマートスピーカーとの対話にロジックを組み込みたいときには、DialogflowとAzure Functionsを使うことでこれを比較的簡単に実現できることが分かったはずだ。
今回はエンティティ、インテント、Webhook、Azure Functionsを組み合わせて、簡単なアプリを作成した。次回はより複雑な会話を行えるようにしてみる予定だ。
Copyright© Digital Advantage Corp. All Rights Reserved.