Microsoft Bot Framework v3.0 からはじめるBOT開発: Yes/No ダイアログを表示する - Dialog(2)

Microsoft Bot Framework (V3.0) のテンプレートをそのまま動かしてみる、その次にコミュニケーションのプロセスを扱う Dialog で基本的なメッセージの送受信をコーディングしました。今回はそれを応用して、メッセージ数をカウントするプロセスを作成します。
基本的な Dialog を使ったメッセージ送受信に会話数のカウントを追加します。「X番目にYという質問をする/確認する」というフローを入れたいなど、現在何メッセージ目なのかカウントしたい場合に使えます。またメッセージダイアログ(Yes/No)を表示し、入力された操作の確認を行います。

>[Microsoft Bot Framework v3.0 からはじめるBOT開発: 最初の一歩編](http://qiita.com/annie/items/edc26c0ee9603e84a2e4)
>[Microsoft Bot Framework v3.0 からはじめるBOT開発: コミュニケーションの基本クラス Dialog(1)](http://qiita.com/annie/items/bd4248bb07eafcf83a3a)

#Dialog を使ったメッセージ送受信(下準備)
開発環境の準備は [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/bd4248bb07eafcf83a3a#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%E6%96%B0%E8%A6%8F-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%E4%B8%8B%E6%BA%96%E5%82%99) で Bot Framework テンプレートを使う準備を行い、[Dialog を使った単純なメッセージの受信、返信](http://qiita.com/annie/items/bd4248bb07eafcf83a3a#dialog-%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%9F%E5%8D%98%E7%B4%94%E3%81%AA%E3%83%A1%E3%83%83%E3%82%BB%E3%83%BC%E3%82%B8%E3%81%AE%E5%8F%97%E4%BF%A1%E8%BF%94%E4%BF%A1) の通り、MessageController.cs を編集します。

#メッセージ数をカウントする (その1)
##メッセージ数のカウント
返答を作成する EcoDialog クラスの代わりに、下記のように EchoCountDialog というクラスを追加します。count でメッセージ数をカウントしておき、返答文を作るときにカウントを増やします(this.count++)。"reset" という入力を受信したらカウントをリセットします。返答メッセージの最初にカウント数を文章の頭につけています。

```MessagesController.cs
[Serializable]
public class EchoCountDialog : IDialog<object>
{
    protected int count = 1;
    public async Task StartAsync(IDialogContext context)
    {
        context.Wait(MessageReceivedAsync);
    }
    public async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> argument)
    {
        var message = await argument;
        if (message.Text == "reset")
        {
            await context.PostAsync($"会話数をリセットします");
            this.count = 1;
        }
        else
        {
            await context.PostAsync(string.Format("{0}:{1}って言ったね。", this.count++, message.Text));
        }
        context.Wait(MessageReceivedAsync);
    }
}
```

メッセージの送受信を行う Post でも EchoCountDialog を呼び出すように変更します。

```MessageController.cs
[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());
            await Conversation.SendAsync(activity, () => new EchoCountDialog());
        }
        else
        {
            HandleSystemMessage(activity);
        }
    }
    return new HttpResponseMessage(System.Net.HttpStatusCode.Accepted);
}
```

##Emulatorで動作確認(その1)
[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 からメッセージを送信します。
メッセージ数が返答の頭に表示され、"reset" と送信するとカウントがリセットされるのを確認してください。
![メッセージ数のカウント](https://msdnshared.blob.core.windows.net/media/2016/08/bluesky_20160805_011-e1470292760527.png)


#メッセージ数をカウントする (その2): リセット時に確認メッセージを表示する
その1 では "reset" を受信すると即リセットを行いますが、その2では確認メッセージを表示して可否を確認します。
Microsoft.Bot.Builder.Dialogs.PromptDialog で Yes/No ダイアログを表示し、Yes または No の選択をもとに ResetCountAsync を実行します。

```MessagesController.cs
[Serializable]
public class EchoCountDialog2 : IDialog<object>
{
    protected int count = 1;
    public async Task StartAsync(IDialogContext context)
    {
        context.Wait(MessageReceivedAsync);
    }
    public async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> argument)
    {
        var message = await argument;
        if (message.Text == "reset")
        {
            PromptDialog.Confirm(context, ResetCountAsync, "リセットしますか?");
        }
        else
        {
            await context.PostAsync(string.Format("{0}:{1}って言ったね。", this.count++, message.Text));
            context.Wait(MessageReceivedAsync);
        }
    }
    public async Task ResetCountAsync(IDialogContext context, IAwaitable<bool> argument)
    {
        var confirm = await argument;
        if (confirm)
        {
        this.count = 1;
            await context.PostAsync("会話数をリセットしました。");
        }
        else
        {
            await context.PostAsync("会話数リセットを中止しました。");
        }
            context.Wait(MessageReceivedAsync);
        }
    }
```

Post からの呼び出しも EchoCountDialog2 に変更します。

```MessageController.cs
[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());
            //await Conversation.SendAsync(activity, () => new EchoCountDialog());
            await Conversation.SendAsync(activity, () => new EchoCountDialog2());
        }
        else
        {
            HandleSystemMessage(activity);
        }
    }
    return new HttpResponseMessage(System.Net.HttpStatusCode.Accepted);
}
```

##Emulatorで動作確認(その2)
今回は "Reset" と送信すると、確認ダイアログが表示されます。Emulator の右上にある Locale はデフォルトで OS の言語に設定されている(はず)、Locale:ja-jp では [はい][いいえ] と表示されます。
![メッセージ数のカウント(Yes/No 確認ダイアログ(日本語))](https://msdnshared.blob.core.windows.net/media/2016/08/bluesky_20160805_021-e1470292517131.png)

Locale:en-us など英語に設定すると、確認ダイアログは [Yes][No] になります。
![メッセージ数のカウント(Yes/No 確認ダイアログ(英語))](https://msdnshared.blob.core.windows.net/media/2016/08/bluesky_20160805_031-e1470292549200.png)