Edited at

[GitHub API & Webhook + hubot]社内で実際にいい反響を得ているチャットボットの機能

More than 1 year has passed since last update.

サイバー・バズの@kashira2339です。

チャットボット Advent Calendar 2016の6日目の記事となります。

弊社ではSlackを使っており、そこでは何体かのhubotが動いています。



作って役立ってるもの

話は結論から。


1. hubotで現在のマイルストーン問い合わせする機能

Slack_-_Cyber_Buzz.png

モザイクがかかっているが、汚いものではない。

hubot {repository} (ms|milestones) now

弊社のSlackで動作しているhubotは、このように話しかけると

現在のマイルストーン及びそのマイルストーンに紐づくIssueを出力してくれる。


なんでBotで?


  1. でしゃばらないテキストインターフェースでもいい

  2. みんなにコピペして共有する手間がはぶける

弊社にはリリース前にチャットなどにリリースノートを貼るという文化があった。

「これ今日リリースするものなので確認お願いしまーす」

とかを、GitHubのmilestonesから拾い上げてきて共有することが面倒臭かった。

欲しい形でまとまってないし。

チャットで表示されれば自然とみんな見てくれてるし、

適度に出力が整っていればいいということでbotで採用。

通知したいチャンネルでhubot xxxx ms nowって発言すれば済むので楽チンなのだ。


簡単な実装説明

# hubot + GitHubなら、githubotがいい

npm install --save githubot

github = require './github'

module.exports = (robot) ->
# 反応させるパターンを決めて、
robot.respond /(.+) (milestones|ms) now/i, (msg) ->
repo = msg.match[1]
github.milestones { repo: repo }, (response) ->
# マイルストーンいろいろしたり、
github.issues { repo: repo, milestone: マイルストーン番号 }, (response) ->
# Issueをいろいろして、
msg.send "なんかメッセージ"

マイルストーンと紐づくIssueの取得に必須なのはこれくらい。

あとは、お好みで並び替えたり絞り込んだりして、msg.sendに渡してしまえばチャットルームでボットがしゃべる。


2. GitHubのメンション・アサインを読み取り、SlackにDMを送る

スクリーンショット_0028-12-05_午後8_02_01.png

このBotからのメッセージは、GitHubのIssueやPullRequestのコメント上で

メンションが検出されたユーザー向けのDMとなっているため、全員が使うチャットの画面を汚すことがない。

また、DMなので運用担当者であっても非常に気づいてくれやすく、

Issueをベースにしたコミュニケーションが円滑になった。

(通知がきてたあのIssueの件だけど...とか)

今ではこのBotからDMが飛ばないと苦情がくるほどである。


なんでBotで?


  1. Botが「話しかけてくる」という魅力

正直この機能は、GitHubのWebHookさえ待ち構えられれば(ようは、Webサーバーがあれば)それで十分なのである。

だが、Botはチャットへのもう一人の参加者なのだ。

単なる監視システムからのNotifycationなどとは愛情の深さが違うのである。

botme
AWS CloudWatch

botme.png
Slack-cwatch.png

モザイクが悪い演出をしているが、これがDMでくると思うと非常に愛らしくはないだろうか?

「すぐに確認しなきゃ!」という気持ちになる。


簡単な実装説明

# GitHub Webhookのヘッダに含まれるシグネチャの検証
isValidSign = (sign, body) ->
secret = process.env.HUBOT_GITHUB_WEBHOOK_SECRET
hmac = crypto.createHmac 'sha1', secret
hmac.update JSON.stringify(body), 'utf-8'
hash = hmac.digest 'hex'
generated_signature = "sha1=#{hash}"

module.exports = (robot) ->
# hubotは標準でExpressに依存しているのでルーティング簡単
robot.router.post '/github/webhook', (req, res) ->
# イベントの型取って、シグネチャも検証する
type = req.get 'X-Github-Event'
sign = req.get 'X-Hub-Signature'

unless isValidSign sign, req.body
res.status(401).send 'unauthorized'
return

# req.bodyがwebhook本体なのでいろいろして
res.status(200).send 'ok' # 200返しとく
if !!robot.adapter.client
userId = robot.adapter.client.getUserByName('kashira2339')?.id
return unless userId?
robot.adapter.client.openDM userId, (data) ->
# robot.emit関数でattachment(見た目が綺麗なメッセージ)が送れる!
robot.emit 'slack.attachment',
content:
pretext: 'タイトルの上のプレーンテキスト'
text: '本文'
fallback: '通知時の文言'
title: 'タイトル'
title_link: 'タイトルクリック時の飛び先'
mrkdwn_in: ['markdownを適用するプロパティ(textとか)']
color: '色(16進数)'
channel: param['kashira2339'] # ユーザ名
else
robot.send {room: '#general'}, "めっせーじ"

