読者です 読者をやめる 読者になる 読者になる

paiza開発日誌

IT/Webエンジニア向け総合求人・学習サービス「paiza」(https://paiza.jp ギノ株式会社)の開発者が開発の事、プログラミングネタ、ITエンジニアの転職などについて書いています。

SlackとHubotで開発チームの分報を集めるBotを作ってみた

f:id:paiza:20170501190924j:plain
Photo by Alper Çuğun
中村です。

チームで開発している皆さんは、そのチーム内でのコミュニケーションをどのようにとっていますか?

最近、弊社のエンジニアチーム内ではSlackをもっと便利に使おうぜブームが来ているので、実験的に分報を書く取り組みを実施しています。

分報とは何ぞという方はこちら
要は「全部の報告が日報だと遅いときあるよねー、ツイッターでツイートするみたいに、その都度チャットで気軽に報告し合えた方がいいよねー」っていうのが分報です。

今まではSlackにエンジニアチーム用のchannelがあって、そこにみんなで書き込んでいたのですが、スレッドやメッセージのシェアがあるとはいえ、個人のつぶやきを投稿するような感じでは使えていませんでした。

あと、GitHubのプルリクエストでも作業の内容は見れるのですが、そもそもレビュー前にノウハウを共有できた方が効率的ですし、レビューとは違う問題へのアプローチもできそうですよね。

そんな期待を込めて、Slackで分報を集めるBotを作ってみることにしました。

■導入当初の話

初めは、メンバーごとのchannelへの投稿を、Zapierを使って「timeline」というchannelに集めてみました。

Zapierとは
zapier.com
なんかいろんなサービスを連携させていろいろできる便利なやつです。

しかしですね、このZapierを使う方法ではすぐに欠陥が見つかりました。別のメンバーのchannelへの投稿をすると、timelineにはchannelのオーナーの投稿のように見えてしまうのです。(AさんがオーナーのchannelへBさんが投稿すると、timelineにはAさんの投稿として表示されてしまう…という感じです)

そのため返信はtimelineに書いていたのですが、それだと結局後から議論を振り返りたいとなった場合はtimelineをいちいち読み解く必要があって、かなり面倒でした。

そこで、今度はHubotを使って分報の一覧を作っている方のやり方をを真似することにしました。

↓参考記事
qiita.com
ただ、この記事が書かれたときと現在(2017年5月時点)では、Slack APIのバージョンが異なっているため、そのままではうまく動かず、次のような対応をいろいろしてみました。

■Hubotを使って連携させるためにSlack APIの変更に対応する

◆方法の検討

分報用のchannelは `times_foobar` という命名規則を採用しています。前述の参考記事では、その命名規則を利用してコントロールをしていますが、Slack APIの変更に伴い、2017年5月時点では `msg.envelope.room` の結果はIDになっているため、そのままのコードではうまく動作しません。

そこで、いくつか解決策を考えてみました。

  1. timelineに載せるchannelのIDを、Herokuの環境変数として管理する
  2. Hubotが招待されているchannel全て(timelineをID指定で除く)という条件にする
  3. 命名規則でやるためにchannelの名前を取ってくる

…という選択肢が思いつきましたが、1だとメンバーが増えるたびに作業が必要だし、2だとHubotを他の目的に利用できなくなってしまいます。

というわけで、channel名を取得する方法を調べてみました。

◆channelの名前を取得する

Hubotで利用しているadapterで `robot.adapter.client` からSlackのクライアントにアクセスしてみましょう。

Slack APIとしてはrtm.startがありますが、今回はchannel名が欲しいだけです。ユーザー、チャンネルなどの情報はHubot内のSlackクライアントがMemoryDataStoreとしてキャッシュしてくれているので、そちらを使った方がよさげですね。

今回はchannelからの投稿だけを前提にしているので `getChannelById(channelId)` を使います。するとChannelオブジェクトが返却されるので、nameを取り出すことができました。

※参考:SlackMemoryDataStore.md

roomId = msg.envelope.room
room = robot.adapter.client.rtm.dataStore.getChannelById(roomId)
room.name // => 'times_foobar'

ただ、余談ですがhubot-slack adapter の開発者間で「 robot.adapter.client.rtm.dataStore ではなく robot.brain を使うべき」という議論が出ているようなので、今後はこのやり方は非推奨になるのかもしれません…。

github.com

◆動かしてみる

あとは参考記事の通りに動かせますね。

チーム名の部分はHerokuの環境変数を利用しています。今見ると、投稿先のchannel名も環境変数にしてしまえばよかったですね…。

module.exports = (robot) ->
  robot.hear /.+/, (msg) ->
    roomId = msg.envelope.room
    room = robot.adapter.client.rtm.dataStore.getChannelById(roomId)
 
    if room.name.match('^times_.+')
      id = msg.message.id.replace('.','')
      archiveUrl = "https://#{ process.env.SLACK_TEAM_NAME }.slack.com/archives/#{ room_id }/p#{ id }"
 
      robot.send { room: '#timeline' }, archiveUrl


HubotをHerokuにデプロイして動かした結果がこちらになります。

ちなみにHubotのアイコンは、「ぱいじょ!」に登場する霧島京子さんの自作マシン・マーガレットちゃんです。
f:id:paiza:20170501184415p:plain

paiza.jp

■まとめ

というわけで、Slackで分報を集めるBotを作ってみました。

分報を導入したいなーという人や、分報に限らずSlackでBotを作りたいなーという人の参考になればと思います。

また今回初めてHubotを触ったので、何かおかしな点などあればご指摘いただけますと嬉しいです。

■「Rails入門レッスン」を期間限定・無料公開中!動画で学べる「paizaラーニング


paizaラーニング」は、プログラミング未経験者・初心者向け学習サービスです。

現在、普段は有料の「Webアプリ開発入門 Rails編」の各レッスンを、期間限定で連続無料公開しております!

Webアプリ開発入門 Rails編」無料公開スケジュール


動画レッスン名無料期間
Rails入門1いつでも無料
Rails入門24/25(火)~5/1(月)まで無料
Rails入門35/2(火)~5/8(月)まで無料

↓詳しくはこちら
paiza.jp

paizaでは、Webサービス開発企業などで求められるコーディング力や、テストケースを想定する力などが問われるプログラミングスキルチェック問題も提供しています。
paiza.jp
スキルチェックに挑戦した人は、その結果によってS・A・B・C・D・Eの6段階のランクを取得できます。必要なスキルランクを取得すれば、書類選考なしで企業の求人に応募することも可能です。「自分のプログラミングスキルを客観的に知りたい」「スキルを使って転職したい」という方は、ぜひチャレンジしてみてください。

ITプログラマ・エンジニア向け転職・就活・学習サービスのpaiza

プログラミング入門講座|paizaラーニング

PHP入門編Ruby入門編Python入門編Java入門編JavaScript入門編C言語入門編C#入門編アルゴリズム入門編