発想と実装の間をつなぐ AI:人工知能特化型メディア

SlackBotを作るならコレ一択!Watsonとの連携で注目が高まるBotkitをつかってみた

こんにちは! 岡田です。

いままでMicrosoft Bot Frameworkのご紹介をしてきましたが、今回からは何回かにわたり、Slack向けBotのフレームワークについてご紹介していきたいと思います。

Slack向けBotといえば、いま注目なのはやはりIBM Watsonとの連携の話題!

IBMはGitHub上で、「Botkit」向けのWatson Conversationプラグインを公開もしています。なんと、こちらはすでに使える状態。

ということでIBMも注目している「Botkit」。

今回は、そんなBotkitで出来ることの基本と簡単なBotの作り方をご紹介します。もちろん今回も、サンプルソースコードを用意しています。

さらに今回は、1クリックで環境構築までできてしまう「魔法のボタン」も作りましたのでご活用ください!

 

IBM Watsonも連携を発表した「Botkit」とは?

Botkitは、XOXCO社が開発したオープンソースのBotフレームワークです。

Facebook, Twilloなどの様々なプラットフォームで使えるようですが、なかでもSlackに特化しています。

GitHubでのスター数は、約4,700と、Microsoft Bot Frameworkをしのぐ数。(2016年11月現在)

そして、api.aiやFirebaseなどの有名な外部サービスと連携するプラグインが既に多数存在しているのも特徴です。

Botkitの基本

それではさっそくご紹介していきます。サンプルソースは、おなじみGitHubにあげてあります。

では、ソースを順にみていきましょう!

まずは、9-27行目

//=========================================================
// Botの準備
//=========================================================

if (!process.env.token) {
    console.log('Error: Specify token in environment');
    process.exit(1);
}

var Botkit = require('botkit');
var os = require('os');

var controller = Botkit.slackbot({
    debug: true,
});

var bot = controller.spawn({
    token: process.env.token
}).startRTM();

こちらの部分でBotの準備をしています。

ただ、こちらはBotをつくる時は毎回同じ記述部分。つまり、“おまじない”のようなものです。

完全に理解しなくても大丈夫ですので、ご安心を!

次は、31-52行目。こちらが、基本的な受け答えの部分です。

//=========================================================
// 基本的な受け答え
//=========================================================

// 以下がBotkitの基本形です。
// controller.hears()で、マッチした単語に応じて処理を実行します。

// 第一引数 ['ほげ','ふが'] の部分には、マッチさせたい単語を入れます。正規表現も使えます。
// 第二引数 'direct_message,direct_mention' の部分には、反応するパターンを入れます。

//  [反応パターン一覧]
//    direct_message: ダイレクトメッセージに反応します
//    direct_mention: 先頭に@付きで発言されたメッセージに反応します
//    mention: @付きで言及されたメッセージに反応します
//    ambient: どんなメッセージタイプにも反応します

controller.hears(['挨拶', 'こんにちは', 'Bot', 'あなた', '誰', 'だれ', '自己紹介'], 'direct_message,direct_mention,mention', function (bot, message) {

    // bot.reply()で、botに発言をさせます。
    bot.reply(message, 'こんにちは!私は *Botkit製のBot* です! \n _いろんな事ができますよ!_ :smiley:');

});

controller.hears() で単語を指定して、ユーザーの発言にその単語が含まれていたら bot.reply() でBotに発言させる。

基本はこの形です。けっこうシンプルですね! 実行するとこんなカンジです。

01


文字装飾にも対応

Slackをよく使う方は、もうお気づきかもしれませんが、Botkitでは、*太字* _斜字_ :emoji: などの文字装飾も使用可能です。

また、改行は \n で行う事ができます。


反応パターンも細かく調整可能

controller.hears() の第二引数で、反応パターンを細かく指定できます。指定できるのは、以下の4種類。

direct_message

ダイレクトメッセージ内で反応します。
02

direct_mention

先頭に@付きで発言されたメッセージに反応します
03

mention

@付きで言及されたメッセージに反応します
04

ambient

どんなメッセージタイプにも反応します
05

基本は、 ‘direct_message,direct_mention,mention’ の3つの指定をおすすめします。

これらの組み合わせで、かなり表現豊かなBotがつくれそう気がしますね!

質問形式の会話

もちろん、下記のような質問形式の会話を作成する事もできます。

06

ソースでは、56-101行目の部分です。

//=========================================================
// 質問形式の会話
//=========================================================

