FledglingRobin’s diary

Github: https://github.com/FledglingRobin

Botkitでできること

Botkitでslcak botをつくることになった。かんたんにbotが作れると評判のslack bot、標準でどんなことができるのかREADMEをしらべてみる。

github.com

f:id:FledglingRobin:20170102220928p:plain:w300

ユーザーからのメッセージに反応する

message_receivedイベントの購読で、なにかしらの書き込みに反応できる。ほかにdirect_mentiondirect_messageイベントでそれぞれの書き込みに反応できる。メッセージを返すのはbot.reply関数を使ってできる。

controller.on('message_received', function(bot, message) {
    bot.reply(message, 'I heard... something!');
});

hears関数で特定のワードに反応できる。ワードはリストで指定できる。

controller.hears(['keyword1', 'keyword2'], ['message_received'], function(bot, message) {
   bot.reply(message, 'You used a keyword!');
});

hears関数ではパターンマッチングがつかえる。マッチした結果はmessage.matchフィールドに格納される。このフィールドにはJavaScriptstring.matchと同じ形式で情報が格納されている。

controller.hears('open the (.*) doors', ['message_received'], function(bot, message) {
   var doorType = message.match[1];
   if (doorType === 'pod bay') {
      return bot.reply(message, 'I\'m sorry, Dave. I\'m afraid I can\'t do that.');
   }
      return bot.reply(message, 'Okay');
});

botからメッセージを送る

ユーザからのメッセージにひとつずつreplayするだけでなく、bot.say関数でbotからメッセージを発信することもできる。

controller.hears(['hello world'], 'message_received', function(bot, message) {
   bot.startConversation(message, function(err, convo) {
      convo.say('Hello!');
      convo.say('Have a nice day!');
   });
});

ユーザーにといかけて返答を待つこともできる。ask関数を利用する。ユーザから返答がきたあとの処理をcallbackに記述しておけばいい。

controller.hears(['question me'], 'message_received', function(bot, message) {
   bot.startConversation(message, function(err, convo) {
      convo.ask('How are you?', function(response, convo) {
         convo.say('Cool, you said: ' + response.text);
         convo.next();
    });
  })
});

会話が複雑になってくるとcallbackの管理がつらくなってくる。そんなときのためにThered機能がある。

bot.createConversation(message, function(err, convo) {

    // create a path for when a user says YES
    convo.addMessage({
            text: 'You said yes! How wonderful.',
    },'yes_thread');

    // create a path for when a user says NO
    convo.addMessage({
        text: 'You said no, that is too bad.',
    },'no_thread');

    // create a path where neither option was matched
    // this message has an action field, which directs botkit to go back to the `default` thread after sending this message.
    convo.addMessage({
        text: 'Sorry I did not understand.',
        action: 'default',
    },'bad_response');

    // Create a yes/no question in the default thread...
    convo.ask('Do you like cheese?', [
        {
            pattern: 'yes',
            callback: function(response, convo) {
                convo.changeTopic('yes_thread');
            },
        },
        {
            pattern: 'no',
            callback: function(response, convo) {
                convo.changeTopic('no_thread');
            },
        },
        {
            default: true,
            callback: function(response, convo) {
                convo.changeTopic('bad_response');
            },
        }
    ]);

    convo.activate();
});

いくつかの質問を続けるような場合は、ほかの関数を呼び出すような形で書くこともできる。

controller.hears(['pizzatime'], 'message_received', function(bot,message) {
     var askFlavor = function(err, convo) {
        convo.ask('What flavor of pizza do you want?', function(response, convo) {
           convo.say('Awesome.');
           askSize(response, convo);
           convo.next();
        });
     };
     var askSize = function(response, convo) {
        convo.ask('What size do you want?', function(response, convo) {
           convo.say('Ok.')
           askWhereDeliver(response, convo);
           convo.next();
        });
     };
     var askWhereDeliver = function(response, convo) {
        convo.ask('So where do you want it delivered?', function(response, convo) {
          convo.say('Ok! Good bye.');
          convo.next();
        });
     };

     bot.startConversation(message, askFlavor);
});

ユーザの「はい」「いいえ」を藩閥するのに便利な関数も提供されている。bot.utterances.yesyes, yeah, yup, ok and sureにヒットする。 bot.utterances.nono, nah, nopeにヒットする。 日本語には対応していないみたいなので拡張をしながら使う。

情報の保存

デフォルトだとBotkitはJSON filesに書き込みをする形で情報を保存する。保存先を指定することができる。

var controller = Botkit.slackbot({
   json_file_store: 'path_to_json_database'
});

保存する際にキーを設定する。キーにはユーザーやチャンネル、チームを利用するといい。

controller.storage.users.save({id: message.user, foo:'bar'}, function(err) { ... });
controller.storage.users.get(id, function(err, user_data) {...});
controller.storage.users.delete(id, function(err) {...});
controller.storage.users.all(function(err, all_user_data) {...});

JSON files以外にもDBなどを利用することもできる。

var controller = Botkit.slackbot({
  storage: my_storage_provider
})