Microsoft Bot Framework v3.0 からはじめるBOT開発: コミュニケーションの基本クラス - Dialog(1)

前回の記事では Microsoft Bot Framework (v3.0) のテンプレートを使って、チャットできるBOT (Webサービス) を簡単に作成しました。
>[Microsoft Bot Framework v3.0 からはじめるBOT開発: 最初の一歩編](http://qiita.com/annie/items/edc26c0ee9603e84a2e4)

以下、コミュニケーションのプロセスを扱う Dialog についてもう少し詳しく説明していきます。

# Dialog を使った 基本的な BOT 動作の開発
BOT としての基本操作、メッセージを受信したら内容を取得して返答を返すプロセスを作成していきます。
##Visual Studio テンプレートから新規 BOT アプリケーションの作成～下準備
[Bot Framework を使うための開発環境](http://qiita.com/annie/items/edc26c0ee9603e84a2e4#bot-framework-%E3%82%92%E4%BD%BF%E3%81%86%E3%81%9F%E3%82%81%E3%81%AE%E9%96%8B%E7%99%BA%E7%92%B0%E5%A2%83) を参考に開発環境を作成し、[Visual Studio テンプレートから Bot アプリケーションの作成](http://qiita.com/annie/items/edc26c0ee9603e84a2e4#visual-studio-%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%83%88%E3%81%8B%E3%82%89-bot-%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AE%E4%BD%9C%E6%88%90) と同じプロセスで新規アプリケーションを作成します。今回は EchoBot という名称で作成しています。
![Visual Studio テンプレートから Bot アプリケーションの作成](https://msdnshared.blob.core.windows.net/media/2016/08/bluesky_20160802_011-e1470057193310.png)

テンプレートから作成される *MessageController.cs* (Controllerフォルダ下にあります) を編集します。
![MessageController の編集](https://msdnshared.blob.core.windows.net/media/2016/08/bluesky_20160802_021-e1470057207907.png)

まずは、Bot.Builder.Dialogs への参照を追加します。

```csharp:MessageController.cs
using Microsoft.Bot.Builder.Dialogs;
```
テンプレートでは Post クラスで受信メッセージを元に返答を返すコードが作成されていますが、一旦この部分を削除 or コメントアウトします。

```csharp:MessageController.cs
public class MessagesController : ApiController
    {
        : 
/// <summary>
     /// POST: api/Messages
     /// Receive a message from a user and reply to it
     /// </summary>
     //public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
     //    {
     //    if (activity.Type == ActivityTypes.Message)
               :
     //    }
     //    var response = Request.CreateResponse(HttpStatusCode.OK);
     //    return response;
     //}
```

##Dialog を使った単純なメッセージの受信、返信
ユーザーからのメッセージを受信したどうかは Microsoft.Bot.Connector.Activity.GetActivityType で診断します。
ActivityType.Message なら返答を作成して送信する Post クラスを MessagesController クラス内に下記のように作成します。Microsoft.Bot.Builder.Dialogs.Conversations.SendAsync で受信したメッセージに返答できます。返答を作成するクラスは EchoDialog です(→次の項目で作成します)。
ActivityType.Message 以外の Activity の場合は、テンプレートの HandleSystemMessage をそのまま利用します。
いずれの場合も、HttpStatusCode.Accepted (=202) を返します。

```csharp:MessageController.cs
public class MessagesController : ApiController
    {
        :
        [ResponseType(typeof(void))]
        public virtual async Task<HttpResponseMessage> Post ([FromBody] Activity activity)
        {
            if (activity != null)
            {
                if (activity.GetActivityType()==ActivityTypes.Message)
                {
                    await Conversation.SendAsync(activity, () => new EchoDialog());
                }
                else
                {
                    HandleSystemMessage(activity);
                }
            }
            return new HttpResponseMessage(System.Net.HttpStatusCode.Accepted);
        }
```

>テンプレートでは activity.Type == ActivityTypes.Message で直接 Activity を判定していますが、上記では先に activity != null で Activity の有無を判定するコードになっています。

次に Post クラスの下に返答を作成する EcoDialog クラスを作成します。ユーザーのメッセージは Microsoft.Bot.Connector.IMessageActivity で取得でき、下記のコードではそれを単純に返す返答を生成します。

```csharp:MessageController.cs
public class MessagesController : ApiController
    {
        :
        [Serializable]
        public class EchoDialog : IDialog<object>
        {
            public async Task StartAsync(IDialogContext context)
            {
                context.Wait(MessageReceivedAsync);
            }
            public async Task MessageReceivedAsync(IDialogContext context,
                IAwaitable<IMessageActivity> argument)
            {
                var message = await argument;
                await context.PostAsync($"「{message.Text}」って言ったよね。");
                context.Wait(MessageReceivedAsync);
            }
        }
```
>この単純な返答作成ではあまり問題ありませんが、会話数をカウントする場合など Serializable を忘れずに。

##Emulator から動作確認
ここまでの内容で動作を確認します。[Botアプリケーションのローカル実行とエミュレーターによるアクセス](http://qiita.com/annie/items/edc26c0ee9603e84a2e4#bot%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AE%E3%83%AD%E3%83%BC%E3%82%AB%E3%83%AB%E5%AE%9F%E8%A1%8C%E3%81%A8%E3%82%A8%E3%83%9F%E3%83%A5%E3%83%AC%E3%83%BC%E3%82%BF%E3%83%BC%E3%81%AB%E3%82%88%E3%82%8B%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9) と同様に Visual Studio から F5 でビルド＆デバック実行を開始し、Bot Framework Channel Emulator からメッセージを送信します。入力したメッセージと同じ文章が返答されれば OK です。
![Bot Framework Channel Emulator からのメッセージ送信と返答](https://msdnshared.blob.core.windows.net/media/2016/08/bluesky_20160802_031-e1470057219988.png)