Skip to main content
納税申告書、銀行取引明細書、給与明細書など、機密ドキュメントを読んで一日を過ごす場合、何度もコンテキストを切り替える必要があります。PDFをダウンロードし、それを別のビューアーで開いて、さらに別の場所でマークアップしてから、決定を記録するワークベンチに戻ります。切り替えのたびに、ドキュメントの漏えい、メモの紛失、アプリケーションの遅延が生じる可能性があります。 このチュートリアルでは、レビューの全工程が自分のアプリケーション内で完結します。
  1. ローンワークベンチがセキュアなアップロードAPIを通じて、各借入人ドキュメントをBoxにアップロードします。
  2. Boxが、アップロードされたドキュメントを忠実度の高いHTML5レンダリングに変換します。
  3. お客様のアプリが有効期間の短い埋め込みURLをリクエストして、<iframe>に挿入します。
審査担当者は、コンテキスト内でドキュメントを読んだり、ドキュメントに注釈を付けたりします。より充実した機能 (コンテキスト内でのマークアップ、メタデータとアクティビティのサイドバー、またはBox AI Q&A) が必要な場合は、Box内の基になるファイルにをレイヤーとして追加します。

作業用サンプルの複製

動作するコードで試してみたい場合は、このチュートリアルで作成するアプリの完成版がGitHubにあるので、それを複製し、Boxの資格情報を追加して実行してください。

構築する内容

このチュートリアルの最後には、次の機能を備えた実用的な統合ソリューションが完成します。
  • アップロードAPIを使用して借入人ドキュメントをBoxにアップロードし、プレビューのための自動変換をトリガーします。
  • アップロードしたファイルのために、有効期間の短い、有効期限付き埋め込みURLを生成します。
  • ワークベンチで<iframe>内のドキュメントをレンダリングします。
  • ファイルの範囲にダウンスコープされたトークンを発行し、ブラウザで保持される資格情報が常に最小権限になるようにします。
  • 素のiframeをBox Content Previewにアップグレードして、審査担当者がコンテキスト内で注釈を付けたり、より充実したレビューUIを使用したりできるようにします。

前提条件

