BoxのWebhookを利用してAWS S3にファイルを同期する仕組みをサーバーレスで構築してみた!

2020.02.04

おつかれさまです。

「Box上の特定ファイルをAWS S3に同期したい」という要件があったので一部をブログ化してみました。

やり方としては、

  1. CloudWatch Eventsのスケジュール実行で定期的にBoxのデータを取得
  2. Box Webhookを利用してファイルの変更/削除をAPI Gatewayに通知

のパターンがあるかとおもいますが、今回は後者でおこないます。

同期というワードを利用しましたが、今回は完全同期までやりません。ファイルのアップロードを検知して、S3に転送するぐらいまでです。

構成図

せっかちな人へ

GitHubのリポジトリにLambdaのソースコードとTerraformのtfファイルをあげています。

すでにBoxアプリを作成している方には、こちらが参考になるかと思います。

Box側の設定

Boxには、アプリケーションを認証してREST APIにリクエストするための認証モデルとして、「標準のOAuth 2」「JSON Web Tokens (JWT)を使用したOAuth 2」があります。

参考ドキュメント

今回はサーバーからのアクセスになるので「OAuth 2 + JWT」の設定をおこないます。

「App User」というのはアプリケーション用ユーザを指します。

アプリユーザーは、Box Platformでカスタムアプリケーションを開発する場合に作成される特別なアカウントです。アプリユーザーには、ログイン資格情報がなく、APIでしかBoxにアクセスできません。アプリユーザーは、サービスアカウントと管理者アカウントで管理されます。

アプリケーションの作成と設定

Box側の設定を公式ドキュメントに沿って進めていきます。

まずはBox画面左にある「開発者コンソール」からアプリケーションの新規作成を行っていきます。

「アプリの新規作成」 > 「カスタムアプリ」 > 「JWTを使用したOAuth 2.0」 > 「アプリの作成」 の流れで進めていき、アプリが作成されたら「アプリの表示」をクリックします。

  • アプリの新規作成

次のページでアプリの詳細設定をおこないます。

自分のユーザが作成したフォルダーへのアクセスを行うので「アプリケーションアクセス」をEnterpriseにします。 「Webhookを管理」忘れずにチェックします。

  • アプリの設定

「公開/秘密キーペアを生成」をクリックしてキーペアの生成を行い、クレデンシャル情報一式をダウンロードします。(公開鍵はBox側に登録されます。)

  • キーペアの生成

ここまででいったん変更を保存します。

次にWebhookの設定です。 これは、実際にBoxから送信されたか検証するためのキーになります。 後ほどAWS側にセットするのでメモしておきます。

  • Webhookの設定

最後に「管理コンソール」> 「Enterprise設定」の「アプリ」タブから作成したアプリの登録を行います。

  • アプリの登録

画面中央の「新しいアプリケーションを承認」をクリックしアプリケーションの登録をおこないます。 APIキーにはさきほどダウンロードしたクレデンシャル情報のclientIDを入力します。

これにてアプリの作成および設定は終了です。

Webhookの作成

ここからWebhookの作成です。

今回はログインユーザのルートディレクトリにarai-test-folderというフォルダーあらかじめ作成しています。 このフォルダー内にファイルがアップロードされたら、Webhookが起動するように設定します。

Box Cliのインストールと設定

その前に、webhookを作成するためbox cliをインストールします。

インストール方法はこちらを参考にしてください。

インストールが完了したら、config設定を行います。./config.jsonは先ほどダウンロードしたクレデンシャル情報です。

  • configの設定
$ box configure:environments:add ./config.json --name arai-test-app

  • App Userの情報表示
$ box users:get me
...省略
Name: arai-test-app
Login: AutomationUser_xxxxx_xxxxxxx@boxdevedition.com
...

ここでのApp User(アプリケーションユーザ)は、arai-test-appのことですね。

App User(アプリケーションユーザ)をBoxのフォルダーに招待

App Userをarai-test-folderに招待します。

  • 「このフォルダを共有」をクリック

  • App UserのLogin情報を入力して招待

操作後には画面右の共有が増えているかと思います。

  • 共有者一覧

これでApp Userがこのフォルダーに対する操作が可能になりました。

Webhookの作成

ようやくWebhookの作成に移れます。。。

Webhookの送信テストをするため以下のサイトを利用します。

https://webhook.site/

適当なURLが生成されるのでコピーしておきます。

  • Webhookのテスト送信先コピー

Box Cliで、Webhookを作成します。

  • Webhook作成コマンドを実行
$ box webhooks:create folder <folder_id> --triggers FILE.UPLOADED --address https://webhook.site/xxxxx

※ ターゲットURLは後ほど変更します。

ファイル操作のトリガーの一覧はこちらから確認できます。

それぞれのトリガーには設定できる対象(Folder/File)が決まっているので注意が必要です。自分はここでハマりました。

Webhookのテスト実行

ためしにBoxのフォルダーにファイルをアップロードしてみます。

  • ファイルアップロード

webの画面上で情報が確認できればOKです。

  • Webhook受信

これにてBox側の設定は終了です。

AWS側の設定

AWSリソースの作成

面倒なので、LambdaやAPI Gatewayなどのリソース作成は、Terraformを使って一括デプロイします。

内容はGitHubのリポジトリにすべてあげています。

フォルダー構成

.
├── src
│   └── lambda.py # Lambdaのソースコード
└── main.tf # Terraformの設定ファイル

ライブラリのインストール

$ pip install "boxsdk[jwt]" -t src/libs

Lambdaのソースコード

src/lambda.pyに記載します。

※長いのでコードはこちらにあげています。

Terraformの設定ファイル

main.tfに記載します。

※長いのでコードはこちらにあげています。

デプロイ

デプロイを実行しAWSで必要なリソースを一気に作成します。

terraform apply

Secrets Managerへクレデンシャル情報登録

AWSコンソールからSecrets Managerの設定画面に移ります。

  • AWS Secrets Manager

ダウンロード済みのconfig.jsonの中身をプレーンテキストで貼り付けます。 Webhookのプライマリキーも合わせて入力しておきます。

  • シークレット情報の入力

Box Webhookの送信先URLをAPI Gatewayに変更

作成されたAPI GatewayのURLを確認します。

  • API Gateway

さきほど登録したWebhookの送信先を更新します。

  • Box Cli
$ box webhooks:update <webhook_id> --triggers FILE.UPLOADED --address https://<api_id>.execute-api.ap-northeast-1.amazonaws.com/test/webhook

これにてAWS側の設定も終了です。

動作確認

Boxにファイルをアップロードして、最終的な動作確認をしてみます。

  • Boxに新しいバージョン(V2)でファイルをアップロード

  • S3側のファイル確認

まとめ

いかがだったでしょうか。

情報が少なく、Box側の設定でハマりましたがなんとか目的を達成することができました。

以上、どなたかの役に立てば幸いです。お疲れ様でした!