検索
連載

DialogflowからAzure Functionsを呼び出してみるGoogle Homeプログラミングを始めよう(3/3 ページ)

今回はWebhookを利用して、DialogflowからAzure Functionsを利用してみよう。

Share
Tweet
LINE
Hatena
前のページへ |       

動作確認

 これで準備はできた。ハンバーガーボタンをクリックして、メニューから[Integrations]を選択しよう。

[Integrations]ページ
[Integrations]ページ

 一番上の[Google Assistant]カードをクリックすると、以下のダイアログが表示される。

[Google Assistant]ダイアログ
[Google Assistant]ダイアログ

 一番下にある[TEST]ボタンをクリックすると、シミュレーターが起動されるので、ここで実際に動作を確認してみよう。

シミュレーターの起動画面
シミュレーターの起動画面

 Googleアシスタントアプリに接続すると(ここでは「Insider.NETにつないで」と入力。特に設定をしていなければ「テスト用アプリにつないで」となる)、テストバージョンが起動するので、続けて「ラジオを消して」などと入力してみよう。

「承知しました」と返事が返ってくる
「承知しました」と返事が返ってくる

 「承知しました」という返事にあまり意味はない(エラーとならないようにしているだけ)。重要なのは、Functionsアプリの関数がログに残したデータだ。

DialogflowからFunctionsアプリに渡される値(赤枠内)
DialogflowからFunctionsアプリに渡される値(赤枠内)

 このままの出力は見にくいので、このデータがどんなものかを簡単に見てみよう。

データの確認と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"
}


DialogflowからFunctionsアプリへ送信されたデータ

 ここで重要なのは、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を組み合わせて、簡単なアプリを作成した。次回はより複雑な会話を行えるようにしてみる予定だ。

「Google Homeプログラミングを始めよう」のインデックス

Google Homeプログラミングを始めよう

Copyright© Digital Advantage Corp. All Rights Reserved.

前のページへ |       
ページトップに戻る