始める前に、以下が揃っていることを確認してください。
  • 開発者コンソールへのアクセス権限とPlatformアプリを承認する管理者権限があるBoxアカウント (は使用可。コンシューマ/個人アカウントは使用不可)。オプションのBox AI Q&Aレイヤーを利用する場合は、有料のが必須です。
  • クライアント資格情報許可 (CCG) 認証とアプリケーションアクセスが [アプリアクセスのみ] に設定されている、。これにより、アプリのサービスアカウントが、アップロードされたすべてのドキュメントの所有者になります。
  • Python 3.11以上。
  • アプリで以下のスコープが有効になっていること。
    • Boxに格納されているすべてのファイルとフォルダの読み取りと書き込み
  • ワークベンチのフロントエンド (http://127.0.0.1:5000など) に使用する正確なオリジンを、CORS許可リストに追加します。これは、に必要な操作です。オリジンが許可リストに追加されるまでContent Previewは失敗し、403が返されます。
  • Box Enterprise ID (開発者コンソールにあるアカウントアイコンの [Enterprise IDをコピー] で取得できます)。
このチュートリアルでは、サービスアカウント (enterprise_id) としてのCCG認証を使用します。サービスアカウントはアップロードするファイルを所有するため、それらのファイルをプレビューするのにコラボレーションへの招待が必要ありません。これは、既存の企業コンテンツを扱う統合と比べた場合、大きな簡素化ポイントです。

仕組み

Box Viewのフローは次の3つの段階で構成されます。
  1. アップロード。バックエンドがセキュアなアップロードAPIを通じて借入人ドキュメントをBoxにアップロードします。コンテンツはウイルススキャンと256ビット暗号化が適用されて保存されます。
  2. 変換。アップロード時に、ファイルは明瞭かつレスポンシブにレンダリングされるHTML5互換のアセットへと自動的に変換されます。変換はファイルごとに1回実行され、アセットはファイルが保存されている限り保持されます。
  3. 埋め込み。バックエンドがファイルのexpiring_embed_linkをリクエストしてフロントエンドに返します。フロントエンドはそれを<iframe>に配置します。
このソリューションでは、以下に示す3つのBox Platform機能を使用します。
有効期限付き埋め込みリンクは約1分間有効で、生成後すぐに<iframe>に挿入するよう想定されています。有効期限付き埋め込みリンクは常に、審査担当者がドキュメントを開いたときにオンデマンドでサーバー側で生成するようにして、保存したり事前に送信したりしないでください。

手順

1

開発環境のセットアップ

  1. ターミナルを開き、新しいプロジェクトディレクトリを作成します。
  1. Pythonの仮想環境を作成してアクティブ化します。
アクティブ化すると、ターミナルのプロンプトの先頭に(.venv)と表示されます。これにより、仮想環境内で作業していることがわかります。
新しいターミナルウィンドウやタブを開くたびに、プロジェクトディレクトリからsource .venv/bin/activateを実行して、仮想環境を再アクティブ化する必要があります。コマンドの実行中にModuleNotFoundErrorが表示される場合、通常、venvがアクティブ化されていないことを意味します。
  1. 必要なパッケージをインストールします。
  1. 資格情報を保存するための.envファイルを作成し、以下の内容を追加します。プレースホルダの値を、Box開発者コンソールで確認した実際の資格情報で置き換えます。
LOAN_DOCS_FOLDER_IDはデフォルトでは、サービスアカウントのルートフォルダ0になっています。これは作業を開始するのに適しています。実際の環境では、専用のフォルダ (ローン申請ごとに1フォルダなど) を作成してそのIDを使用することで、ドキュメントが整理された状態に保たれます。
.envファイルはバージョン管理システムにコミットさせないでください。.env.gitignoreに追加します。
環境変数の理解: .envファイルには機密情報 (実際の資格情報) が保存されています。Pythonコードは、os.getenv("VARIABLE_NAME")を使用してこれらの名前を参照することで、その値を読み取ります。たとえばos.getenv("BOX_CLIENT_ID")を実行すると、.envファイル内のBOX_CLIENT_ID=の隣に保存されている値を検索します。以下の手順でコードをコピーする際は、引用符で囲まれた変数名をそのまま正確に保持してください。実際の資格情報に置き換えないでください。
2

Boxクライアントの認証

プロジェクトディレクトリにbox_client.pyという名前の新しいファイルを作成します。そのファイルを開き、以下のコードを貼り付けます。
アプリケーションのサービスアカウントがコンテンツを所有する、サーバー間のBox Viewユースケースでは、クライアント資格情報許可をお勧めします。その他の認証オプションについては、を参照してください。
3

借入人ドキュメントのアップロード

upload.pyという新しいファイルを作成します。次の関数は、ドキュメントをローンドキュメント用フォルダにアップロードし、新しいファイルIDを返します。ドキュメントをアップロードすると自動的に変換がトリガーされるため、少しするとファイルのプレビュー準備が整います。
ほとんどのタイプのドキュメントと画像で、変換はアップロード時に自動的にトリガーされます。動画と3Dファイルの場合、変換は最初のプレビュー時にトリガーされます。いずれにしても、変換はファイルごとに1回のみ実行され、コードで明示的な操作を行う必要はありません。
4

プレビュー用埋め込みURLの生成

preview.pyという新しいファイルを作成します。get_embed_url関数は、Boxにファイルのexpiring_embed_linkを要求し、フロントエンドによって<iframe>に配置されるURLを返します。
expiring_embed_linkは、fieldsパラメータを通じてのみリクエストし、すぐに使用してください。リンクは、埋め込みの安全性を確保するために、約1分で有効期限が切れるよう設計されています。
5

ブラウザ用にダウンスコープされたトークンの発行

素のiframeにはトークンは必要ありません。しかし、Box Content Preview (後で追加) はブラウザで実行されるため、トークンが必要です。フル権限のサービスアカウントトークンをダウンスコープされたファイルスコープのトークンに交換する関数をpreview.pyに追加します。このトークンは、1つのファイルに対してスコープで許可されている操作のみを実行でき、ブラウザに安心して送信できるように有効期間が短く設定されています。
スコープはレビュー機能に直接マッピングされます。
クライアントシークレットまたはアクセストークン全体をクライアント側のコードで公開しないようにしてください。トークンは、ブラウザに送信する前に常にダウンスコープします。詳しくは、を参照してください。
6

バックエンドのエンドポイントの公開

app.pyという新しいファイルを作成します。このFlaskアプリケーションは、ローンワークベンチによって呼び出されるバックエンドです。ドキュメントをアップロードするエンドポイント、オンデマンドで新しい埋め込みURLを取得するエンドポイント、ダウンスコープされたトークンを発行するエンドポイントをそれぞれ1つ公開します。
/embedエンドポイントは、リクエストが行われるたびにリンクを新しく作成します。リンクは約1分で有効期限が切れるため、フロントエンドは、このエンドポイントを事前に呼び出すのではなく、審査担当者がドキュメントを開いた瞬間に呼び出す必要があります。
ルートを追加または変更するたびにFlaskを再起動してください。Flaskは起動時に1回コードを読み込むため、新しく追加されたルート (/review/<file_id>など) は、Ctrl+Cでサーバーを停止してpython app.pyを再度実行するまで404 Not Foundを返します。debug=Trueを設定すると自動再読み込みが有効になるため、以降の編集は自動的に再読み込みされます。ただし、ルート追加直後の実行は、手動で再起動する必要があります。debug=Trueは、実稼働環境では使用しないでください。
/review/<file_id>ルートがバックエンドと同じオリジンからレビューページを提供するため、ページの相対的なfetch("/api/...")コールはAPIに届きます。review.htmlをダブルクリックで開くことはしないでください。これをfile://プロトコル経由で開くと、相対的なfetchには呼び出すサーバーがなく、iframe srcは設定されず、ページのヘッダーのみが表示されることになります。review.htmlは次の手順で作成します。
この時点でプロジェクトディレクトリには、以下のファイルが含まれていることになります。
7

iframeでのドキュメントのレンダリング

バックエンドが準備できたら、フロントエンドは簡単です。埋め込みURLを取得して、それを<iframe>srcとして設定します。これは安全なアプリ内レビューインターフェースであり、審査担当者はワークベンチを離れずに済みます。review.htmlというファイルをプロジェクトのルートに作成します (app.pyの隣に配置することで、/review/<file_id>ルートから提供できます)。ファイルIDはページが自らのURLパスから読み取るため、ハードコーディングは不要です。
このページには、常にhttp://127.0.0.1:5000/review/<file_id>のバックエンド経由でアクセスしてください。review.htmlをダブルクリックしてアクセスしないでください。ダブルクリックしたファイルはfile://によって開かれます。この場合、相対的なfetch("/api/...")には到達できるサーバーがありません。さらに、iframe srcは設定されず、ヘッダーのみが表示されることになります。このページとAPIはオリジンが共通している必要があります。
実稼働環境では、ワークベンチアプリとBox向けバックエンドが通常、同じゲートウェイ (同じオリジン) の背後で動作するか、/api/*がバックエンドにプロキシされるため、こうした相対的なfetchコールは解決されます。
8

アップロードおよび埋め込みフローのテスト

パイプライン全体をUIへの接続前にコマンドラインから実行できます。
コマンドを実行する前に、loan-reviewディレクトリを開いていること、また、仮想環境がアクティブ化されていることを確認します。
1. バックエンドを開始します。
Running on http://127.0.0.1:5000と表示されます。このターミナルは起動したままにしておきます。2. ドキュメントをアップロードします。2つ目のターミナルで、サンプルの納税申告書または明細書 (任意のPDFでかまいません) をアップロードします。
ファイルIDが返されます。
3. このファイルIDの埋め込みURLを取得します。
4. この埋め込みURLをiframeで表示します。バックエンドがまだ実行されているので、ファイルIDを最後のパス部分として使用し、サーバーを通じてレビューページを開きます。
ドキュメントがiframe内でレンダリングされます。Loan application 4815ヘッダーのみが表示される場合は、review.htmlをダブルクリック (file://プロトコル) で開いていると考えられます。代わりに、上記のURL経由で開いてください。別の健全性チェックとして、手順3の埋め込みURLを1分以内にブラウザに直接貼り付けるという方法もあります。これを行うと、ドキュメントがレンダリングされ、変換が成功したことが証明されます。

トラブルシューティング

仮想環境がアクティブ化されていません。pythonコマンドを実行する前に、プロジェクトディレクトリからsource .venv/bin/activateを実行してください。新しく開いたターミナルタブは、すべて個別にアクティブ化する必要があります。
以下のように、.envファイルを確認します。
  • BOX_CLIENT_IDおよびBOX_CLIENT_SECRETが、開発者コンソール > 自分のアプリ > [構成] の値と一致していることを確認します。
  • BOX_ENTERPRISE_IDが自分のEnterprise IDであることを確認します (開発者コンソール > アカウントアイコン > [Enterprise IDをコピー])。
  • アプリの種類がクライアント資格情報許可であり、アプリが承認済みであることを確認します。
アプリがまだ管理者によって承認されていません。開発者コンソールで、[承認] タブを開いて [確認して送信] をクリックし、Box管理者に管理コンソールでアプリを承認してもらいます。詳しくは、を参照してください。
Flaskに/review/<file_id>ルートが登録されていません。これはほとんどの場合、ルートは追加したのにサーバーを再起動しなかったことが理由です。Flaskは起動時に1回コードを読み込みます。Ctrl+Cでサーバーを停止して、python app.pyを再度実行してください。さらに、send_fileがインポートされていること (from flask import Flask, request, jsonify, send_file)、また、app.pyにルートが存在することを確認してください。debug=Trueを設定して実行すると、以降の編集に対して自動再読み込みが有効になります。
review.htmlをバックエンド経由ではなく直接 (file://プロトコルを介して) 開いています。ページの相対的なfetch("/api/documents/.../embed")コールは、ページがAPIと同じオリジンから提供されている場合にのみ機能します。ファイルをダブルクリックするのではなく、バックエンドを起動してhttp://127.0.0.1:5000/review/<file_id>を開きます。ブラウザの開発者コンソールを開いて確認してください。失敗したfetchリクエストが表示されるはずです。
埋め込みリンクの有効期限が切れています。埋め込みリンクは約1分持続します。このリンクはiframe srcを設定する直前に生成し、審査担当者がドキュメントを開くたびに新しいものをリクエストしてください。
これは、CORS許可リストの問題である場合がほとんどです。iframeレビューページは、BoxでホストされているURLを読み込み、オリジンからBox APIを呼び出すことがないため、CORSなしで機能します。ただし、Box Content Previewは、ブラウザから直接api.box.comを呼び出します。開発者コンソールでは、繰り返されるGET https://api.box.com/2.0/files/<id>?fields=...リクエストがpreview.jsを返し、403からスローされる様子を確認できます。次の手順で修正してください。
  • ページを開くときに使用する正確なオリジンを、http://127.0.0.1:5000などのスキームやポートも含めてCORS許可リスト (開発者コンソール > アプリ名 > [構成] > [CORSドメイン]) に追加します。なお、127.0.0.1localhostは異なるオリジンであり、どちらか使用する方を追加します。保存して1~2分待ち、再起動と再読み込みを行います。
  • それでも403する場合、ダウンスコープされたトークンの権限が不足しています。[すべてのファイルとフォルダの読み取りと書き込み] スコープを有効にしてあり、その後に管理コンソールでアプリを再承認したことを確認します。
  • /annotate/<file_id> URL内のファイルIDが、トークンの発行対象となったファイルと一致していることを確認します。トークンは単一のファイルにダウンスコープされているため、IDの不一致でも403が返されます。

Box Content Previewを使用したコンテキスト内注釈の追加

iframeの埋め込みは、迅速な読み取り専用レビューに最適です。納税申告書上の疑わしい数字のハイライトや、署名漏れを指摘するコメントの追加など、審査担当者がコンテキスト内でドキュメントをマークアップできるようにするには、素のiframeの代わりに、 UI Elementを使用して同じファイルをレンダリングします。コンテンツプレビューはBoxウェブアプリ内でのレビューを担い、クライアント側のみで動作するため、注釈はワークベンチ内に留まります。 ブラウザでコンテンツプレビューを使用するにはトークンが必要です。ダウンスコープされたファイルスコープのトークン (注釈用のスコープを備えたもの) を返す/tokenエンドポイントをすでに作成したため、フロントエンドにフル権限の資格情報が表示されることはありません。
この手順を行う場合、使用するオリジンを事前にCORS許可リストに追加しておく必要があります。 Box Content Previewは、ブラウザからapi.box.comに直接API呼び出しを行います。Boxは、ページのオリジンがアプリのCORS許可リスト (開発者コンソール > アプリ名 > [構成] > [CORSドメイン]) に含まれていない限り、その呼び出しを拒否し、403 (Forbidden)を返します。ページを開くときに使用する正確なオリジンを、http://127.0.0.1:5000などのスキームやポートも含めて追加します。http://127.0.0.1:5000http://localhost:5000異なるオリジンであることに注意してください。実際に参照する方のオリジン (または両方のオリジン) を許可リストに追加します。変更が反映されるまで、1~2分かかります。
annotate.htmlというファイルをプロジェクトのルートに作成し、iframeページと同様にAPIと同じオリジンからそのファイルを提供するルートをapp.pyに追加します。
iframeページを開いたときと同様、ファイルをダブルクリックではなくバックエンド (http://127.0.0.1:5000/annotate/<file_id>) を通じて開きます。 showAnnotationstrueに設定されていて、トークンが注釈用のスコープを備えている場合は、審査担当者にプレビューヘッダーの注釈コントロールが表示されます。注釈はBoxのファイルに対して保存されるため、2人目の審査担当者が同じドキュメントを開くと、1人目の審査担当者のメモが表示されます (annotation_view_allが付与されているため)。
Boxの注釈では、コメントのハイライトハイライトのみ描画ポイントという注釈の種類がサポートされています。ポイント注釈はドキュメントと画像の両方で機能し、ハイライトおよび描画による注釈はドキュメントのみで機能します。また、ハイライトによる注釈の場合は、テキストレイヤーを使用可能にするためにitem_downloadスコープも必要です。詳細なマトリックスや、リアルタイムのV4注釈を有効にする方法については、を参照してください。
許可リストにオリジンを追加した後もプレビューで403が返される場合は、ダウンスコープされたトークンの権限が不足しています。確実にアプリで [すべてのファイルとフォルダの読み取りと書き込み] スコープを有効に設定し、有効にした後で管理コンソールでアプリを再承認してください。CCGスコープの変更は、アプリが再承認されるまで反映されません。に関するガイドを参照してください。

レビューUIを充実させるレイヤーの追加

Box Content Previewを実行すると、同一のファイルでレビュー機能を段階的に充実させることができます。その際、ドキュメントを再アップロードしたり、2つ目のコピーを作成したりする必要はありません。
コンテンツプレビューUI Elementのサイドバーを使用して、ドキュメントと一緒にファイルの詳細、バージョン、アクティビティフィードを表示します。これにより、複数の審査担当者がドキュメントの履歴を確認して、ページを離れることなくそのドキュメントについて議論することができます。アクティビティフィードとドキュメントビューでともに注釈を有効にして、接続されたレビューワークフローを実現します。詳しくは、を参照してください。
Box AI for UI Elementsを使用すると、コンテンツプレビューのヘッダーにドキュメントのQ&Aと要約を直接追加できます。審査担当者が「借入人が報告した年収はいくらですか?」と質問すると、ドキュメントに基づいて引用された回答が得られます。hasHeader: truecontentAnswersPropspreview.show()に渡します。詳しくは、を参照してください。
ローン申請のファイルが1つであることはまれです。ファイルIDのcollectionpreview.show()に渡すと、審査担当者は、単一のプレビューアー内でナビゲーション用の矢印を使用して納税申告書、W-2、銀行取引明細書を閲覧できます。
コレクション内の各ファイルをカバーするリソースとスコープを備えた、ダウンスコープされたトークンを発行します。
トークンのスコープは審査担当者のロールに合わせます。たとえば、下級の審査担当者にはbase_preview + annotation_view_self + annotation_edit (自分のメモのみ閲覧可能) を付与し、上級の融資審査担当者にはannotation_view_allを付与します。決定が確定した後は、編集スコープを削除して、効果的にドキュメントを読み取り専用にします。詳しくは、を参照してください。

本番環境へのスケーリング

すべてをサービスアカウントのルートにアップロードするのではなく、ローン申請ごとにフォルダを作成して、そのIDをアップロードの親として渡します。これにより、ドキュメントがグループ化され、クリーンアップが簡単になるうえに、コンプライアンス対応のためのをフォルダレベルで適用できます。
埋め込みリンクは約1分で有効期限が切れ、ダウンスコープされたトークンも有効期間が短く設定されています。どちらも必要になった時点でサーバー側で生成してください。コンテンツプレビューでは、静的な文字列ではなくを渡します。それにより、プレビューアーは必要になるたびに新しいトークンを取得できます。
クライアントシークレット、Enterprise ID、およびアクセストークン全体がブラウザに公開されることがあってはなりません。これらは環境変数かシークレットマネージャに保存し、[アプリケーションアクセス] を [アプリアクセスのみ] に設定したままにして、CORS許可リストをBox Content Previewの実行ドメインに厳密に制限します。詳しくは、を参照してください。
を使用すると、すべてのローンドキュメントを横断して、プレビュー、ダウンロード、注釈アクティビティを追跡できます。これにより、コンプライアンス部門はレビューの担当者、内容、時期についての監査証跡を利用できるようになり、ユーザー向けアプリに追跡機能を組み込まなくて済みます。

次の手順

請求書の取り込み自動化

Box AI Extractとメタデータを活用して、買掛金処理を自動化します。

Box Viewの概要

アップロード、変換、埋め込みが連携する仕組みについて説明します。
最終更新日 2026年7月21日