« ココログの「スマートフォン表示」に無理矢理スタイルを設定してみた | トップページ | de:code 2016雑感 »

2016年5月12日 (木)

Microsoft Bot Frameworkを使ってSlashのbotを作ってみた(前編)

連休中にMicrosoft Bot FrameworkでBotを作って、 家族内の連絡に使っているSlackのチームに突っ込んでみました。 まずは、特に工夫もない単純なBotだけど。 その話などぼちぼち書いてみます。

Microsoft Bot Frameworkとは

Microsoft Bot FrameworkはBuild 2016において"Conversations as a Platform"の一要素として発表されました。 賢いBotが人間の相手をして、仕事を色々とこなしてくれれば、 GUIとかとはまた違った便利なインターフェイスなるだろう、 そういうBotを作ろうぜ、 という話ですね。

Botを作る話はFacebookも最近発表しました。 Facebookの話がFacebook Messengerを対象にしているのに対し、 Microsoft Bot Frameworkは様々なメッセージングサービスを相手にします。 Botサービスを一つ立ち上げておいて、 それを各種サービス(Email, Slack, Skype, Facebook Messenger, etc.)に繋ぎます。 LINEも対応予定だと言っていたなあ。 現状のメニューには出てなかったけど。

以下の図がよく説明で引用される図です。

Bot Frameworkの説明図

Bot Framework Overviewから

Bot Frameworkは大きく以下の三つの要素からなります。

  • Bot Builder SDKs: Botを簡単に開発できるようにするSDK
  • Bot Connector: 作ったBotをメッセージングサービスに繋ぐサービス(SaaS)
  • Bot Directory: (将来予定)Botを流通させるためのサービス

BotとBot Connectorの関係はこんな感じ。 BotはBot Builder SDKで作らなくても、 インターフェイスを満たせばBot Connectorで繋げることができます。

Bot Frameworkの構成図

Bot Framework Overviewから

メッセージングサービスにBotを送り込む枠組みはこれでよいとして、 「賢い」Botを実装するためには、 賢く状況を認識できるようにしなければなりません。 そのための道具立てが"Conversations as a Platform"のもう一つの要素である"Microsoft Cognitive Services"です。 色々な認識を行うためのサービスが揃っています。 その中のEmotion APIは先月簡単に動かして見ました(前編, 後編)。

さて、ということでSlack上で動くBotを作ってみます。 今編では、まずBot Builder SDKを使ってBot本体を作ります。 次編でBot Connectorを使ってそれをSlackに接続します。

どういうBotを作るか

ファーザーBotを作ります。 以下のセリフをランダムに返します。

  • いいです。
  • わしもですか?
  • みんなもですか?
  • わしがですか?

これは、 「神聖モテモテ王国」のファーザーが発行した紙幣(壱萬ラブ)の四コマ中のセリフです。 これをランダムに返してくれると、 いい感じに壊れた雰囲気になるでしょう。

言語の選択とSDKの準備

まず、言語を選択します。 現状用意されているのはC#またはNode.jsです。 ここではC#を使います。 C#を使う場合は、 Visual Studio 2015 Update 2以降が必要です。 Node.jsを使う場合は、Node.jsとエディタだけでできそう。

C#版SDKは実質的にはテンプレートのみです。 テンプレートのzipファイルをユーザーレベルのテンプレートの置き場所に置くだけです。 具体的には説明の通り。

プロジェクトの作成

ここでVisual Studioを起動し直すと、 「新しいプロジェクト」のC#のプロジェクトテンプレートの中に「Bot Application」テンプレートが現れるようになります。

「新しいプロジェクト」ダイアログ

ここからプロジェクトを新規作成すると、 プロジェクト構成はこんな感じになります。 ASP.NETのWeb APIがベースっぽいですが、 かなりシンプルになっています。

プロジェクト構成

ソースコードの修正

ソースコードの中心部は以下です。 テンプレートの初期実装は入力メッセージの文字数を答えるものですね。

