Amazon API Gateway+AWS Lambdaを利用してGitBucketのイベントをChatWorkに通知する


はじめに

GitBucketの新着イベントをChatWorkに通知するため、Amazon API Gateway+AWS Lambdaを利用してサーバーレスに連携する仕組みを実装した。
https://github.com/tokada/gitbucket-chatwork

ここではAWS環境の設定を含めた手順を記載する。

関数パッケージの準備

https://github.com/tokada/gitbucket-chatwork からコードを取得し、ローカルでnpmパッケージを含めたzipファイルを作成する。

git clone https://github.com/tokada/gitbucket-chatwork.git
cd gitbucket-chatwork
npm install request ejs
zip -r gitbucket-chatwork.zip *

AWS環境の設定手順

Lambda関数の作成

「AWS Lambda > 関数の作成」 から、以下のように関数を作成する。

  • 名前
    • 任意(postChatWorkMessageなど)
  • ランタイム
    • Node.js 6.10
  • ロール
    • Lambda用のロールがない場合は、「Basic Edge Lambda アクセス権限」を付与したロールを作成する

Lambda関数コードの設定

関数コード

ローカルで作成した「gitbucket-chatwork.zip」をアップロードして関数コードを作成する。

  • コード エントリ タイプ
    • .ZIPファイルをアップロード
  • ランタイム
    • Node.js 6.10
  • ハンドラ
    • index.handler(デフォルト値)
  • 関数パッケージ
    • ファイルダイアログで gitbucket-chatwork.zip を選択

環境変数

