先日、ChatworkがWebhookに対応されました。弊社では普段からChatworkを利用しており、早速検証しました。
Webhook対応でできること
ChatworkがWebhookに対応したことで、「自分宛のメッセージ受信」「特定のルームでの発言」等をトリガーに、任意のURLを呼び出し処理を実行できるようになります。
今までも、APIで特定のルームのメッセージをポーリングすることで、同様のことは実現できました。ただし、APIリクエスト数の「5分あたり100回」という制限もあり、リアルタイム性に課題がありました。
Webhookの利用方法
公式ドキュメントに詳しく記載されていますが、簡単に紹介したいと思います。
Webhookの受信側の準備
AWS EC2上にRailsアプリケーションを構築し、Webhookから呼び出すコントローラを準備します。
class Chatwork::WebhookController < ApplicationController def test # 処理を実装 end end
Webhookの作成
Chatworkの設定画面で、Webhookメニューが新しく追加されており、そこからWebhookが作成できます。
- Webhook名
- 任意です
- Webhook URL
- httpsから始まる必要があります。
- イベント
- トリガーとなるイベントを設定します。
- アカウントに対するイベントか、特定のルームでのイベントのどちらかが選択できます。
- ルームイベントの場合は、自身が所属するルームIDしか入力できません。
Webhookの確認
該当のルームでメッセージを投稿すると、指定したWebhook URLが呼び出され、Chatworkから以下のデータがPOSTされます。 ポーリングとは異なり、即座に反応します。
{"webhook_setting_id"=>"xxxxxxxxxxxx", "webhook_event_type"=>"message_created", "webhook_event_time"=>1509724361, "webhook_event"=>{"message_id"=>"xxxxxxxxxxxx", "room_id"=>xxxxxxxxxxxx, "account_id"=>xxxxxxxxxxxx, "body"=>"テストメッセージ", "send_time"=>1509724361, "update_time"=>0}, "room_id"=>"xxxxxxxxxxxx", "webhook"=>{"webhook_setting_id"=>"xxx", "webhook_event_type"=>"message_created", "webhook_event_time"=>1509724361, "webhook_event"=>{"message_id"=>"xxxxxxxxxxxx", "room_id"=>xxxxxxxxxxxx, "account_id"=>xxxxxxxxxxxx, "body"=>"テストメッセージ", "send_time"=>1509724361, "update_time"=>0}}}
これでWebhookの設定は完了です。あとはパラメータの内容を解析して、任意の処理を実装すれば、Chatworkでの投稿をトリガーとしたBotが作成できます。
リクエストの署名検証
実装上必須ではありませんが、Webhookリクエストの送信元がChatworkであることを、確認する方法が用意されています。
- トークンをBASE64デコードしたバイト列を秘密鍵として、HMAC-SHA256アルゴリズムによりリクエストボディのダイジェスト値を得ます
- ダイジェスト値をBASE64エンコードした文字列が、リクエストヘッダに付与されたsignature(X-ChatWorkWebhookSignatureヘッダの値)と一致することを確認します
上記の説明だけでは少し複雑ですが、Ruby/Railsでは、以下のように実装しました。
require 'openssl' require 'base64' def test if chatwork_signature.present? && chatwork_signature == Base64.strict_encode64(digest) render text: 'success', status: 200 else render text: 'invalid', status: 403 end end private def secret_key token = '[トークン]' Base64.decode64(token) end def request_body request.body.read end def chatwork_signature request.headers[:HTTP_X_CHATWORKWEBHOOKSIGNATURE] end def digest OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha256'), secret_key, request_body) en
※ トークンは、Webhookの設定画面から確認できます。
まとめ
Webhookを利用すると、簡単にリアルタイム性の高いやりとりが実現できることが確認できました。
弊社では、既にChatworkとHubot連携してデプロイ等を行っていますが、Webhookを利用して更に自動化を進めていきたいと思います。
LCLではエンジニア・インターン募集中です。 サービス開発はもちろん、開発プロセスの自動化も積極的に推進しています。 少しでも興味がある方は、ご連絡お願い致します。