少し高度なSlack botを作ろうとすると、botにデータを持っておいてもらいたい時がある。botの外部にデータベースを持つのもいいけれどそこまでの話でもなかったりする。そんな時、Slack bot用のフレームワーク Botkit を使えばJSON形式で簡単お手軽にデータを扱える。今回はBotkitでデータを保持・取得する方法を紹介したい。
Contents
Botの準備
今回作るBotはユーザーの名前を聞いて、Botを立ち上げ直しても覚えているもの。
「call me A」と言うと、「あ、このユーザーはAっていう名前なんだな」とデータストアに情報を保存する。一旦Botを終了し、再度立ち上げた後「who am I」と聞くと情報を引っ張ってきて「Your name is A」と答えてくれるというもの。
まずはプロジェクトを作りたいディレクトリへ移動し、githubからプロジェクト一式を落としてくる。
1 |
git clone https://github.com/howdyai/botkit.git |
プロジェクトに入り、依存パッケージをインストールする。
1 2 |
cd botkit sudo npm install |
データストアのパスを設定する
まずはBotが使用するデータストアを設定するところから。BotkitはデータをJSONファイルの形で保存するからその置き場所を指定するわけだ。
botkitディレクトリにあるbot.jsを開き、controllerを作っている部分をこのコードに置き換えよう。
1 2 3 |
var controller = Botkit.slackbot({ json_file_store: 'storage_bot_db' }); |
これだけでOK。Botkitの楽さったら無いね。
ユーザーの名前を保存する
なんという名前かをBotに教える部分を作る。bot.jsのhearsメソッドのうち、『call me (.*)』を引き受けているところを見てみよう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
controller.hears(['call me (.*)', 'my name is (.*)'], 'direct_message,direct_mention,mention', function(bot, message) { var name = message.match[1]; controller.storage.users.get(message.user, function(err, user) { if (!user) { user = { id: message.user, }; } user.name = name; controller.storage.users.save(user, function(err, id) { bot.reply(message, 'Got it. I will call you ' + user.name + ' from now on.'); }); }); }); |
ハイライト部分がデータを保存している箇所だ。このような構造になっている。
1 |
controller.storage.users.save({id: message.user, foo: 'bar'}, function(err) { ... }); |
idプロパティを持つオブジェクトと、save完了後のコールバックを指定するシンプルなもの。今回は、事前にidとnameプロパティを持つオブジェクトを作って渡している。
ユーザーの名前を取得する
さて、「who am I」と聞かれて名前を返す部分。名前を設定した時と同じくbot.jsの該当する箇所を見てみよう。
1 2 3 4 5 6 7 |
controller.hears(['what is my name', 'who am i'], 'direct_message,direct_mention,mention', function(bot, message) { controller.storage.users.get(message.user, function(err, user) { if (user && user.name) { bot.reply(message, 'Your name is ' + user.name); } else { ~略~ |
ハイライト箇所でメッセージを送ったユーザーのデータを取得している。このメソッドの構造はこうなる。
1 |
controller.storage.users.get(id, function(err, user_data) {...}); |
データを保存するときに指定したのと同じidを使ってユーザーごとのデータを取得し、コールバックで処理するというこれまたシンプルなもの。実に簡単。
このBotを実際に動かしてみたいときは以前の記事を参考にBotユーザーを作ってbot.jsを動かしてほしい。
全ユーザーのデータを扱う
保存してある全てのユーザーデータにアクセスすることもできる。
1 |
controller.storage.users.all(function(err, all_user_data) {...}); |
コールバックの第二引数に全てのユーザーデータが入っている。今回の例だと、ユーザーのidとnameプロパティを持つオブジェクトが一纏めになっている。
チャンネルごとのデータを扱う
「ユーザー一人々々のデータを扱う方法は分かったけれど、チャンネルごとではどうなの?」もちろん大丈夫!僕らのBotkitはバッチリだ。ユーザーの時と同じようにチャンネルのidを持つオブジェクトを扱うだけ。
1 2 3 |
controller.storage.channels.save({id: message.channel, foo:'bar'}, function(err) { ... }); controller.storage.channels.get(id, function(err, channel_data) {...}); controller.storage.channels.all(function(err, all_channel_data) {...}); |
チームごとのデータを扱う
ユーザーやチャンネルの時と同じようにチームごとでもデータを扱える。構造は全く同じ。
1 2 3 |
controller.storage.teams.save({id: message.team, foo:'bar'}, function(err) { ... }); controller.storage.teams.get(id, function(err, team_data) {...}); controller.storage.teams.all(function(err, all_team_data) {...}); |
このように、ユーザー / チャンネル / チームの単位で簡単にデータを扱える。ちょっとしたデータの管理には十分に備えられていることがわかった。
言語を越えて活用できるプログラマー必携の書