controller.hears(['ラーメン'], 'direct_message,direct_mention,mention', function (bot, message) {

    bot.reply(message, ':ramen:いいですよね:grin:');

    // 会話を開始します。
    bot.startConversation(message, function (err, convo) {

        // convo.ask() で質問をします。
        convo.ask('私が何味が好きか当ててみてください!', [
            {
                pattern: '醤油', // マッチさせる単語
                callback: function (response, convo) {

                    // ▼ マッチした時の処理 ▼

                    convo.say('正解!:ok_woman:\n醤油!これぞ王道!:+1:'); // convo.say()で発言をします。
                    convo.next(); // convo.next()で、会話を次に進めます。通常は、会話が終了します。
                }
            },
            {
                pattern: '味噌',
                callback: function (response, convo) {
                    convo.say('正解!:ok_woman:\n寒いと味噌たべたくなります!:+1:');
                    convo.next();
                }
            },
            {
                default: true,
                callback: function (response, convo) {

                    // ▼ どのパターンにもマッチしない時の処理 ▼

                    convo.say('うーん、おしいです!:no_good:');
                    convo.repeat(); // convo.repeat()で、質問を繰り返します。
                    convo.next(); // 会話を次に進めます。この場合、最初の質問にも戻ります。
                }
            }
        ]);

    })

});

質問形式の会話の場合には、さきほどの bot.reply() ではなく、bot.startConversation() を使用します。

さらに、bot.startConversation() の中で convo.ask(’質問文’, [{ … },{ … }]) を実行して質問を開始します。

第二引数の [{ … },{ … }] のなかに、質問の返答を記述していきます。返答の記述方法は、下記の形です。

            {
                pattern: '醤油', // マッチさせる単語
                callback: function (response, convo) {

                    // ▼ マッチした時の処理 ▼

                    convo.say('正解!:ok_woman:\n醤油!これぞ王道!:+1:'); // convo.say()で発言をします。
                    convo.next(); // convo.next()で、会話を次に進めます。通常は、会話が終了します。
                }
            },

