ココからスタートしよう、Botkitの基礎！+応用への手引き

みなさん、こんにちは！ okajaxです！

チャットボット Advent Calendar 2016 の 16日目。
本日は、Botkitの「ココさえ押さえれば！」というBotkitの基礎TIPS集を書こうと思います。

Botkitをはじめる際、「こまったな:thinking:」「アレしたいな:thinking:」と思ったとき
この記事から読んでいただけたらと思います♪

*(※この記事は、[SlackBotを作るならコレ一択！Watsonとの連携で注目が高まるBotkitをつかってみた - BITAデジマラボ](https://bita.jp/dml/slack_botkit) のコンパクト再編集版+αです)*

# 基本的なサンプルコード

サンプルコード+Heroku用のテンプレートを、GitHubにあげてあります。
「とりあえず動かしてみたい」という方は、ポチっとデプロイしてみてください♪
↓
[okajax / Botkit-template-for-heroku](https://github.com/okajax/Botkit-template-for-heroku)

# 基本の受け答え .hears()

Botkitの基本会話の形は下記のとおり。

>**◯◯という単語にマッチ → ◻◻という発言(または処理)をさせる**

コードすると下記のとおり。

```js

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

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

});
```

`['挨拶', 'こんにちは', 'Bot', 'あなた', '誰', 'だれ', '自己紹介']`
第一引数の配列には、マッチする単語群を指定します。 
正規表現も使えます。

`'direct_message,direct_mention,mention'`
第二引数には、反応するメッセージタイプを指定します。

第三引数の関数内の `bot.reply()` で発言をさせます。


# テキストの装飾について

`**` `__` `::` といった装飾が、通常のSlackメッセージと同様に使えます。
改行は、`\n`で行えます。


# 反応するメッセージタイプ

Botkitは、細かく反応するメッセージタイプを指定する事もできます。
種類は下記の4つ。

* direct_message (ダイレクトメッセージ)
* direct_mention (直接メンション)
* mention (メンション)
* ambient (どんなタイプでも反応)

ちょっとイメージわきづらいと思いますので、画像付きで解説しますね。

![1.jpg](https://qiita-image-store.s3.amazonaws.com/0/124249/a3985ed9-1212-772b-3a34-b8e9293c8985.jpeg)

![2.jpg](https://qiita-image-store.s3.amazonaws.com/0/124249/a0f77b8b-fd20-125e-20a6-fe41cc39cfb7.jpeg)
![3.jpg](https://qiita-image-store.s3.amazonaws.com/0/124249/d3b585b6-6383-454c-d803-f1f277abc259.jpeg)
![4.jpg](https://qiita-image-store.s3.amazonaws.com/0/124249/6993df97-4980-2dcf-51c3-fad18de9186e.jpeg)

このように、かなり細かく指定ができます！
基本は、 `direct_message,direct_mention,mention` の3つの指定で良いと思います。


# メッセージから単語を取り出すには message.match

`message.match`で、正規表現にマッチした単語を取り出せます。

たとえば、

```js
controller.hears(['(.*)って呼んで'], ... ){ ... }
```

に「okajaxって呼んで」と入れると、`message.match` には
`['okajaxって呼んで', 'okajax']` が入っています。

ですので、 `message.match[1]` で正規表現にマッチした
「okajax」を取り出せます。

[サンプルコードはこちら](https://github.com/okajax/Botkit-template-for-heroku/blob/master/bot.js#L152-L195)


# 質問形式の会話

連続した会話を開始するには
`bot.startConversation(message, function (err, convo) {...})`
を使います。

こちらの第二引数の関数のなかで`convo.ask(...)`を呼び出す事で
質問形式の会話が実装できます。

こちらに関しては実際のコードを見て、
形を覚えてしまうのがオススメです。

```js
// 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(); // 会話を次に進めます。この場合、最初の質問にも戻ります。
        }
    }
]);
```

[サンプルコードはこちら](https://github.com/okajax/Botkit-template-for-heroku/blob/master/bot.js#L56-L101)


# データの保存

一時的にデータを保存する事もできます。
ただし、セッションの続く限りの期間限定です。
(自分のほうでは、Botがスリープや再起動するとリセット、と解釈しています)


**保存、取得、削除、すべて削除** の4つの操作ができます。

```例.js
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) {...});
```
**「ユーザー」「チャンネル」「チーム」ごと**にデータを保持する事ができます。
それぞれ、下記のように呼び出せます。

```例.js
controller.storage.users.***
controller.storage.channels.***
controller.storage.teams.***
```

実際にユーザーデータを取得/保存しているコードが下記になります。

```js
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 + '* さんですね！覚えました！');

    });

});
```

[サンプルコードはこちら](https://github.com/okajax/Botkit-template-for-heroku/blob/master/bot.js#L163-L193)

`controller.storage.users.get()`の第一引数は、
ユーザーIDにしないとエラーが出るため注意です！


※後述しますが、永続的にデータを保存したい方向けには、FirabaseやMongo向けのミドルウェアも用意されています。


# どれにも当てはまらなかった場合の返答

Botkitには、どれにも当てはまらないときのデフォルト対応
(MicrosoftBotFrameworkでいう所の`onDefault`にあたるもの)
が、自分が探した限りだと見当たりませんでした。

調べたところ `hears()`には優先順位があり、
一番最後に `controller.hears(['(.*)'], ... ){ ... })` を用意すれば
デフォルト対応が実装ができました。

[サンプルコードはこちら](https://github.com/okajax/Botkit-template-for-heroku/blob/master/bot.js#L199-L227)

# 応用への手引き

## ミドルウェア

通常ですと、データの保存は、セッションの続く限りの期間限定ですが
**FirebaseやMongoDBと接続できる**ミドルウェアも存在しています。

また、**API.ai, LUIS, WatsonConversation** といった自然言語処理系サービスと
連携できるミドルウェアも存在しています。

公式GitHubにまとめページがあるので、興味がある方はぜひ！
↓
[botkit / readme-middlewares.md (ミドルウェアまとめページ)](https://github.com/howdyai/botkit/blob/master/readme-middlewares.md)


## 応用的な使い方のご紹介

個人的に気になっている、Botkitの応用的な活用法のリンク集です。

- [slack新機能！message buttonを使ってbotkitをレベルアップさせる！](http://qiita.com/LOUIS_rui/items/3692ddeab6c7773abd11)

- [Slackにアップしたファイルを自動でS3にアップするBOTを作ってみた -ファイルはS3にどんどんしまっちゃおうねぇ～-](http://qiita.com/Mic-U/items/c0234b7801bf1204bfff)

- [BotkitでSlackのSlash Commandを作る](http://qiita.com/hiconyan/items/b506b0631265268a850b)

- [Slackでメンバーが参加しているチャンネルをBotkit(Slack API)で調べる](http://qiita.com/Will_meaning/items/c2227c0e432e9e19daca)

- [botkit使って定期的につぶやくslackbot作る](http://blog.duck8823.com/entry/2016/05/20/005734)

- [会話エンジンにWatson Conversationを使ったSlack botを作ってみた](http://qiita.com/LOUIS_rui/items/3692ddeab6c7773abd11)


# さいごに

Botkitは、Slackに特化しているだけあって、色々な事ができそうですね！

Botkitでの開発に興味ある方は、[公開Facebookグループ](https://www.facebook.com/groups/283027658760138/)もありますのでよかったらぜひどうぞ！

### ここまでのAdventCalender感想

すべて目を通しています！楽しい記事ありがとうございます！＞＜
LINE、Slack、シェルスクリプト製Bot、Pepperなど... とても多様で面白いですね！:raised_hands:

このAdvent Calenderは「Bot作りたいけど、どういう手段・開発手法があるんだろ？:thinking:」と知りたい方へのインデックスとして役立つかもですね♪

記事をみていて、
なかでも気になったのは**「ChatOps」**というワードでした！ (ごめんなさい、初耳でした＞＜)
Botは「AIと組み合わせて〜」って方向だけでなく、仕事面でも戦略的に使っていけるぞー！という概念なのですね！

[GitHubとの連携に特化した「githubot」という物の紹介もあったり](http://qiita.com/kashira2339/items/26f97809673acf99e2b4)で、とても学びが多いです:laughing:

Slackは、ChatOpsにドンピシャリですね！
同じ方向では、MicrosoftTeamsの今後も動向も、個人的に気になる所です♪

---

AdventCalendar後半も
実践的内容や、機械学習やAIを扱った記事があり、楽しみですね！:kissing_closed_eyes:

それではまたー！