Scala番外編「Boxに保存したファイルをBox APIを使ってダウンロードしよう!」


はじめに

みなさんこんにちは、プロダクト開発本部の亀梨です。
普段はXmediaOneというメディアプランニング・広告運用管理・トラッキング・マーケティング分析を行う
統合プラットフォームの開発を担当しています。

Box APIを使う背景・目的

DACはメディアレップです

メディアレップとは、インターネット広告の取引において、広告媒体サイトと広告会社の仲介を行っている事業者のことです。
DACでは数多くの媒体のインターネット広告メニューを取り扱っており、広告媒体サイトから広告枠を、同じく広告会社から広告出稿の案件を預かり、両者にとって最適な条件となるようにマッチングさせる役割を担っています。
DAC AD GUIDE

Boxについて

DACでは各広告媒体のメニュー詳細情報や料金、広告素材を入稿する際の規定等を記した資料(以下、媒体資料)を用意しています。
広告代理店担当者様やDACのプランナーが出稿する広告メニューを検討する際に使います。

この媒体資料はDAC社内で「Box」というファイル共有サービスに格納・管理しています。
Box – セキュアなファイル共有、ストレージ、コラボレーション

Box APIについて

Boxは外部サービスとの連携ができるようにするAPIを提供しています。
Box Developer Portal

XmediaOneでのBox APIの利用

XmediaOneは広告代理店担当者様やDACのプランナーがどの媒体に広告を出稿するかをプランニングする機能となっており、
その中でDACが保有している媒体資料を社内外に広く公開するために、Box APIを使って資料をダウンロードできる仕組みを構築しました。
今回はXmediaOneとBoxAPIを連携させる事例を紹介したいと思います。

前提

XmediaOneはScala言語で開発しています。そしてビルドツールはsbtを使っています。
また今回Box APIを利用するにあたってはBoxが提供しているJavaのSDKを使います(詳しくは後述)。

開発環境

  • Scala 2.11.8
  • sbt 0.13.13
  • Box Java SDK 2.24.0

試したこと

Boxの事前設定

管理者アカウントで管理コンソールにログインし、API用のユーザーアカウント(以下、閲覧ユーザー)を作成

APIにリクエストを投げる際に必要なユーザーアカウントを作成します。
詳細はこちらより確認してください。

Boxのファイル閲覧画面にログインし、ダウンロードしたい対象のファイルを格納しているディレクトリに閲覧ユーザーをコラボレータとして追加

閲覧ユーザーでBoxの開発者コンソールを開き、必要な設定を行う

1. Boxにログインした状態で、Developerコンソールを開く
開発者コンソールのURLは https://xxxxx.ent.box.com/developers/console →xxxxxの部分が会社ごとに違う

2. アプリを新規作成する
外部システム(今回で言うXmediaOne)とBox APIを連携させるために、Boxでは連携用の”アプリ”を作成する必要があります。
↑の画面中央の「アプリの新規作成」をクリックし新しいBoxアプリを作成する画面に移ります。
そして次の画面で、アプリの種別を選択します。今回のケースのように既にあるBoxのファイルに対してAPI経由で操作を行う場合は
「企業統合」を選択して「次へ」ボタンをクリックします。

3. 認証方法を選択する
今回のように既存のプラットフォーム内のサーバー上でAPIの認証・リクエストを行う場合には、
「JWTを使用したOAuth 2.0 (サーバー認証)」を選択します。

4. アプリの作成完了
アプリの作成が完了すると以下の画面になりますので、中央にある「アプリの表示」ボタンをクリックします。

5. アプリの「構成」ページで必要な設定を行う
以下の画面よりファイルダウンロードができるようにするための設定を行います。

詳細は公式ドキュメントの「JWTアプリケーションの設定」に記載がありますが、正直これ分かりづらいです^^;
なのでかいつまんでご説明します。ファイルダウンロードをするのに変更が必要な項目としては、

  • アプリケーションアクセス
    • Enterpriseを選択
  • アプリケーションスコープ→ファイルダウンロードに必要な最小スコープとして以下にチェックを付ける
      • Boxに格納されているすべてのファイルとフォルダの読み取り
      • Boxに格納されているすべてのファイルとフォルダの読み取りと書き込み
      • ユーザーを管理
  • 高度な機能
    • ユーザーとして操作を実行 をOnにする
    • ユーザーアクセストークンを生成 をOnにする

