API Gatewayを使ってSlackの書き込みをChatWorkに連携する
チャットツールとしてChatWorkとSlackを併用しているのですが、業務では個人的にSlackをあまり利用していません。 しかし、何か連絡が来た時に気づかないと困るという状況でした。
たまにしか見ないものに意識を使うのもなんなので、普段意識を使うチャットツールを1本に絞るため、SlackのメッセージをChatWorkに流してみます。
構成
少々変則的ですが、以下の構成でSlackのメッセージをChatWorkに連携します。
- SlackのOutgoing WebHooksでAPI Gateway1にメッセージを送信(API Gateway1)
- Slackから値を受け取る(API Gateway1)
- 値をJSONに変換しAPI Gateway2に送信(API Gateway1)
- 変換された値を受け取り検証する(API Gateway2)
- JSONをChatWorkのAPIで受け取れる値に変換し、ChatWorkに送信(API Gateway2)
API Gatewayを2つ利用しているのは、
- Slackから送信されるtokenの検証をしたい
- SlackからはデータがJSONで送信されない
- JSONでないとJSON Schemaで検証できない
といった理由から、API Gateway1でJSONに変換してAPI Gateway2でTokenの検証をしているためです。 (tokenの検証をJSON schemaのバリデーションで対応するのはどうだろう?とも思いますが、今回はとにかく簡単にやりたいのでこのようにしています。)
本記事でAPI Gatewayを2つ利用している仕組みについては、以下の記事でも記載しています。
API Gatewayを2つつないでJSON以外の値をJSON Schemaでバリデーションしてみた
やってみる
以下の流れで設定していきます。
- API Gateway2の設定(ChatWorkへデータを送信するAPI Gateway)
- API Gateway1の設定(Slackからデータを受け取るAPI Gateway)
- SlackのOutgoing WebHooksの設定
- SlackのtokenをAPI Gateway2に設定
1. API Gateway2の設定
API Gateway1からAPI Gateway2に接続する設定をする必要があるため、先にAPI Gateway2を設定します。
APIを作成し、POSTメソッドを設定
以下の設定でPOSTメソッドを設定します。
- integration type:HTTP
- Endpoint URL:https://api.chatwork.com/v2/rooms/[room_id]/messages
room_id
にはChatWorkのグループチャットのURLより、https://kcw.kddi.ne.jp/#!ridXXXXXXのXXXXXX
の部分を指定します。
モデルの作成
API Gateway1から送信されるデータに合わせてモデルを作成します。 Content typeにはapplication/jsonを、Model schemaには以下を設定します。
{ "$schema": "http://json-schema.org/draft-04/schema#", "description": "", "type": "object", "properties": { "token": { "enum" : ["XXXXXXX"] }, "team_id": { "type": "string", "minLength": 1 }, "team_domain": { "type": "string", "minLength": 1 }, "service_id": { "type": "string", "minLength": 1 }, "channel_id": { "type": "string", "minLength": 1 }, "channel_name": { "type": "string", "minLength": 1 }, "timestamp": { "type": "string", "minLength": 1 }, "user_id": { "type": "string", "minLength": 1 }, "user_name": { "type": "string", "minLength": 1 }, "text": { "type": "string", "minLength": 1 } }, "required": [ "token", "team_id", "team_domain", "service_id", "channel_id", "channel_name", "timestamp", "user_id", "user_name", "text" ] }
Slackから送信されたリクエストのみを受け付ける値をJSON schemaによって検証しています。 tokenの値はSlackの設定後に設定し直します。
こちらのスキーマはjson-schema-generatorによって生成したものを元にしています。
Method Requestの設定
API Gateway2のMethod Requestを設定します。 リクエストの検証を本文の検証に設定し、コンテンツタイプapplication/jsonのモデルに先ほど作成したモデルを設定します。
Integration Requestの設定
API Gateway2のIntegration Requestを設定します。
Http Headersに以下の値を設定します。
- X-ChatWorkToken:チャットワークのAPIキー
- Content-Type:'application/x-www-form-urlencoded'
※どちらの値もシングルクオートでくくる必要があります。
application/x-www-form-urlencodedのマッピングテンプレートを定義し、以下の値を設定します。
body=[info][title]${input.path('$.user_name').toString()}[/title]${input.path('$.text').toString()}[/info]
ChatWorkのメッセージ記法に合わせて、メッセージの投稿者とメッセージ本文を設定しています。 こちらの値を変更することで、ChatWorkに連携する情報の種類やメッセージのフォーマットを変更できます。
ChatWorkのメッセージ記法の詳細はこちらをご確認ください。
設定が完了したら、APIをデプロイし作成したエンドポイントのURLをメモしておきます。(API Gateway1の設定で使います。)
2. API Gateway1の設定
Slackから値を受け取るAPI Gateway1の設定をします。
APIを作成し、POSTメソッドを設定
以下の設定でPOSTメソッドを設定します。
- integration type:HTTP
- Endpoint URL:API Gateway2のエンドポイント
Integration Requestの設定
Http Headersに以下の値を設定します。
- Content-Type:'application/json'
※'application/json'はシングルクオートでくくる必要があります。
application/x-www-form-urlencodedのマッピングテンプレートを定義し、以下の値を設定します。
{ #set( $tmpstr = $input.body ) #foreach( $keyandvaluestr in $tmpstr.split( '&' ) ) #set( $keyandvaluearray = $keyandvaluestr.split( '=' ) ) "$keyandvaluearray[0]" : "$keyandvaluearray[1]"#if( $foreach.hasNext ),#end #end }
Slackから送信される値は「token=XXXXXXXX&user_name=inabajun&text=hello....」のような形式ですが、これをJSON形式に変換しています。
設定が完了したら、APIをデプロイし作成したエンドポイントのURLをメモしておきます。(Slack側の設定で使います。)
3. SlackのOutgoing WebHooksの設定
左メニューのAppsを選択し、Browse AppsにてOutgoing WebHooksを選択
Add Configrationを選択
Add Outgoing WebHooks integrationを選択
Integration Settings
以下の値を設定します。
- Channel:Slackから連携したいChannelを選択
- URL(s):API Gateway1のエンドポイントを設定
また、Integration Settings内に表示されるtokenの値をメモしておきます。
4. SlackのtokenをAPI Gateway2のモデルに設定
API Gateway2のモデル仮の値にしていたtokenを、SlackのOutgoing WebHooksにて払い出された値で再設定します。
以下のXXXXXXX
を、Slackで生成されたtokenの値に再設定します。
"token": { "enum" : ["XXXXXXX"] },
再度API Gateway2をデプロイしたら設定完了です。
試してみる
Slackで設定したChannelにメッセージを入力します。
ChatWorkにメッセージが連携されました。
ChatWork→Slackはこちら
注意
ChatWork→Slackの記事でも紹介されていますが、ChatWorkのAPIは呼び出し回数に「5分あたり100回まで」という制限があります。 参考:エンドポイント - チャットワークAPIドキュメント
Slackに5分以内100回以上メッセージを送ったり、他にもAPIを利用していると上限に達してしまう可能性が十分にありますので、あまり使わないChannelや、日報のようなメッセージの数が決まっているChannelでの使用が現実的かと思います。
私からは以上です。