LoginSignup
2

More than 5 years have passed since last update.

Azure BotService を触った所感

Last updated at Posted at 2017-01-22

まえがき

2016年3月30日?に BotFramework が発表されてもう半年が過ぎた。
Azure に BotService なるサービス(現時点ではプレビュー)が生まれているのでファーストインプレッションを書いておく。

所感

  • Bot開発で WebApp, APIApp, FunctionApp と、どのサービス使うべきか考えなくてよくなった。
  • リリース直後の BotFramework 周りはボットの登録は別でやって・・・準備が面倒だったのがポータル内に集約されてラクになった
  • コードがその場でいじれるので大したことのないBotならそのまま触れてよい
  • とはいえプレビューなのでエディタの補完が効かない点や最後のハマりどころなど、不満はある

準備

Azureポータル から Bot Service を作成する。

bot-service-1.png

次に MS の App ID を取得する。
ID とパスワードが発行されるので、画面内に貼り付けるだけ。

bot-service-1-2.png

最後に言語と Bot パターンを選択する。
Bot 開発にありがちなピザの注文は Form。
今回も Form で作成する。

bot-service-1-3.png

ということで BotService が作成された。

Bot開発

BotService を開くと、いかにもコードがいじれそうな画面が開く。

bot-service-2.png

Form の場合は BasicForm.csx 9割、MainDialog.csx を1割見れば大体どうにかなる。

今回は勤怠連絡のためのBotを書いてみた。

BasicForm.csx
public enum KintaiOptions
{
    一日休み = 1,
    遅刻,
}

public enum ReasonOptions
{
    交通状況 = 1,
    体調不良,
    その他の問題,
}

[Serializable]
public class BasicForm
{
    public BasicForm()
    {
        /*
        Kintai = KintaiOptions.遅刻;
        Reason = ReasonOptions.交通状況;
        Comment = "特になし";
        */
    }

    [Prompt("今日はいかがしましたか?{||}")]
    public KintaiOptions Kintai;

    [Prompt("どうしちゃったの?{||}")]
    public ReasonOptions Reason;

    [Prompt("誰かに何か伝えておくことあるかな?")]
    public String Comment;

    public static IForm<BasicForm> BuildForm()
    {
        OnCompletionAsyncDelegate<BasicForm> processConfirm = async (context, state) =>
        {
            var message = context.MakeMessage();
            switch (state.Reason) {
                case ReasonOptions.交通状況:
                    message.Text = "落ち着いて来てくださいね!";
                    await context.PostAsync(message);
                    break;
                case ReasonOptions.体調不良:
                    message.Text = "いのちをだいじに!お大事にしてください〜";
                    await context.PostAsync(message);
                    break;
            }
        };
        return new FormBuilder<BasicForm>()
            .Message("こんにちは。勤怠Botです。")
            .Field(nameof(Kintai))
            .Field(nameof(Reason))
            .Field(nameof(Comment))
            .AddRemainingFields()
            .Confirm(async (state) => {
                return new PromptAttribute($"「{state.Reason}」が原因で「{state.Kintai}」です。連絡事項は「{state.Comment}」。この内容で伝えていいですか?(y or n)");
            })
            .OnCompletion(processConfirm)
            .Build();
    }

    public static IFormDialog<BasicForm> BuildFormDialog(FormOptions options = FormOptions.PromptInStart)
    {
        // Generated a new FormDialog<T> based on IForm<BasicForm>
        return FormDialog.FromForm(BuildForm, options);
    }
}
MainDialog.csx
    private async Task FormComplete(IDialogContext context, IAwaitable<BasicForm> result)
    {
        try
        {
            var form = await result;
            if (form == null)
            {
                await context.PostAsync("空の申請がリクエストされました。はじめからやり直してください。");
            }
        }
        catch (OperationCanceledException)
        {
            await context.PostAsync("申請がキャンセルされました。はじめからやり直してください。");
        }

        context.Wait(MessageReceivedAsync);
    }

Form の選択肢の変数を初期化しないと警告が表示されるが、初期化するとユーザの入力を待たずに選択されている扱いになってしまうという罠がある。
はじめは未選択、という状態になっているためで、これが列挙型の開始値を1にしなければならない理由だと思われる。

設定まわり

どのチャットサービスと連携するかは Channels で設定する。
残念ながら LINE はない。

bot-service-6.png

あとは FunctionApp そのものをいじる場合は Settings からいじる。

bot-service-3.png

bot-service-4.png

bot-service-5.png

開発が進めばあとは公開するだけ。

ハマりどころ

しばらく開いているとコードエディタで Save しても裏側の FunctionApp が再読込しなくなる。
ブラウザを更新すればこの状態は復活する。
おかしいときは FunctionApp を再起動すれば直る。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2