ここまでの設定を行ったら、画面右上の「変更を保存」ボタンをクリックします。
そして次に、「公開キーの追加と管理」項目の「公開/秘密キーペアを生成」をクリックします。

すると、上記で設定した構成を反映したJSONファイルがダウンロードされます。
このJSONファイルにはAPIを使うのに必要なユーザー情報や秘密キーが保存されています。再ダウンロードができないため、慎重に扱ってください。

ここまでで開発者コンソールでの設定は完了です。

管理コンソールで作成したアプリの登録、承認を行う

管理者アカウントで管理コンソールにアクセスし、以下の手順を使用して、アプリケーションへのアクセス権限を付与します。

  1. 管理コンソールのBusiness設定を開きます。
  2. ページ上部のナビゲーションの[アプリ]リンクをクリックします。
  3. [カスタムアプリケーション]セクションまで下にスクロールし、[新しいアプリケーションを承認**]ボタンをクリックします。
  4. APIキーを求められたら、最初の手順で作成したJWTアプリケーションのクライアントIDを入力します。

クライアントIDは先ほどの開発者コンソールのアプリの構成ページ内「OAuth 2.0資格情報」にあるクライアントIDです。

Scalaでのダウンロード処理の実装

はい、ちょっと事前設定の説明が長くなってしまいましたが、ようやく実装に入ります。

SDKのインストール

先にも書きましたが、Boxは複数の言語でSDKを提供しています。今回はScalaでの実装となるため、
Javaで提供されているライブラリ「Box Java SDK」を使用します。
Box Java SDK


build.sbtに以下の様に依存関係を記載して利用します。

Scalaの実装コード

Box APIにアクセスする手順としては

  1. 作成したアプリの構成を設定ファイルから読み込み
  2. 構成を元にAPIの操作を行うためのオブジェクトを作成
  3. ファイルを操作するAPIアクセスを実行

となります。まずは実装コードの全体を見ていきましょう。

では手順ごとにコードを細かく見ていきましょう。

手順1: 構成の出力
先ほど事前設定でダウンロードしたファイルをプロジェクト内の任意の場所に格納しておきます。
そしてそのファイルに記載されたアプリケーションの情報やプライベートキーの構成オブジェクトを作成します。

手順2: 新規Box SDKクライアントの作成
このクライアントを使うとBox内のファイルに呼び出しができます。

上記のユーザーIDは閲覧ユーザのIDで、事前設定で作成したアプリの開発者コンソールで確認することができます。
XmediaOneでは事前にファイルIDを登録する機能を作っており、そのファイルをJSONでAPIにGETリクエストする形をとっています。

手順3: ファイルのダウンロード
いよいよファイルのダウンロードです。
ダウンロードするにはファイルのIDが必要になります。開発者コンソールではなく通常のBoxページでダウンロードしたいファイルIDを確認します。


はい、実装コードは以下となります。

はい、以上が実装コードとなります。ちなみにBox APIでの様々な操作の具体的な実装方法についてはGitHubのページに詳しく掲載されています。

これでファイルがダウンロードできましたーめでたしめでたしー。。。

エラーの解消

と思いきや、このBox APIの実装には解消しなければいけないエラーがあります。
上記のコードを実行すると、

というエラーに遭遇します。これはJavaのセキュリティポリシーを更新しなければいけないということらしいです。
手順としては、

  1. オラクルのWebサイトより必要なファイル US_export_policy.jar と local_policy.jar をダウンロード
  2. ダウンロードしたファイルを、アプリケーションサーバーにインストールしてあるJavaの該当パス (JAVA_HOME)/jre/lib/security にコピー(上書き)

となります。これを行うことでエラーが解消され正常にAPIでファイル操作が可能となります。
このエラー解消にはこちらの記事が参考になりました。

まとめ

今回はBox APIという外部APIを使うにあたり、認証に関する事前設定・動作検証に多くの時間を費やしました。
実装コード自体は単純なのですが、このAPIは公式のドキュメントの文章が翻訳のせいなのか少々難解で読み解くのに非常に苦労しました。
なおBoxでは開発者フォーラム(英語)があり、なにか不明点が出た際はこちらに質問を投げるとBoxの中の人が1営業日程度で回答を返してくれます。割と親切です。

