こんばんは,うどん大 情報系 院2年の@hico_horiuchiです.
この記事はChatOps Advent Calendar 2015の17日目です.
本当は「Hubot + ImgurでプルリクにLGTMする」だったのですが,@jacopen大先輩に
「セカホリ、botkit試してー」
と言われたので,急遽Botkitで頑張ることにしました.
Botkit?
昨日のSlack Platformの発表の中で,新しいBot Frameworkの 「Botkit」 が紹介されました.
- howdyai/botkit
- The Slack Platform Launch | Several People Are Typing
- Slackがプラットフォーム化を宣言。「Slack App Directory」と対応Bot開発用の「Botkit」発表。アプリ開発支援に約100億円の資金準備も - Publickey
Hubotと同じく,Node.js上で動作するようです.
READMEを読んで感じた特徴は,以下のような感じです.
メッセージの受信方法の多様性
Hubotは robot.hear
と robot.respond
の2種類だけでした.
BotkitではSlackに特化して,5種類準備されているようです.
-
message_received
: 全てのメッセージ(robot.hear
相当) -
ambient
: メンション以外のメッセージ -
direct_mention
:@bot hello
のように名前で始まるメンション -
mention
:hello @bot
のように名前を含むメッセージ -
direct_message
: 1対1のDirect Messages
更に controller.hears('hello', ['direct_message', 'mention',])
のように複数指定できる.
(ただ,Botとのインタフェースを増やし過ぎるのは良くなさそう.)
対話機能
bot.startConversation
を使うと,Yes/Noなどの対話を簡単に実装できるみたい.
Yes/Noの判定は標準で用意されてるけど,自分でも 'done'
などを指定できる.
-
bot.utterances.yes
: yes, yeah, yup, ok, sure -
bot.utterances.no
: no, nah, nope
「プルリクマージする?」「デプロイする?」みたいな場面で使えそうですね.
Imgurから画像を取得してLGTM
ここからが本題です.
突然ですが,みなさんLGTMしてますか?
LGTMとは、Looks good to meの略です。
GitHubのPull Requestなど、コードやデザインのレビューをした際などに「いいね!」の意味合いでつかわれます。
今やってる開発系のバイトではプルリク駆動開発をしていて,LGTMし合っています.
ただ,LGTM用の画像を探してきて,コメントして…って面倒ですよね.
そこで,Botを使ってSlackからLGTMできるようにしてみました.
今回は,お気に入りのLGTM画像をImgurのアルバムにしてみました.
ここからランダムに画像を取得して,LGTMコメントに使います.
(一緒にバイトしてる同級生の影響で,俺妹のGIFが多いですね.)
最初に,SlackとImgurでAPIトークンを取得しておきます.
こちらは,Qiitaに投稿されている記事を参考にします.
次に,適当な作業ディレクトリを作って,必要なライブラリをインストールします.
$ mkdir ~/botkit
$ cd ~/botkit
$ npm install --save botkit request node-github
さて,少し長いですが,Botkitのコードはこのようになります.
Imgur APIの呼出にはrequestを,GitHub APIの呼出にはnode-githubを利用しました.
関数の階層が深くなるのが嫌だったので,以前覚えたコールバック関数を積んでいく形にしました.
var SLACK_TOKEN = 'xoxb-0123456789abcdefghijklmnopqrstuvwxyz';
var IMGUR_ALBUM_ID = 'ABCDE';
var IMGUR_CLIENT_ID = '0123456789abcde';
var GITHUB_ACCESS_TOKEN = '0123456789abcdefghijklmnopqrstuvwxyz0123';
var botkit = require('botkit');
var request = require('request');
var githubAPI = require('node-github');
var controller = botkit.slackbot({
debug: false
});
controller.spawn({
token: SLACK_TOKEN
}).startRTM();
var getAccountImages = function(bot, message, args) {
request.get({
url: 'https://api.imgur.com/3/album/' + IMGUR_ALBUM_ID + '/images',
headers: {
'Authorization': 'Client-ID ' + IMGUR_CLIENT_ID
}
}, function(error, response, body) {
if (error || response.statusCode !== 200) {
return bot.reply(message, 'Faild to request of Imgur API.');
}
var images = JSON.parse(body).data;
if (images.length === 0) {
return bot.reply(message, 'No images are uploaded to Imgur album.');
}
args.image = images[Math.random() * images.length | 0];
args.callbacks.shift()(bot, message, args);
});
};
var issuesCreateComment = function(bot, message, args) {
github = new githubAPI({
version: '3.0.0'
});
github.authenticate({
type: 'oauth',
token: GITHUB_ACCESS_TOKEN
});
github.issues.createComment({
user: args.user,
repo: args.repo,
number: Number(args.id),
body: '![' + args.image.id + '](' + args.image.link + ')'
}, function(error, _) {
if (error) {
bot.reply(message, 'Failed to request of GitHub API.');
}
});
};
controller.hears('^lgtm +(.+)\/(.+) +([0-9]+)$', 'direct_mention', function(bot, message) {
var matches = message.text.match(/^lgtm +(.+)\/(.+) +([0-9]+)$/i);
getAccountImages(bot, message, {
callbacks: [issuesCreateComment],
user: matches[1],
repo: matches[2],
id: matches[3]
});
});
ちなみに,元になったHubotでの実装もあります.
Botkitでは正規表現に ¥s
とか ¥S
が使えないっぽい?
(Hubotでは /lgtm\s+(\S+)\/(\S+)\s+([0-9]+)$/i
にしてました.)
あと,正規表現のマッチ部分を message.match[1]
とかで取れないのも不便です.
実際に使ってみる
では,実際にBotkitを起動してみましょう.
$ node bot.js
** No persistent storage method specified! Data may be lost when process shuts down.
** Setting up custom handlers for processing Slack messages
** API CALL: https://slack.com/api/rtm.start
** BOT ID: bot ...attempting to connect to RTM!
コマンドのフォーマットは @bot: lgtm <user>/<repo> <id>
です.
(イカに深い意味はありません.)
APIトークンをタイポしてたりすると,ちゃんとエラーを返してくれます.
(これは bot.log
にも出した方が良さそう.)
まとめ
今回は,Botkitの紹介と,ImgurとGitHubを組み合わせたサンプルを書いてみました.
Hubotと比較して,Slackに特化して,多機能になっている感じです.
移植も,インタフェース部分を変えるだけなので,比較的に出来そう…?
ただ,やっぱりHubotの方が知見や資産も多くて良いなと思います.
(あと,CoffeeScriptで書けないし…ファイル分割もどうやるんだろう.)
Slack + Botkitでどんなことが出来るようになるのか,今後が楽しみですね!
Hubot×ChatOps勉強会
僕は生粋のうどん県民ですが,実は大阪や神戸で「Hubot×ChatOps勉強会」をやってます.
来年の4月から就職して上京するので,その前にもう1度開催したいと思っています.
そこで,大阪で「会場提供しても良いよ」という方居ましたら,連絡頂けると嬉しいです!
また,Botkitも含め,HubotやChatOpsについて発表して頂ける方も募集中です!