用意したパターンにマッチしなかった場合の処理は、下記のように記述します。

            {
                default: true,
                callback: function (response, convo) {

                    // ▼ どのパターンにもマッチしない時の処理 ▼

                    convo.say('うーん、おしいです!:no_good:');
                    convo.repeat(); // convo.repeat()で、質問を繰り返します。
                    convo.next(); // 会話を次に進めます。この場合、最初の質問にも戻ります。
              }

少し複雑ですが、サンプルのテンプレをコピペして使えば基本は大丈夫です!

より高度な事もできますが、ここでは割愛します。詳細は、 公式GitHubのControl Conversation Flowの章をご覧ください。

絵文字リアクション

Slackには「絵文字リアクション」という機能があります。具体的には誰かのメッセージに絵文字でリアクションをつけれる、というもの。

07

絵文字はボタンになって、他の人が押す事もできます。ちょっとしたアンケートや投票をする、といった使い方をしている人もいるようです。

文章だけだとついつい固くなりがちですが、絵文字リアクションを使うと、ちょっと場が和みますね!

Slack特化のBotkitでは、もちろんこの絵文字リアクションも可能です。実際にBotに絵文字リアクションをしてもらった様子は、以下の通り。

08

サンプルソースでは、105-124行目の部分です。

//=========================================================
// 絵文字リアクション
//=========================================================

controller.hears(['ハイタッチ'], 'direct_message,direct_mention,mention,ambient', function (bot, message) {

    bot.reply(message, 'ハイタッチ!');

    // 絵文字リアクションを追加
    bot.api.reactions.add({
        timestamp: message.ts,
        channel: message.channel,
        name: 'raising_hand', // ここで絵文字名を指定します (例 : smilely, muscle など)
    }, function (err, res) {
        if (err) {
            bot.botkit.log('Failed to add emoji reaction :(', err); // エラーが出たとき用の出力
        }
    });

});


bot.api.reactions.add({ … })
で、受け取ったユーザー発言に対し、絵文字リアクションをしています。

ソースはすこし記述が多いですが、重要なのは以下の部分。

  name: 'raising_hand', // ここで絵文字名を指定します (例 : smilely, muscle など)

’raising_hand’ の部分を変更すれば、好きな絵文字でリアクションができます。Slackで使用可能な絵文字の一覧は、EMOJI CHEAT SHEETというサイトで確認できます。

工夫しだいで面白い会話が実装できそうですね!

データを記録する

一時的にデータを記録しておく事もできます。今回のサンプルでは、Botに名前を覚えてもらう機能を実装しました。

以下が実際にBotに名前を覚えてもらった様子。

09

このデータ保存を行っているのは、152-195行目の部分です。

controller.hears(['(.*)って呼んで'], 'direct_message,direct_mention,mention', function (bot, message) {

    // 「◯◯って呼んで」の、◯◯の部分を取り出します。
    // message.match[1] には、hearsの正規表現にマッチした単語が入っています。

    var name_from_msg = message.match[1];

    // まず、controller.storage.users.getで、ユーザーデータを取得します。

    // message.userには、ユーザーIDが入っています。
    // ユーザーデータは、ユーザーIDと紐付けていますので、第一引数には、必ずmessage.userを入れます。

    controller.storage.users.get(message.user, function (err, user_info) {

        // ▼ データ取得後の処理 ▼

        // ユーザーデータが存在しているかどうか調べる
        // ※第二引数で指定した変数(ここでは'user_info')に、ユーザーデータが入っています。
        if (!user_info) {

            // ▼ ユーザーデータがなかった場合の処理 ▼

            // ユーザーidとユーザー名 のオブジェクトを、user_infoとして作成します。
            user_info = {
                id: message.user,
                name: name_from_msg
            };

        }

        // user_infoを保存します。
        controller.storage.users.save(user_info, function (err, id) {

            // ▼ 保存完了後の処理▼

            bot.reply(message, 'あなたのお名前は *' + user_info.name + '* さんですね!覚えました!');

        });

    });

});

まず、controller.storage.users.get() で、ユーザーのデータを取得します。

ユーザーデータが何もなかった場合には、オブジェクトを作成し、controller.storage.users.save() で保存します。

どちらも、第二引数の function(hoge, hoge){ … } の中に、取得後/保存後に行う処理を記述していきます。

また、Botkitはユーザーに対してだけでなく「ユーザー」「チャンネル」「チーム」ごとでデータを保持する事ができます。

保存したデータは、セッションの続く間、保持されます。つまり「Botが起動し続けている間だけ」保持するという事。Botがスリープしたり再起動するとリセットされるので、注意が必要です。

ただし、データベース用のプラグインを使えば、データをずっと保存しておく事も可能です!

詳しくは、公式GItHub Botkit middlewaresページにあるStorage Modulesの章をご覧ください。

Herokuで動かしてみよう!

さて、ここまでご紹介してきたBotkit。「興味が出てきたので、動かしてみたいなぁ」という方もいるのでは…?

というわけで今回は、クリックするだけでHeroku上でBotkitをデプロイ(環境構築+動作)できる魔法のボタンをご用意しました!

さっそくデプロイ!と行きたい所ですが、その前に、必要なものを確認・準備しましょう。

必要なもの

  • Slackチーム/アカウント
  • Herokuアカウント
  • SlackのBot作成用Token
※Slack・Herokuのアカウント作成については今回は割愛します。

Bot作成用Tokenを用意しよう

SlackチームにBotを追加するには、「Bot作成用Token」を用意しなければいけません。と言っても、こちらも簡単に作成できるのでご安心を。

SlackのBot追加ページを開きます。

10

Bot名を入力し、「Add bot integration」をクリックすると、Tokenが作成できます。

11

デプロイの際に必要になりますので、コピーして保管しておきましょう。

魔法のボタンでデプロイ!

さぁ、準備が整いました。こちらをクリックすると、デプロイが始まります。

Deploy

すると、下記のような画面が表示されます。

12

アプリケーション名と、さきほど作成したTokenを入力したら「Deploy」をクリックします!

しばらくすると、「Your app was successfully deployed.」というメッセージが表示され、デプロイが完了します。

ただ、ここから変更が必要な設定が、1つだけあります。「Manage App」をクリックして管理画面に進みましょう。

13

管理画面に進んだら、「Configure Dynos」をクリックします。

14

すると次のような画面に進みます。

現在は、「webがON」「workerがOFF」になっているかと思います。右部分にある鉛筆アイコンをクリックして、設定を編集します。

15

下記画像のように、「webがOFF」「workerがON」になるよう、設定してください。

16

これで、デプロイ+設定は完了です!おつかれさまでした!

Slack上で、Botが動いているか確認しましょう!

17

まとめ

今回は、Botkitでできる基本的なことをご紹介しました。

Slackに特化したフレームワークならではの表現豊かなBotが作れそうですね!

今回は割愛しましたが、ほかにもファイルがアップロードされたときに〇〇な処理をする、などの高度な事もできるようです。

気になる方は、公式GitHubをご覧になってください!

それではー!

Botkitを「これから試してみよう」「もっと知りたい」「すでに使ってるよ!」という方向けに、Facebookで Botkit 日本開発者向けの公開グループも作成してみましたので、是非ご参加してみてください!

自分もよくSlackを使うので、Botkitで何か作ってみようと思います。皆さんも何か作った時は、グループでシェアしてみてくださいね!

岡田 孟典 by
AIのリアルを追う、“やってみた”ライター兼エンジニア。過去には、海外向けにチャットボットをリリースした実績もある。エンジニアとしての成長も目指して日々奮闘中。