BEACHSIDE BLOG

MicrosoftとかC#を好むレンジャーの個人的メモ

グローバルメッセージハンドラー (1/2) - Bot Frameworkの基本機能 (global message handlers using Scorables)

Bot Framework で開発するときに使うであろう基本機能、Scoralbles をC#で実装関連のメモです。
通称(?)global message handler でドキュメントやGitHubに載っていて、Scorables を使って実装するやーつです。

Overview

Environment

0. Scorables とは

具体的な用途の例

こんな時に使うと便利だと(個人的に)思っています。

  • 会話の途中で「ヘルプ」と言ったらヘルプのダイアログが発動
  • 何かを注文している会話の途中で「リセット」といったら最初からやり直す
  • ユーザーがチャットボットと会話している途中で、チャットボットから人(コールセンターのオペレーターとか)とのチャットに切り替える
  • FAQボットを作った際、QnA Maker と LUIS を併用していい感じの答えの方を使う

Scorables の動作の概要

(チャットボットに話しかけている)ユーザーからメッセージを受け取ると、通常のチャットボットの処理を行う前に、スコアを算出します(というよりは、スコアを算出するプログラムを自分で書きます)。
スコアの算出する処理後、スコアは

  • 「スコアをもっているか?」
  • 「スコアが何点か?」

という2つの概念があり、全ての Scoralbles がスコアを持っていなければ、通常のチャットボットの処理を行います。
スコアを持ってる Scoralbles が存在すれば、トップスコアの Scoralbles の処理を実行します。

会話の途中であれば、DialogStack に完全に割り込んで処理を実行します。Scoralbles で割り込んだ処理が終わった後に、元のDialogStackに戻ります。

わかりにくいですね。。。実装して動かして試してみましょう。

1. デモ用ボットの作成

事前準備

まだ Bot Framework の Project Template や Emulator の用意ができてない場合は、以下の手順で準備ができます(UIがやや異なりますが手順は一緒です)

beachside.hatenablog.com

プロジェクトの作成

Visual Studio 2017で新規にプロジェクトを作っていきます。

f:id:beachside:20170720190619p:plain


新しいプロジェクトの画面の右上、テンプレートの検索で「bot」と入力して検索し、「Bot Application」 を選択、名前を適当に入れて OK をクリックで作成されます。.NET Frameworkのバージョンは4.6を選んでいます。

f:id:beachside:20170720190632p:plain

ここで「Bot Application」 と表示がなければ、テンプレートの準備をしていないか配置してるフォルダがおかしいとかです。上記の準備の手順を見ながら確認してみましょう。


NuGet パッケージの更新

NuGet のパッケージで更新できるものはしておきましょうかね。
(最新にするとかはケースバイケースなので、ご注意を...)

コマンドでやります。「パッケージマネージャー コンソール」を開きましょう。
(VSの上部のメニュー ツール > NuGet パッケージ マネージャー > パッケージ マネージャー コンソール で表示されます。)

「既定のプロジェクト」が先ほど作成したプロジェクトになっていることを確認し、

Update-Package

とコマンドを入力します(コマンドの解説はここではしません..)。依存関係に応じた最新のパッケージに更新してくれます♪今回だと、BotBuilder は 3.8.5 になりました。

f:id:beachside:20170720190725p:plain


フライト予約のDialog作成

会話の途中でDialogStackに割り込んで、Scorablesの処理を発動し、終わったら元の会話に戻るって確認がしたかったので、よくあるあるなダイアログのクラスを作ります。

ソリューションエクスプローラーで Dialog のフォルダーを右クリック > 追加 > クラス を選択します。

f:id:beachside:20170720190755p:plain


クラス が選択されていることを確認して、名前に「FlightsDialog」と入力して追加します。

f:id:beachside:20170720190806p:plain


実装はこんな感じです♪

ざっくりな解説ですが、

  • Dialogのエントリーポイントとなる StartAsync メソッド(12行目)でユーザーからのメッセージを待っています。
  • ユーザーからメッセージが来たら、context.Wait メソッド(14行目)の引数にセットしている AskOrigin メソッドが動作します。
  • AskOrigin メソッド(21行目)では、出発地を聞いて、ユーザーからの返答を待ちます。
  • 後は同様に、AskDestination メソッドで行き先を聞き、BookFlight メソッドで確認しておしまいという流れです。

ユーザーが入力した出発地は、変数 _from に格納しておきました。Dialogでは、会話が終了 ≒ context.Done が呼ばれるまでは、変数の値が保持されます。(他にも会話の終了方法はありますがここではざっくりと)

実装部分の動作チェック

FlightsDialog が呼ばれるように、MessagesController クラスの Post メソッドを書き換えます。以下のコード12行目にあるように FlightsDialog を呼ぶようにしました。

デバッグしてみましょう。エミュレーターで接続先を入力し動作確認してみましょう。

f:id:beachside:20170720190839p:plain

下準備が完了しました。まだ長くなりそうなので、次回に本題の部分の実装をします!