Bot FrameworkでラクラクBot開発!

UI開発者 加藤

ここ数年でSlackをはじめとしたチャットツールが一気に流行りました。その背景には、メールや電話よりも気軽に素早くコミュニケーションがとれることに加えて、ユーザーが機能を追加したり他のツールと連携させたりなど、好きなようにカスタマイズできることが理由の一つではないかと思います。

そのカスタマイズ機能の1つにBotがあります。AIの流行と共にBot自体も取り上げられ、目にすることが多くなったように感じます。今回の記事では、Microsoft Bot Frameworkを使ったBotの開発方法をご紹介します。

Microsoft Bot Framework

Microsoft Bot Frameworkはその名の通りMicrosoft社が提供しているBotを開発するためのフレームワークで、このフレームワークを使用して作られたBotはMicrosoft社のサービスであるSkypeやTeamsはもちろん、SlackやFacebook Messengerなどに導入することも可能です。

SDKはオープンソースでGitHubに公開されており、C#もしくはNode.jsで開発することが可能です。

今回はあまり新規性がありませんが、このフレームワークとNode.jsを用いて天気を取得するBotを開発してみたいと思います。

お天気を取得するAPIはOpenWeatherMapを利用します。

'use strict';

var http = require('http');
var restify = require('restify'); // ローカル開発用のフレームワーク
var builder = require('botbuilder'); // Bot Builder SDK
var server = restify.createServer();

server.listen(3978, function () {
    console.log('%s listening to %s', server.name, server.url);
});

var connector = new builder.ChatConnector();
var bot = new builder.UniversalBot(connector);
server.post('/api/messages', connector.listen());

var API_KEY = 'APIキー';
var URL = 'http://api.openweathermap.org/data/2.5/weather?q=Tokyo,JP&units=metric&appid=' + API_KEY;

// 天気を取得します。
function getWeather () {
    return new Promise((resolve, reject) => {
        http.get(URL, (res) => {
            let rawData = '';
            res.on('data', chunk => {
                rawData += chunk;
            });
            res.on('end', () => {
                resolve(JSON.parse(rawData));
            });
        }).on('error', err => {
            reject(err.message);
        });
    });
}

// ユーザーからの全てのメッセージに反応する、ルートダイアログです。
bot.dialog('/', [
    session => {
        // 下部にあるaskダイアログに会話の制御を渡します。
        session.beginDialog('/ask');
    },
    // askダイアログが閉じられると、制御がルートダイアログに戻り下記が実行されます。
    (session, results) => {
        var response = results.response.entity;
        getWeather().then(
            data => {
                if (response === '気温') {
                    session.send('気温は%s°です!', Math.round(data.main.temp));
                } else if (response === '気圧') {
                    session.send('気圧は%shpaです!', data.main.pressure);
                } else if (response === '湿度') {
                    session.send('湿度は%s%です!', data.main.humidity);
                }
            },
            err => {
                session.send('天気を取得できませんでした!!');
            }
        );
    }
]);

// askダイアログ
bot.dialog('/ask', [
    session => {
        builder.Prompts.choice(session, "こんにちは!何が知りたいですか?", "気温|気圧|湿度");
    },
    (session, results) => {
        // askダイアログを閉じ、ルートダイアログにユーザーからの返答データを渡します。
        session.endDialogWithResult(results);
    }
]);

このコードをBot Framework Emulatorで実行してみると、下記のようになります。

Bot Framework Emulatorで実行している様子

Botが完成したら、Microsoft Azureや、Herokuなどを利用して、Botをクラウドに展開し、Bot Framework PortalからMy botsとして登録し、好きなチャネルに追加することができます。

開発する上で考えるべきこと

Botを開発する上で考えるべきこととして、最初に挙げられるのが、Botとユーザー間の「会話の管理」です。Botに対してどういう発言をすれば良いのかがユーザーに伝わるように会話の「シナリオ」をしっかり作る必要があります。Bot Frameworkでは、「Dialog」という概念を使用して会話のロジックを整理することができます。Design bot navigationのページに、Botとユーザーの会話が噛み合っていない例がいくつか掲載されていますので、NGパターンとして参考にしていただければと思います。

そしてもう1つよりよいBotを作るのに必要なのが、AIです。LUISという自然言語解析ツールがこれもまたMicrosoftから提供されています。上記でご紹介したコードでは、Botから選択肢を提示され回答を選ぶシナリオですが、LUISを使用することで例えば「今日の東京の天気は?」という文章から「東京」、「天気」といったキーワードを抜き取り返信させることができるようになります。もちろんBot FrameworkとLUISを容易に連携させることも可能です。

何ができるのか

さて、ここまでBotの開発について説明してきましたが、まだ何ができるのか想像がつかない方もいるかもしれません。そんな方はBot directoryから様々な開発者が作成したBotを試すことができますのでご覧になってみるのもいいかもしれません。

個人的には秘書やアシスタントのようなものだというと分かりやすいと思っています。自分に変わってスケジュールを管理してくれたり、現在地周辺のランチ情報を集めてくれたり、申請などの雑務を代わりに行ってくれたりなどなど...社長にならなくても秘書を持てる時代がすぐそこまできているのかもしれませんね。