今回の教訓としては、「外部APIと連携させる場合は事前に入念な動作検証をしておけ!」です。
APIだからといって安易に導入すると苦労するぞということを学びましたw。

はい、ということで少し長くなりましたが、Box APIを使ってBoxファイルをダウンロードする方法を紹介させていただきました。
またなにか面白い事例等がありましたらこの場で共有させていただきます。それではー。


DACエンジニア採用情報

  関連記事

SDKってどうやって作ってるの?【Android編】

こんにちは。4度目の投稿です。 現在私はAndroidのSDKを開発しています。 javaにもAndroidにもSDKにも手を出したのは初めてなので、最初はそもそもSDKのイメージが湧かず、ふわふわした状態で始めました。 SDKと調べても「あるソフトウェアを開発するために必要なプログラムや文書などを …

TypeScriptについてまとめてみた

はじめに JavaScript がとりあえずそのまま動くので、雰囲気で使ってしまいがちな TypeScript。初心者向けに基本的なことをまとめてみました。 TypeScript って何? TypeScript はマイクロソフトが開発したプログラミング言語で、オープンソースでメンテナンスされています …

【小ネタ】JSで要素の組み合わせを列挙する

下記のような、キーの数や要素数が可変のデータの組み合わせを、列挙するjavascriptコードです。 pythonにはitertoolなどの順列・組み合わせ計算を行う定番ライブラリがあるようです。 やっている事ですが、イメージとしては組み合わせを数列に置き換えています。 1桁目が2進数、3桁目が3進 …

【未経験からのRuby on Rails – 第3回】変数と定数

こんにちは。新卒1年目のmatsuariです。 今回はRubyに限らずプログラミングを学ぶ上で非常に重要となる「変数と定数」について、ご紹介していきます。 変数とは・・・ オブジェクトを一時的に格納しておく箱で、オブジェクトを識別するために利用します。 言葉だけでは理解が難しいかと思いますので、まず …

Qiita Team API と Google Spread Sheet でチーム日報を生成する

チーム日報を活用する MarketOne 開発チームでは複数拠点に分かれての開発を行っています。リモート開発が中心となると口頭でのコミュニケーションに限界があるため、テキストベースのコミュニケーションの比重が高い状態にあります。 チケットシステムやソースコード管理ツール上の議論はもちろんおこなってい …

D3.jsとその活用事例について

D3.jsとは? D3とは「Data Driven Document」の略で、データに基づいてドキュメントを操作するための JavaScript ライブラリです。 ご存知の方も多いと思いますが、ちょっとだけD3.jsの基本的な使い方、そして弊社プラットフォームでの利用についてご紹介したいと思います。 …

no image
Angular.jsのvalueとfactoryの違いを考える

次のようなHTMLがあったとする。 [code language=”html”] <!doctype html> <html lang="jp" ng-app="App"> <head> <me …

Vagrantの機能を使って開発環境の効率をあげてみた。

プラットフォーム・ワンのシステムの運用・保守担当のエンジニアです。 保守の仕事に関わると、 ユーザからのお問い合わせだったり、監視アラートによる検知から システムを調査することがあります。 ログとソースコードを見て、不具合を特定し改修する。 すぐできればカッコいいですが、 「本番環境に反映して別のエ …

x-callback-urlを使ってみた

x-callback-urlとは? iOSのアプリ間連携の仕様の一つみたいです。簡単に言うと、ディープリンクを行うためにカスタムURLスキームを利用するが、アプリ毎にバラバラな規則でURLスキームを設定するとアプリ間連携をスムーズに行うことができないため、どのような規則でURLスキームを設定するかを …

fastavroとjqでAVRO形式のファイルからデータを取得しよう

AVRO形式のファイルを取り扱いたい AVROとはApacheプロジェクトのひとつとして開発されているデータ交換形式です。 コンパクトなバイナリで高速なシリアライズ・デシリアライズが行えるため、サーバーログなどに利用されています。 弊社内での一部システムのログデータにも利用されているのですが、専用の …