namespace FatherBot {
  [BotAuthentication]
  public class MessagesController: ApiController {
    /// <summary>
    /// POST: api/Messages
    /// Receive a message from a user and reply to it
    /// </summary>
    public async Task<Message> Post([FromBody]Message message) {
      if (message.Type == "Message") {
        // calculate something for us to return
        int length = (message.Text ?? string.Empty).Length;

        // return our reply to the user
        return message.CreateReplyMessage($"You sent {length} characters");
      } else {
        return HandleSystemMessage(message);
      }
    }

これを以下のように変更します。 まあ、まずはシンプルな内容で。

namespace FatherBot {
  [BotAuthentication]
  public class MessagesController: ApiController {
    private static readonly string[] replies = {
      "いいです。",
      "わしもですか?",
      "みんなもですか?",
      "わしがですか?"
    };
    private Random random = new Random();

    /// <summary>
    /// POST: api/Messages
    /// Receive a message from a user and reply to it
    /// </summary>
    public async Task<Message> Post([FromBody]Message message) {
      if (message.Type == "Message") {
        string reply = replies[this.random.Next(replies.Length)];

        // return our reply to the user
        return message.CreateReplyMessage(reply);
      } else {
        return HandleSystemMessage(message);
      }
    }

ビルド

このままプロジェクトをビルドします。 実は、このソースだと「Postメソッドについているasyncの意味が無いぞ」という趣旨の警告をC#コンパイラが出します。 通常、Postメソッドの中では色々仕事をするだろうから、きっと非同期メソッドを呼び出すことだろう、 ということでテンプレートは非同期スタイルでPostメソッドを生成してます。 しかし、現状の内容だと同期的な処理しかしていないので無意味なわけですね。

でもまあ、実害はないので無視しましょう。 asyncを取り除くとそれはそれで同期スタイルに直さなければならなくて手間だし。

デバッグ実行

で、これをデバッグ実行すると、 ブラウザ上にスタートページが表示されます。

スタートページ

このページを開いている間、 Botサービスは動いており、 ページを閉じるとBotサービスのデバッグ実行が終了する、 だったと思うんだけど、 ページ閉じてもデバッグセッションが終了しないな。 ASP.NETのデバッグってそういう動きだったっけ?

まあともかく、 Botサービスを起動している間に、 その動作を試します。 それには、 Bot Framework Emulatorを使うと便利です。

Bot Framework Emulatorは 説明ページのリンクからインストールできます。 なんと、最近ほとんど見ないClickOnceアプリケーションですよ。

Bot Framework Emulatorを使うと、 こんな感じでBotの動きをチェックすることができます。 Bot Framework Emulator側で入力を与えつつ、 Visual Studio側でデバッグを行うことができるわけです。

Bot Framework Emulator

Bot Framework Emulatorを正しくBotに接続させるためには、 Emulatorの上部の帯にある"URL", "App Id", "App Secret"を正しく指定しなければなりません。

"URL"はBotを動かしているアドレスです。 先ほど開いたスタートアドレスのページのアドレスバーを見れば見当が付くでしょう。 注意点としては、BotのAPIのパスは(テンプレートそのままだと)サイトのルートではなく、"/api/messages"になるところですかね。

"App Id", "App Secret"によってBotはクライアントからの接続を認可します。 この値はプロジェクト中のWeb.configで設定されています。

現時点では、 テンプレートから生成された仮の値が入っています。 BotをBot Connectorに登録する際には、 ちゃんとした値を入れることになるでしょう。

スタートページ

次回、BotをBot Connectorに登録し、Slackから利用可能にします。

« ココログの「スマートフォン表示」に無理矢理スタイルを設定してみた | トップページ | de:code 2016雑感 »

Windows」カテゴリの記事

その他」カテゴリの記事

コメント

コメントを書く

(ウェブ上には掲載しません)

トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/595179/63615655

この記事へのトラックバック一覧です: Microsoft Bot Frameworkを使ってSlashのbotを作ってみた(前編):

« ココログの「スマートフォン表示」に無理矢理スタイルを設定してみた | トップページ | de:code 2016雑感 »