ごった煮

色々な事を書いてます

状態を持ったBotを作る

少し頭のいいBotを作ってみましょう

状態を持ったBot

Botが受けたり応答したりしたメッセージの数をカウントするみたいな仕組みを作ってみます。

前回の記事 のEchoDialogクラスを改造します。

    [Serializable]
    public class StateEchoDialog : IDialog<object>
    {
        private int count = 1;

        public async Task StartAsync(IDialogContext context)
        {
            context.Wait(MessageReceivedAsync);
        }

        public async Task MessageReceivedAsync(IDialogContext context, IAwaitable<Message> argument)
        {
            var message = await argument;
            if(message.Text == "reset")
            {
                PromptDialog.Confirm(context, AfterResetAsync, "カウントをリセットしてもいいですか ?", "消せませんでした");
            }
            else
            {
                await context.PostAsync($"あなたは{this.count++}回 {message.Text}と言いました");
                context.Wait(MessageReceivedAsync);
            }
        }

        public async Task AfterResetAsync(IDialogContext context, IAwaitable<bool> argument)
        {
            var confirm = await argument;
            if (confirm)
            {
                this.count = 1;
                await context.PostAsync("リセットしました");
            }
            else
            {
                await context.PostAsync("リセットしませんでした");
            }
            context.Wait(MessageReceivedAsync);
        }
    }

 

カウント自体は、グローバル変数にカウントを持てばいいので難しくありません。

今回は、カウントのリセットが重要なポイントです。

今回の使用は、resetコマンドを送信するとBotがリセットするかどうかの待機状態になり、yesを送るとカウントがリセットするという動きにします。

入力を待機する

今回一番大事な部分です。以下みたいな感じ

PromptDialog.Confirm(context, AfterResetAsync, "カウントをリセットしてもいいですか ?", "消せませんでした");

PromptDialogクラスのConfirmが呼び出されると、次のBotへの入力が第二引数に渡したメソッドに渡されます。

このConfirmは、yesかnoを受け取るダイアログになるのでyesかnoを

送ってやると第二引数のメソッドが呼び出されます。

ちなみにConrifmは、y, yes, okを内部的にtrueとして受け取り、n, noをfalseとして受け取ります。また、

その他の文字列は、返答以外の文字列という結果を返します。

動かしてみると以下みたいな感じです

image

 

image

 

image

 

まとめ

PromptDialogクラスのConfirmが何の文字列を受け取るのかの仕様とかがソース読んでね状態とか結構ドキュメントが不親切でこちらに完全に丸投げされてるので結構辛い感じがしてます。

 

あと、別のコントローラを作ってこれ用のエンドポイントを生やしたらなぜかエンドポイント自体にはたどり着いているのに今回よりも先に作ってある前回のMessegeReceivedAsyncに処理が飛ばされたのが挙動として最高に意味が分からないので誰か教えてください