Watson Discovery と Boxを同期する

ほぼ下記資料の翻訳です。ただし、僕が検証できるのがBoxけなのでBox部分のみ。
わかりにくいところ以外はほぼGoogle翻訳です。

https://cloud.ibm.com/docs/services/discovery/connect.html#connectbox

#データソースへの接続について

データソースに接続し、必要に応じてそのソースに関連付けるコレクションを構成することで、スケジュールに従ってドキュメントをDiscoveryサービスに取り込むことができます。 各コレクションは1つのデータソースで設定できます。 Discoveryサービスは、クロールと呼ばれるプロセスを使用してデータソースからドキュメントを引き出します。 クロールは、指定された開始位置から体系的に文書を参照して検索するプロセスです。 明示的に指定されたアイテムのみがDiscoveryサービスによってクロールされます。 次の種類のデータソースをクロールできます。

- Box
- Salesforce
- Microsoft SharePoint Online
- Microsoft SharePoint 2016 On-Premise
- Web Crawl (beta)

**（お、ここで、ベータ版ながら「Webクロール」なんてのが出てきました。これについては別途検証します。）**

データソースへの接続は、DiscoveryツールまたはAPIを使用して実行できます。 Discoveryツールは、ソースシステムの理解をあまり必要としない単純化された接続方法を提供し、APIは、接続しているソースのより深い理解を必要とする、よりきめ細かく設定可能なインターフェースを提供します。次のプロセス概要を読むと、この文書のどの部分を次に読む必要があるかがわかります。

1. 何が必要になるかについての一般的な理解を得るために「 一般的なデータソースの要件」を読んでください。
1. ソースシステムに固有の要件を読んでください。
**（省略 Boxのみ）**
1. 選択した設定に基づいてソース設定手順を読みます。
    - ツールを使用
    - APIを使用
**（省略　今回かはツールのみ）**

オンプレミスのデータソースを選択した場合は、最初にIBM Secure Gatewayをインストールして構成する必要があります。詳しくは、オンプレミスデータ用のIBM Secure Gatewayのインストールを参照してください。

## 一般的なデータソースの要件
以下の一般的な要件がすべてのデータソースに適用されます。
- Box、Salesforce、SharePoint Online、およびSharePoint 2016の個々のドキュメントファイルのサイズ制限は10MBです。
- 各データソースの認証情報とファイルの場所（またはURL）が必要になります。これらは通常、データソースの開発者/システム管理者によって提供されます。
- クロールするデータソースのどのリソースかを知る必要があります。これはソース管理者によって提供されます。 BoxまたはSalesforceをクロールするときに、Discoveryツールを使用してソースを設定するときに使用可能なリソースのリストが表示されます。
- データソースをクロールすると、データソースのリソース（API呼び出し）が使用されます。呼び出し数は、クロールされたドキュメントの数によって異なります。データソースに対して適切なレベルのサービス（たとえば、Enterprise）を取得する必要があり、ソースシステム管理者に相談してください。
- 次の種類のファイルがDiscoveryによって取り込まれる可能性があります。その他の種類の文書はすべて無視されます。
    - Microsoft Word
    - PDF
    - HTML
    - JSON
- Discoveryのソースクロールでは、コレクションに格納されている文書は削除されません。ソースが再クロールされると、新しい文書が追加され、更新された文書は現在のバージョンに変更され、削除された文書は最後に保管されたバージョンのままになります。

## Box

IBM Watson™Discoveryに接続するには、新しいBoxカスタム・アプリケーションを作成する必要があります。作成したBoxアプリケーションには、エンタープライズレベルまたはアプリケーションレベルのアクセス権が必要です。

- 組織のBox管理者ではない場合は、アプリケーションレベルのアクセスをお勧めします。申請を承認するには管理者が必要です。
- あなたがあなたの組織のBox管理者であれば、エンタープライズレベルのアクセスが推奨されます。

注：Boxのアップデートがある場合は、Boxへのアクセスを設定する手順が変わることがあります。更新については、Boxの開発者向けドキュメントの外部リンクアイコンを参照してください。

### アプリケーションレベルのアクセス権を設定する
1. https://app.box.com/developers/console （会社のBox URLを使用）に移動して、[アプリの新規作成]をクリックします。<img width="1439" alt="スクリーンショット 2019-02-07 19.07.42.png" src="https://qiita-image-store.s3.amazonaws.com/0/45591/329c2435-1527-1976-9159-cb6fd9f1584d.png">
もしくは下の画面
<img width="1431" alt="スクリーンショット 2019-02-07 18.03.52.png" src="https://qiita-image-store.s3.amazonaws.com/0/45591/b45825ea-be2d-f7a6-6612-64a76aa92637.png">

