目的
Hubot + Heroku + Slack な組み合わせはよくあるけれど、うちの社内ではチャットに Yammer を使用しているのと、AWS アカウントがあるので AWS/EC2 + Hubot + Yammer の組み合わせを試します。
Slack でやってもいいんですが周りの人にわざわざ Slack アカウント作ってもらうのが面倒なのと、誰も Yammer-Adapter 使ってなさそうなので人柱です。
Hubot-Yammer の README を読みながらすすめました。
athieriot/hubot-yammer: This is the Yammer adapter for hubot that allows you to send a message to him with Yammer and he will happily reply the same way.
結果
できました。
社内で ChatOps 的なことができそうです。
Hubot を生かす為だけに EC2 使うのもいまいちなので最終的にはこれを Lambda でサーバレスにしようと思っていたのですが、Yammer には Outgoing Webhooks の機能が無いので、Yammer に投稿があったタイミングでイベントを発行したい場合は Zapier などで Yammer -> Webhook なレシピ(zapbook)を作らないとだめみたいです。
構築手順
EC2 インスタンス作成するのと、Hubot インストールまではざっくりした流れだけ記載します。
必要なもの
必要なもの | 今回作成した名称 | 備考 |
---|---|---|
AWS の Linux インスタンス | - | 無料枠(t2.micro)のAmazon Linux を作成 |
Yammer 内 Public グループ | BOTTESTGROUP | テスト用のグループ、日本語でもいけましたがスペース入れるとだめ。 |
BOTアカウント | YAMMERBOTACCOUNT | APIトークンを取得する、実際には人のアカウントを借りました。 |
テスト用アカウント | TESTYOUACCOUNT | BOTに話しかける用、自分のアカウントを使いました。 |
AWS/EC2 上に Linux インスタンスを作成
無料枠(t2.micro)で Linux インスタンスを作成、EIP を割当てました。セキュリティグループは構築のための SSH/MyIP と、Yammer API 呼び出しのための HTTP/AnyIP で許可が必要です。後者は Yammer API の IP範囲で絞っても良いとおもいます。
nodejs, npm のインストール
Hubot、Yoneman に必要な node.js, npm をインストールします。n はグローバルにインストールした node.js のバージョン管理するものみたい。
[ec2-user@HOST ~]$ sudo yum install nodejs npm --enablerepo=epel
[ec2-user@HOST ~]$ npm -v
1.3.6
[ec2-user@HOST ~]$ sudo npm install -g n
[ec2-user@HOST ~]$ sudo n stable
install : node-v6.8.1
mkdir : /usr/local/n/versions/node/6.8.1
fetch : https://nodejs.org/dist/v6.8.1/node-v6.8.1-linux-x64.tar.gz
######################################################################## 100.0%
installed : v0.10.46
[ec2-user@HOST ~]$ node -v
v0.10.46
Yeoman、generator-hubot のインストール
Yeoman (yo) と Hubot の Yeoman ジェネレーター (generator-hubot) をインストールします。
[ec2-user@HOST ~]$ sudo npm install -g yo generator-hubot
(略)
[ec2-user@HOST ~]$ sudo npm list -g generator-hubot yo
npm WARN unmet dependency /usr/lib/node_modules/block-stream requires inherits@'~2.0.0' but will load
npm WARN unmet dependency undefined,
npm WARN unmet dependency which is version undefined
npm WARN unmet dependency /usr/lib/node_modules/fstream requires inherits@'~2.0.0' but will load
npm WARN unmet dependency undefined,
npm WARN unmet dependency which is version undefined
npm WARN unmet dependency /usr/lib/node_modules/fstream-ignore requires inherits@'2' but will load
npm WARN unmet dependency undefined,
npm WARN unmet dependency which is version undefined
npm WARN unmet dependency /usr/lib/node_modules/fstream-npm requires inherits@'2' but will load
npm WARN unmet dependency undefined,
npm WARN unmet dependency which is version undefined
npm WARN unmet dependency /usr/lib/node_modules/glob requires inherits@'2' but will load
npm WARN unmet dependency undefined,
npm WARN unmet dependency which is version undefined
npm WARN unmet dependency /usr/lib/node_modules/npmconf requires inherits@'~2.0.0' but will load
npm WARN unmet dependency undefined,
npm WARN unmet dependency which is version undefined
npm WARN unmet dependency /usr/lib/node_modules/tar requires inherits@'2' but will load
npm WARN unmet dependency undefined,
npm WARN unmet dependency which is version undefined
/usr/lib
├── generator-hubot@0.4.0
└── yo@1.8.5
###(補足)npm WARN unmet dependency 対応
何故かライブラリ inherits が不足しているようなので、追加でグローバルにインストールし、エラーが出なくなることを確認しました。
[ec2-user@HOST ~]$ sudo npm install inherits -g
npm http GET https://registry.npmjs.org/inherits
npm http 304 https://registry.npmjs.org/inherits
inherits@2.0.3 /usr/lib/node_modules/inherits
[ec2-user@HOST ~]$ sudo npm list -g generator-hubot yo
/usr/lib
├── generator-hubot@0.4.0
└── yo@1.8.5
Hubot 作成、初期設定
適当な名前でディレクトリを作成して、yo hubot で作成。Bot adapter には yammer を指定します。コンソールがかわいい。
[ec2-user@HOST ~]$ mkdir YAMMERBOT
[ec2-user@HOST ~]$ cd YAMMERBOT
[ec2-user@HOST YAMMERBOT]$ yo hubot
(略)
? Owner MYEMAILADRESS@example.com
? Bot name YAMMERBOT
? Description YammerBotDesu
? Bot adapter yammer
create bin/hubot
create bin/hubot.cmd
(略)
作成後の Procfile は web の Yammer になっています。
[ec2-user@HOST ~]$ cat Procfile
web: bin/hubot -a yammer
Hubot をローカルで動作確認
まだ Yammer には接続していません。HUBOT_HEROKU_KEEPALIVE_URL 設定せよと WARNING が出ていますが今は無視で。
[ec2-user@HOST YAMMERBOT]$ hubot
YAMMERBOT> [Thu Oct 20 2016 02:59:28 GMT+0000 (UTC)] WARNING Loading scripts from hubot-scripts.json is deprecated and will be removed in 3.0 (https://github.com/github/hubot-scripts/issues/1113) in favor of packages for each script.
Your hubot-scripts.json is empty, so you just need to remove it.
[Thu Oct 20 2016 02:59:28 GMT+0000 (UTC)] ERROR hubot-heroku-alive included, but missing HUBOT_HEROKU_KEEPALIVE_URL. `heroku config:set HUBOT_HEROKU_KEEPALIVE_URL=$(heroku apps:info -s | grep web-url | cut -d= -f2)`
[Thu Oct 20 2016 02:59:28 GMT+0000 (UTC)] INFO hubot-redis-brain: Using default redis on localhost:6379
YAMMERBOT> YAMMERBOT ping
YAMMERBOT> PONG
YAMMERBOT> YAMMERBOT time
YAMMERBOT> Server time is: Thu Oct 20 2016 03:01:21 GMT+0000 (UTC)
Yammer から API アクセスキー取得
API のアクセスキートークンを取得します。BOT アカウントで Yammer にログインした状態で下記 URL にアクセスします。
- ログインユーザ:YAMMERBOTACCOUNT
- https://www.yammer.com/client_applications
- Input
- アプリケーション名:HogeFugaApp
- 組織:HOGE
- サポート用メールアドレス:hoge@example.com
- ウェブサイト:https://example.com/
- リダイレクト先の URI:https://example.com/
上記のように超適当に入力すると、API キーを取得できます。
- Output
- クライアントID:XxXxXxXxXxXxXxXxXxXxXx
- クライアントシークレット:XxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXx
- リダイレクト先:https://example.com/
- Generate a developer token for this application
- Here is your personal token for testing. Please copy it somewhere safe as this will disappear when you change page:
- 00000-XxXxXxXxXxXxXxXxXxXx
一番下の developer token というのを使用します。
投稿用グループの作成
Yammer 上に投稿用のグループを作成、BOT アカウントとテスト用アカウントの2つをグループに追加しておきます。グループ名は環境変数に設定するので、英名のほうがよさそうです。
- グループ作成
- グループ名:BOTTESTGROUP
- 公開範囲:Public
- グループメンバ追加
- BOT アカウント:YAMMERBOTACCOUNT
- テスト用アカウント:TESTYOUACCOUNT
BOT アカウントのアカウント名は必ずしも BOT 名(YAMMERBOT)と合わせる必要はありません。
API キー設定
先ほど取得した API キーと、作成したグループ名を環境変数に追加します。HUBOT_HEROKU_KEEPALIVE_URL は何を指定すればいいのかよくわからないけど、KeepAlive のために 5 分ごとに Get しているようなので、401 が帰ってくる URL を適当に指定するとよさそうでした。Heroku じゃないけど使ってるみたいです。
[ec2-user@HOST ~]$ export HUBOT_YAMMER_ACCESS_TOKEN="00000-XxXxXxXxXxXxXxXxXxXx"
[ec2-user@HOST ~]$ export HUBOT_YAMMER_GROUPS="BOTTESTGROUP"
[ec2-user@HOST ~]$ export HUBOT_HEROKU_KEEPALIVE_URL="https://www.yammer.com/api/v1/users.json"
[ec2-user@HOST ~]$ printenv
HUBOT_YAMMER_GROUPS=BOTTESTGROUP
HUBOT_YAMMER_ACCESS_TOKEN=00000-XxXxXxXxXxXxXxXxXxXx
HUBOT_HEROKU_KEEPALIVE_URL=https://www.yammer.com/api/v1/users.json
EC2 から Yamme API に繋がること確認
ネットワーク設定確認のため、一応 wget します。
[ec2-user@HOST ~]$ wget -O - https://www.yammer.com/
(略)
- 100%[======================================================>] 15.97K --.-KB/s in 0.002s
2016-10-20 05:11:13 (10.2 MB/s) - written to stdout [16354/16354]
BOT 起動と動作確認
満を持して起動します。groups list に設定したグループ名、groups_ids list にグループ名から取得したグループIDが表示されます。5 分毎に keepalive が正常に動いたログも出ています。
[ec2-user@HOST ~]$ hubot -a yammer -n "YAMMERBOT"
[Thu Oct 20 2016 05:21:16 GMT+0000 (UTC)] WARNING Loading scripts from hubot-scripts.json is deprecated and will be removed in 3.0 (https://github.com/github/hubot-scripts/issues/1113) in favor of packages for each script.
Your hubot-scripts.json is empty, so you just need to remove it.
[Thu Oct 20 2016 05:21:16 GMT+0000 (UTC)] INFO hubot-redis-brain: Using default redis on localhost:6379
groups list : BOTTESTGROUP
groups_ids list : 0000000
[Thu Oct 20 2016 05:26:15 GMT+0000 (UTC)] INFO keepalive ping
[Thu Oct 20 2016 05:26:16 GMT+0000 (UTC)] INFO keepalive pong: 401
[Thu Oct 20 2016 05:31:15 GMT+0000 (UTC)] INFO keepalive ping
[Thu Oct 20 2016 05:31:16 GMT+0000 (UTC)] INFO keepalive pong: 401
Yammer のテスト用アカウントから「YAMMERBOT PING」の形式でコマンドが送れました。コンソール側にもログが出力されます。
received YAMMERBOT PING from TESTYOUACCOUNT (thread_id: 000000000, sender_id: 0000000)
reply message to TESTYOUACCOUNT with text PONG
Message creation status 201
おまけのエラー集
BOT アカウント からテストできない。
BOT アカウントで BOT アカウントに話しかけても無視される仕様でした。
groups list : BOTTESTGROUP
groups_ids list : 0000000
received YAMMERBOT PING from YAMMERBOTACCOUNT (thread_id: 000000000, sender_id: 0000000)
YAMMERBOT does not reply himself, YAMMERBOT not crazy nor desperate
認証エラー(Authentication failure)
HUBOT_YAMMER_ACCESS_TOKEN を間違えていると起きるようです。Yammer が落ちててネットワークエラーもこれになりました。
[Thu Oct 20 2016 04:06:52 GMT+0000 (UTC)] ERROR TypeError: Cannot use 'in' operator to search for 'data' in undefined
at /home/ec2-user/node_modules/hubot-yammer/src/yammer.coffee:80:6, <js>:146:23
at /home/ec2-user/node_modules/yammer/main.js:13:19
at Request._callback (/home/ec2-user/node_modules/yammer/main.js:132:14)
at Request.self.callback (/home/ec2-user/node_modules/yammer/node_modules/request/request.js:121:22)
at emitTwo (events.js:106:13)
at Request.emit (events.js:191:7)
at Request.<anonymous> (/home/ec2-user/node_modules/yammer/node_modules/request/request.js:978:14)
at emitOne (events.js:101:20)
at Request.emit (events.js:188:7)
at IncomingMessage.<anonymous> (/home/ec2-user/node_modules/yammer/node_modules/request/request.js:929:12)
at emitNone (events.js:91:20)
at IncomingMessage.emit (events.js:185:7)
at endReadableNT (_stream_readable.js:974:12)
at _combinedTickCallback (internal/process/next_tick.js:74:11)
at process._tickCallback (internal/process/next_tick.js:98:9)
yammer groups error: Error: Error status 401
Authentication failure.
Yammer のステータスはこちら、よく落ちます。ChatOps もそうだけどサービスフルにすると SaaS が止まると業務が止まりますね。
groups_id 取得できないエラー
「groups_ids list : (ブランク)」になる場合は、グループ ID が取得できていません、グループが存在しなかったり、変数 HUBOT_YAMMER_GROUPS の指定を間違えるとなるようです。正常に取得できた場合の ID は Yammer グループ URL の feedId が取得されます。
https://www.yammer.com/COMPANY.com/#/threads/inGroup?type=in_group&feedId=0000000&view=all
[Thu Oct 20 2016 04:07:24 GMT+0000 (UTC)] INFO hubot-redis-brain: Using default redis on localhost:6379
groups list : WRONG_GROUP_NAME
groups_ids list :
[Thu Oct 20 2016 04:07:24 GMT+0000 (UTC)] ERROR Error: No group registered or an error occured to resolve IDs.
at /home/ec2-user/node_modules/hubot-yammer/src/yammer.coffee:146:20, <js>:225:17
at Request._callback (/home/ec2-user/node_modules/yammer/main.js:137:12)
at Request.self.callback (/home/ec2-user/node_modules/yammer/node_modules/request/request.js:121:22)
at emitTwo (events.js:106:13)
at Request.emit (events.js:191:7)
at Request.<anonymous> (/home/ec2-user/node_modules/yammer/node_modules/request/request.js:978:14)
at emitOne (events.js:101:20)
at Request.emit (events.js:188:7)
at IncomingMessage.<anonymous> (/home/ec2-user/node_modules/yammer/node_modules/request/request.js:929:12)
at emitNone (events.js:91:20)
at IncomingMessage.emit (events.js:185:7)
at endReadableNT (_stream_readable.js:974:12)
at _combinedTickCallback (internal/process/next_tick.js:74:11)
at process._tickCallback (internal/process/next_tick.js:98:9)
Yammer と通信できないときのエラー
HTTP/Any を許可していないときは次のようなエラーになりました。グループ ID は取れてるけど。
[Thu Oct 20 2016 08:24:22 GMT+0000 (UTC)] INFO hubot-redis-brain: Using default redis on localhost:6379
groups list : BOTTESTGROUP
groups_ids list : 0000000
[Thu Oct 20 2016 08:24:25 GMT+0000 (UTC)] ERROR TypeError: Cannot use 'in' operator to search for 'data' in undefined
at /home/ec2-user/node_modules/hubot-yammer/src/yammer.coffee:80:6, <js>:146:23
at Request._callback (/home/ec2-user/node_modules/hubot-yammer/node_modules/yammer/main.js:33:43)
at Request.self.callback (/home/ec2-user/node_modules/hubot-yammer/node_modules/yammer/node_modules/request/request.js:121:22)
at emitTwo (events.js:106:13)
at Request.emit (events.js:191:7)
at Request.<anonymous> (/home/ec2-user/node_modules/hubot-yammer/node_modules/yammer/node_modules/request/request.js:978:14)
at emitOne (events.js:101:20)
at Request.emit (events.js:188:7)
at IncomingMessage.<anonymous> (/home/ec2-user/node_modules/hubot-yammer/node_modules/yammer/node_modules/request/request.js:929:12)
at emitNone (events.js:91:20)
at IncomingMessage.emit (events.js:185:7)
at endReadableNT (_stream_readable.js:974:12)
at _combinedTickCallback (internal/process/next_tick.js:74:11)
at process._tickCallback (internal/process/next_tick.js:98:9)
参考リンク
(お世話になりました)
Hubot / ChatOps とは - Qiita
Hubot を Heroku で動かして Slack から話す - Qiita
Hubot のインストール - Qiita
CentOSにEPELリポジトリを追加する - Qiita
CentOS 7 に Node.js をインストールする - Qiita
CentOSにEPELリポジトリを追加する - Qiita
npm WARN unmet dependency発生したら。 by デビット ジョナサン
Hubot を Amazon EC2 にセットアップし、Slack と連携する! - Qiita
yammer App の Programming – Tsmatz
Webhookとは? | SendGridブログ
WebHookの調査と実装
Office 365 Connectors: Where’s Yammer? | Turn the page
(以上)