こんばんは,うどん大 情報系 院2年の@hico_horiuchiです.
この記事はSLP KBIT Advent Calendar 2015の22日目です.
(ChatOps Advent Calendar 2015の15日目が空いてたので,兼用で登録しました.)
先日の「Botkit + ImgurでプルリクにLGTMする」に引き続き,Botkitを使ってみます.
SLPでもGitHubとSlackを使っているので,Botを活用できるシーンを考えてみました.
(SlackはTeamが乱立してるので,統合してChannnelでまとめたい感….)
ちなみに,昨年は「Hubotで始める簡単Bot開発」だったので,2年連続でBotネタですね.
Botkit?
昨日のSlack Platformの発表の中で,新しく紹介されたBot Frameworkです.
- howdyai/botkit
- The Slack Platform Launch | Several People Are Typing
- Slackがプラットフォーム化を宣言。「Slack App Directory」と対応Bot開発用の「Botkit」発表。アプリ開発支援に約100億円の資金準備も - Publickey
第一印象やHubotとの違いなどは「Botkit + ImgurでプルリクにLGTMする」を参照して下さい.
Conversation(対話機能)
Botkitでは,標準で 対話機能 が提供されるようです.
(質問文と,それに続く返答での条件分岐が,対話と定義されてるようです.)
bot.startConversation
を使うと,Yes/Noなどの対話を簡単に実装できるようです.
Yes/Noの判定基準となる単語は,このように定義されていました.
-
bot.utterances.yes
: yes, yeah, yup, ok, sure -
bot.utterances.no
: no, nah, nope
今回は対話機能を使って,Botkitにプルリクエストをマージさせます.
利用シーンとしては,こんな感じでしょうか.
(GitHub上でマージしちゃった方が早い気がしなくもない.)
- Slackに「プルリクが作成されたよ」とGitHubの通知が飛んでくる.
- Slack上でプルリクについて,あーだこーだ議論してみる.
- Botkitに「マージして」と言うと,「本当に良い?」と聞いてくる.
- 「Yes」と答えるとマージ,「No」と答えると何もしない.
ちなみに,誤爆を防ぐために「Botしかマージする権限を持っていない」という会社もあるようです.
マージをトリガにして,CIを使ってデプロイする所まで自動化していると楽しそうですね.
この辺りの話は,Rebuild.fmで有名な@naoya_itoさんが書かれてます.
Conversationでプルリクをマージ
ここからが本題です.
最初に,SlackとGitHubでAPIトークンを取得しておきます.
こちらは,Qiitaに投稿されている記事を参考にします.
次に,適当な作業ディレクトリを作って,必要なライブラリをインストールします.
$ mkdir ~/botkit
$ cd ~/botkit
$ npm install --save botkit node-github
さて,少し長いですが,Botkitのコードはこのようになります.
GitHub APIの呼出にはnode-githubを利用しました.
var SLACK_TOKEN = 'xoxb-0123456789abcdefghijklmnopqrstuvwxyz';
var GITHUB_ACCESS_TOKEN = '0123456789abcdefghijklmnopqrstuvwxyz0123';
var botkit = require('botkit');
var githubAPI = require('node-github');
var controller = botkit.slackbot({
debug: false
});
controller.spawn({
token: SLACK_TOKEN
}).startRTM();
var pullRequestsMerge = function(bot, message, args) {
console.log(args);
github = new githubAPI({
version: '3.0.0'
});
github.authenticate({
type: 'oauth',
token: GITHUB_ACCESS_TOKEN
});
github.pullRequests.merge({
user: args.user,
repo: args.repo,
number: Number(args.id)
}, function(error, _) {
if (error) {
bot.botkit.log('Failed to request of GitHub API:', error);
}
});
};
controller.hears('^merge +(.+)\/(.+) +([0-9]+)$', 'direct_mention', function(bot, message) {
var matches = message.text.match(/^merge +(.+)\/(.+) +([0-9]+)$/i);
bot.startConversation(message, function(err,convo) {
convo.ask('Are you sure you want to merge?', [{
pattern: bot.utterances.yes,
callback: function(response, convo) {
pullRequestsMerge(bot, response, {
user: matches[1],
repo: matches[2],
id: matches[3]
});
convo.next();
}
}, {
pattern: bot.utterances.no,
callback: function(response, convo) {
bot.api.reactions.add({
timestamp: response.ts,
channel: response.channel,
name: '-1',
}, function(error, _) {
if (error) {
bot.botkit.log('Failed to add emoji reaction:', error);
}
});
convo.next();
}
}]);
});
});
実際に使ってみる
では,実際に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: merge <user>/<repo> <id>
です.
(イカに深い意味はありません.)
「no」と返すと されますが,これもBotkitでやってます(後述).
「yes」と返すと,ちゃんとマージされてることが分かりますね.
(GitHubと連携してることが多いと思うので,敢えてBotkitで結果を返してません.)
(おまけ) BotkitからAdd Reactionする
BotkitはSlackに特化してるので,Add ReactionなどのAPIも簡単に利用できます.
以下,howdyai/botkit/bot.jsより抜粋.
bot.api.reactions.add({
timestamp: message.ts,
channel: message.channel,
name: 'robot_face',
},function(err,res) {
if (err) {
bot.botkit.log("Failed to add emoji reaction :(",err);
}
});
このメソッドは,SlackのAPIをそのまま叩いてる感じですね.
タイムスタンプとChannelで,Add Reactionするメッセージを特定するみたいです.
Conversationだと callback: function(response, convo) {}
の response
に返答が入ってるようです.
(「yes」「no」などのメッセージオブジェクト.)
これを指定して bot.api.reactions.add()
してやると,返答にEmojiを付けられます.
まとめ
Botkitだと,標準で対話機能が提供されてるので,簡単に実装できました.
SLPでもこんな感じで,SlackとGitHubを連携させて,ChatOpsが流行ればなーと思っています.
(ChatOpsすると自動化が必要になるので,色々便利になったり,運用ミス減らせるんじゃないかな?)
Hubotで同様の機能を,@bouzuyaさんがhubot-prとして作られてます.
こちらはプルリクの一覧表示ができるなど,高機能で良いですね.