1. [新しいアプリの作成]画面で、[企業統合]を選択して[次へ]をクリックします。**（この辺りBoxの日本語翻訳も怪しいですね。。。）**
<img width="1078" alt="スクリーンショット 2019-02-07 19.08.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/45591/3d4a25fe-05c4-fa72-d668-0145789362c2.png">
1. [認証方法]画面で、[JWTを使用したOAuth 2.0（サーバー認証）]を選択し、[次へ]をクリックします。
<img width="634" alt="スクリーンショット 2019-02-07 19.09.10.png" src="https://qiita-image-store.s3.amazonaws.com/0/45591/35d3abfb-12d7-4fb1-77c1-a12cc9bfc52b.png">
1. アプリに名前を付けて[アプリの作成]ボタンをクリックします。**（今回はWatsonDiscoverySourceという名前にしました）**Boxアプリが作成されたら、[アプリの表示]をクリックします。
<img width="824" alt="スクリーンショット 2019-02-07 19.09.30.png" src="https://qiita-image-store.s3.amazonaws.com/0/45591/00122098-627e-a237-7e0a-ec0726664c0a.png">
![名称未設定.png](https://qiita-image-store.s3.amazonaws.com/0/45591/dd53fcc9-8602-c3df-d8ed-e444e77bf7e1.png)
1. アプリを表示し、[構成]の[アプリケーションアクセス]で[アプリケーション]を選択します。既存の管理対象ユーザーを使用できます。新しいユーザーを作成する必要はありません。
1. ページの[アプリケーションスコープ]セクションまでスクロールし、以下のチェックボックスを有効にします。
    - Boxに格納されているすべてのファイルと フォルダの読み取りと書き込み
    - ユーザーを管理
<img width="1434" alt="スクリーンショット 2019-02-07 19.21.45.png" src="https://qiita-image-store.s3.amazonaws.com/0/45591/cfdc4601-cd2b-954d-1ca4-41e3f16f0a5d.png">
1. 「高度な機能」セクションまでスクロールして、以下の切り替えを有効にします。
    - ユーザーとして操作を実行する
    - ユーザーアクセストークンを生成
<img width="1434" alt="スクリーンショット 2019-02-07 19.26.43.png" src="https://qiita-image-store.s3.amazonaws.com/0/45591/595e3e9a-e2a8-a923-6e76-5b4ebff02c0d.png">
1. [変更を保存]ボタンをクリックしてください。
1. [Developerトークン]と[OAuth 2.0資格情報]の[クライアントID]をコピーしておきます。**（「クライアントID」は以下の手順で「APIキー」として使います）**
<img width="1421" alt="スクリーンショット 2019-02-07 19.50.55.png" src="https://qiita-image-store.s3.amazonaws.com/0/45591/650f5ffd-781d-510f-dcaa-2225d2bf1f8f.png">

次の数ステップはあなたの組織のBoxアカウントの管理者からの援助を必要とするでしょう。組織のBox管理者ではない場合は、Box開発者コンソールを開き、[アカウント設定]> [アカウントの詳細]> [設定]で確認して管理者を識別できます。**（個人用アカウントの場合は当然自分）**

1. [管理者手順] https://app.box.com/master/settings/openbox の[アプリ]（最初に選ばれているタブ）をスクロールし[カスタムアプリ]で、[新しいアプリの承認]ボタンをクリックしてアプリケーションクライアントIDを承認します。<img width="1360" alt="スクリーンショット 2019-02-07 19.34.52.png" src="https://qiita-image-store.s3.amazonaws.com/0/45591/40837a30-2186-8952-6ca8-745d85f5331f.png">
2.  [管理者ステップ] https://app.box.com/developers/console のクライアントIDを[APIキー]フィールドに入力し、[認証]ボタンをクリックしてください。
<img width="482" alt="スクリーンショット 2019-02-07 19.38.19.png" src="https://qiita-image-store.s3.amazonaws.com/0/45591/c5e0d45e-6a2a-fb16-4a30-8321e91e0560.png"><img width="499" alt="スクリーンショット 2019-02-07 19.38.28.png" src="https://qiita-image-store.s3.amazonaws.com/0/45591/da5ad637-61fc-12b3-2cbc-79ad3c7faf34.png">
3.  [管理者ステップ]アプリケーションのDeveloperトークンを取得します。これを行うには、 https://app.box.com/developers/console に移動し、「Developerトークン」セクションまでスクロールしてトークンを生成します。

4.  アプリケーションが管理者によって承認されたので、https://developer.box.com/reference#page-create-an-enterprise-user に移動し、APIリファレンスページを使用してApp Userを作成します。
*アプリユーザーを作成するCurlの例：*

```
curl https://api.box.com/2.0/users -H "Authorization:Bearer DEVELOPERTOKEN" -d '{"name": "Watson Discovery","is_platform_access_only":true}' -X POST
```
レスポンス

``` response
{"type":"user","id":"1234567890","name":"Watson Discovery","login":"AppUser_123456_hogehogehogehoge@boxdevedition.com","created_at":"2019-02-07T03:33:46-08:00","modified_at":"2019-02-07T03:33:46-08:00","language":"en","timezone":"America\/Los_Angeles","space_amount":10737418240,"space_used":0,"max_upload_size":2147483648,"status":"active","job_title":"","phone":"","address":"","avatar_url":"https:\/\/app.box.com\/api\/avatar\/large\/1234567890"}
```
***注意点 Box APIでのユーザー作成***
IBMのドキュメントや本家boxのAPIドキュメントの通りにコピペしてやると、Macのターミナルからは
"curl (6) could not resolve host " や ”Entity body should be a correctly nested resource attribute name\/value pair" などのエラーが返ってくることがある。ダブルクォーテーションがWeb表示用にエンコードされてしまっていたり、無駄なスペースが入っているから。上のスニペットは動作確認済み。複数回実行すると、複数ユーザーが作成されてしまうので注意。

5. 新しく生成されたidフィールドの内容をコピーして、BoxアプリケーションをIBM Watson™Discoveryに接続している非管理者にそれらを提供します。login の項目も必要です。

6. アプリユーザーが作成されたら、クロールするフォルダーをアプリユーザーと共有する必要があり、アプリユーザーにはそれらのフォルダーに対する閲覧者権限を付与する必要があります。これには、上記のcurlコマンド応答からのApp Userログイン名が必要です。例：
```
"login":"AppUser_737729_jmUo@boxdevedition.com"
```

Boxのフォルダを開いて、右側の[共有]たぶからコラボレータの追加をします。
<img width="276" alt="スクリーンショット 2019-02-07 20.41.03.png" src="https://qiita-image-store.s3.amazonaws.com/0/45591/a3950ca9-7c08-4f84-adbc-a319cc4ee29b.png">
<img width="461" alt="スクリーンショット 2019-02-07 20.38.12.png" src="https://qiita-image-store.s3.amazonaws.com/0/45591/32fd2c65-a3dd-2c6d-3fea-4b779b88d1e6.png">


7. Box開発者コンソール https://app.box.com/developers/console に戻り、[公開キーの追加と管理]セクションまでスクロールします。 [公開/秘密キーペアを生成]をクリックして、キーペアファイルをダウンロードします。ファイルを開きます。**（２段階認証が必要です。設定してあればSMSでの認証キーが送信されます。）**
<img width="1093" alt="スクリーンショット 2019-02-07 20.05.44.png" src="https://qiita-image-store.s3.amazonaws.com/0/45591/4ffc0a19-f7a8-548e-4a31-74d912d0c7aa.png">
<img width="580" alt="スクリーンショット 2019-02-07 20.23.50.png" src="https://qiita-image-store.s3.amazonaws.com/0/45591/d9861026-0986-497a-ea5c-8b225d2c0ed6.png">
<img width="436" alt="スクリーンショット 2019-02-07 20.27.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/45591/7aa082e8-5f3a-d096-d568-6a10bcf7b109.png">

8. キーペアファイル（json）から、以下のフィールドをDiscoveryツールにコピペします。
client_id 
enterprise_id
client_secret
public_key_id
private_key
passphrase

## エンタープライズレベルアクセス
省略　違うのはごく一部なので、元記事参考のこと

# Discovery Toolでの設定
（Discoveryサービスの作成までは省略）

[Connect a data source]を選択
<img width="1234" alt="スクリーンショット 2019-02-07 20.12.58.png" src="https://qiita-image-store.s3.amazonaws.com/0/45591/a0ffcacf-bb11-16fd-9fb7-75e498efc8fd.png">

Select a data source から [Box]を選択
<img width="684" alt="スクリーンショット 2019-02-07 20.13.20.png" src="https://qiita-image-store.s3.amazonaws.com/0/45591/493ff8ec-2475-24fb-d587-d1c3bfaa56ff.png">

client_id 
client_secret
enterprise_id
public_key_id
private_key
passphrase
をそれぞれ埋めて[Connect]
<img width="1154" alt="スクリーンショット 2019-02-07 20.13.44.png" src="https://qiita-image-store.s3.amazonaws.com/0/45591/790285ad-f451-9075-2a19-0f6eb9cae1a3.png">

ドキュメントの取得間隔と言語（お、おう、、、英語と日本語のドキュメント両方とかどないすねん、、、）対象のユーザーとフォルダーを指定すればオッケーです。
<img width="1357" alt="スクリーンショット 2019-02-07 21.04.06.png" src="https://qiita-image-store.s3.amazonaws.com/0/45591/21de2d6e-7ac7-c006-b23e-6971a246a97e.png">

~~と、、、ここまで書いておいてなんなんだけど、僕のboxアカウントではうまくいくんだけど、クライアント先のboxアカウントには同期できない。
取得間隔と言語設定する画面がしばらく表示された後に真っ白い画面にリダイレクトしちゃう。何がいけないのか？？~~

### 追記
#### [Failed to retrieve the instance resource. The account named acc_name has invalid or expired credentials.] でエラーになる場合
上記の２段階認証部分などを、招待した外部デベロッパーアカウントで作るとエラーになるので、オーナーの開発者アカウントで作成する

#### 白いページにリダイレクトする場合
box の管理者コンソールでアプリのユーザー数を確認すると0になっているか、どのフォルダもアプリユーザーで共有してないはずなので、アプリユーザーの作成を再度確認して、そのユーザーのアカウントを共有で招待する