環境変数CHATWORK_TOKEN(ChatWorkのAPIキー)とCHATWORK_ROOM_ID(/#!ridNNNNNNNNで示される投稿先の部屋ID)を設定する。

関数コードの確認

「保存」をクリックすると設定が保存される。

関数コードのコードエントリタイプを「コードをインラインで編集」に切り替えると、アップロードされたコードを確認、編集することができる。

Lambda関数コードのテスト

「テストイベントの設定」から、GitBucketのPushイベントを再現するテストイベントを作成する。

作成例

  • イベント名
    • myPushEvent
  • ペイロード
{
  "httpMethod": "POST",
  "headers": null,
  "queryStringParameters": null,
  "pathParameters": null,
  "stageVariables": null,
  "body": "{\"pusher\":{\"name\":\"myname\",\"email\":\"[email protected]\"},\"sender\":{\"login\":\"myname\",\"email\":\"[email protected]\",\"type\":\"User\",\"site_admin\":true,\"created_at\":\"2015-07-22T21:27:26Z\",\"url\":\"http://gitbucket:8080/api/v3/users/myname\",\"html_url\":\"http://gitbucket:8080/myname\",\"avatar_url\":\"http://gitbucket:8080/myname/_avatar\"},\"ref\":\"refs/heads/master\",\"before\":\"ccc0e52c82bf666e2920c44e7b5ffc13b11d5948\",\"after\":\"4d3671004ed03ab75dd3396c55313d36b57e2bbb\",\"commits\":[{\"id\":\"4d3671004ed03ab75dd3396c55313d36b57e2bbb\",\"message\":\"\\\"テスト\\\"<pre>myrepos</pre>\\n\",\"timestamp\":\"2017-12-05T06:42:03Z\",\"added\":[],\"removed\":[],\"modified\":[\"README.md\"],\"author\":{\"name\":\"myname\",\"email\":\"[email protected]\",\"date\":\"2017-12-05T06:42:03Z\"},\"committer\":{\"name\":\"myname\",\"email\":\"[email protected]\",\"date\":\"2017-12-05T06:42:03Z\"},\"url\":\"http://gitbucket:8080/myname/myrepos/commit/4d3671004ed03ab75dd3396c55313d36b57e2bbb\"}],\"repository\":{\"name\":\"myrepos\",\"full_name\":\"myname/myrepos\",\"description\":\"\",\"watchers\":0,\"forks\":0,\"private\":true,\"default_branch\":\"master\",\"owner\":{\"login\":\"myname\",\"email\":\"[email protected]\",\"type\":\"User\",\"site_admin\":true,\"created_at\":\"2015-07-22T21:27:26Z\",\"url\":\"http://gitbucket:8080/api/v3/users/myname\",\"html_url\":\"http://gitbucket:8080/myname\",\"avatar_url\":\"http://gitbucket:8080/myname/_avatar\"},\"forks_count\":0,\"watchers_count\":0,\"url\":\"http://gitbucket:8080/myname/myrepos\",\"http_url\":\"http://gitbucket:8080/git/myname/myrepos.git\",\"clone_url\":\"http://gitbucket:8080/git/myname/myrepos.git\",\"html_url\":\"http://gitbucket:8080/myname/myrepos\"},\"compare\":\"http://gitbucket:8080/myname/myrepos/commit/4d3671004ed03ab75dd3396c55313d36b57e2bbb\",\"head_commit\":{\"id\":\"4d3671004ed03ab75dd3396c55313d36b57e2bbb\",\"message\":\"\\\"テスト\\\"<pre>myrepos</pre>\\n\",\"timestamp\":\"2017-12-05T06:42:03Z\",\"added\":[],\"removed\":[],\"modified\":[\"README.md\"],\"author\":{\"name\":\"myname\",\"email\":\"[email protected]\",\"date\":\"2017-12-05T06:42:03Z\"},\"committer\":{\"name\":\"myname\",\"email\":\"[email protected]\",\"date\":\"2017-12-05T06:42:03Z\"},\"url\":\"http://gitbucket:8080/myname/myrepos/commit/4d3671004ed03ab75dd3396c55313d36b57e2bbb\"}}",
  "isBase64Encoded": false
}

ここで、ペイロードには後述のAmazon API Gateway Lambda統合プロキシから送られる形式で値が設定されている。
bodyには、元のGitBucket Webhooksで送信されるPushEventのapplication/json形式リクエストペイロードが文字列にエンコードされている。

テストイベント作成後、「テスト」をクリックすると、環境変数で設定されたChatWorkの部屋にテストメッセージが投稿され、実行結果が成功で返ればOK。

APIの作成(Amazon API Gateway)

GitBucketのOutgoing WebHookで利用するAPIを作成する。

APIの作成

Amazon API Gatewayから適当な名前でAPIを作成する。

リソースの作成

作成したAPIの「アクション」→「リソースの作成」から、適当な名前でリソースを作成する。

メソッドの作成

作成したリソースに対して「アクション」→「メソッドの作成」からPOSTメソッドを作成し、Lambdaプロキシ統合として設定する。

  • 統合タイプ
    • Lambda関数
  • Lambdaプロキシ統合の使用
    • ONにする
  • Lambdaリージョン
    • Lambda関数を作成したリージョン
  • Lambda関数
    • 作成したLambda関数名を入力する
  • デフォルトタイムアウトの使用
    • ONにする

「保存」をクリックすると、指定のLambda関数にリクエスト情報をプロキシするAPIメソッドが作成される。(統合リクエストのタイプがLAMBDA_PROXY)

APIのテスト

左側の「テスト⚡」をクリックし、リクエスト本文にPushイベントのサンプルペイロードを入力して「⚡テスト」をクリックする。

ChatWorkにサンプルペイロードの内容が投稿され、200レスポンスが返ればOK。

APIのデプロイ

「アクション」から「APIのデプロイ」を選択し、「新しいステージ」からステージ名(dev, staging, prodなど)を設定してAPIをデプロイする。

ステージ名を開いてリソース名「/chatwork-message」メソッド名「POST」を開くとAPIエンドポイントURLが確認できる。このURLをGitBucket側でリポジトリのWebhookに設定する。

GitBucket Webhookの設定

GitBucketでリポジトリの「Settings」→「Service Hooks」→「Add Webhook」からWebhookを設定する。

  • Payload URL
    • 上記のAPIエンドポイント
  • Content type
    • application/json を選択
  • Security Token
    • 空欄
  • Which events would you like to trigger this webhook?
    • 通知対象とするイベントを選択する

動作確認

該当のGitBucketリポジトリで操作を行い、ChatWorkにイベントが通知されることを確認する。

その他

GitBucketのAPIはGitHub APIのサブセットとなっており下位互換性があるので、GitHubとの連携でも問題なく使えるはず?(未確認)

参考リンク