基本的にはこのページ(GitHub Webhooks)とにらめっこしながら作る。

https://developer.github.com/webhooks/

イベントに対応したペイロードに含まれる文字列などからusernameを抽出したら、

あとはそのusernameをSlackの名前と照らし合わせれば、該当ユーザにDMを送れる。

セキュリティのため、シグネチャの検証はしておいた方がいい。


背景

サイバー・バズはもともと他のプロジェクト管理ツール

(某〜らぼさんの出している某acklogというツール)を使っていたのだが、

ある機会にこれをGitHubのIssue駆動に乗り換えた。

自分の所属チームではZenHubも併用している。

もはやこれなしで仕事するにはストレスが溜まるほどだ。

ただし、乗り換えには不満がつきもので

今までできたことが1つできなくなるだけで、とても不便に感じるものである。

開発チームはGitHub運用に概ね賛成だったものの、運用チームは移行のメリットをそこまで享受できなかったり、英語を嫌ったりと難色を示していた。

中でも、移行期間中に上がった大きな不満は以下の2つのことであった。


  • 「リリースノートが見づらい」

  • 「通知が来てるかわかりにくい」

Slackには、GitHubのIntegrationが標準で用意されており、それ単体でもかなり使える。

GitHub自体にもNotificationsページが用意されている。

しかし、このIntegrationやGitHubの機能だけでは上記の課題を満足に解決することはできず、

より強力なソリューションを求めることとなった。

それで実装に至ったのが、上記2つの機能なのである。


※ ここからはうわごと


チャットボットの年

2016年はチャットボットが話題となった年だった。

というより、チャットというプラットフォームでできることへの注目が集まり、高度な技術を持つ人好奇心旺盛な人お金が大好きな人が次々とチャットの世界へ足を踏み入れた。。

FacebookのMessenger Platform BETA

LINE Messaging API

こういったAPIも大手SNSから公開され、

チャットボットへの関心は以前の比にならないくらい高まった。

Google Trendsで「チャットボット」で調べてみても、その推移は一目瞭然だ。

スクリーンショット 0028-12-05 7.26.25.png


疑問

昨今ではあらゆることがチャットでできるようになったおかげで、

チャットプラットフォーム側でもあらゆる機能が実装されている。


  • お問い合わせフォーム

  • EC

  • 決済

  • 予約

また、もっと身近なところでは、チャットボットで以下をつくってみた〜なんて記事も見かける。


  • 今日の天気

  • 雑談

  • リマインダー

ただ、これだけ多くのことができるようになったからこそ

本当にチャットボットに必要な機能ってなんなんだ…?

そのように感じるようになった。


チャットボットに求められていること



- ボットが一人の参加者としてエビデンスを残すこと

- 誰にでも馴染みのある抽象化されたインタフェースを提供すること

チャットという場は、プロジェクトの関係者やチームメンバーが参加している。

つまり、チャット上での発言はメンバー全員の目に触れる。

テキストボックスとチャットルーム(チャンネル)は参加者に共通のインターフェースを提供する。

チャットはログが残る。

ログは、会話の流れとともに記録される。

前後のやり取りや背景が把握しやすくなる。

GitHub社などでは、チャットプラットフォーム上でビルド・テスト・デプロイのコマンドを書き込むことでシステムの運用を図っているそうだ。これをChatOpsと読んだりする。

これらはチャット、そしてチャットボットというインタフェースが

意図せずとも記録制約を作り上げているからこそ効果を発揮する。

運用の記録を取ることで再利用可能な価値を残し、

個人の差異を吸収することで安定した運用を叶える。

これらの一つの解決策がチャット+チャットボットなのではないだろうか。



おわりに

チャットボットは、その取り組みやすさやカジュアルさも魅力。

プログラミング初心者の方もぜひ肩肘はらず、チャレンジしてみてください。

チャットボット Advent Calendar 2016の6日目はここまで。

7日目は@yukihirai0505さんより、「GASとSlackではじめるチャットボット〜初心者プログラマ向け〜」です。

ではまた。