🔄

boxのリンクをGoogleドライブのリンクに変換する方法

2024/06/05に公開

boxからGoogleドライブへ移行をした際にNotionにまとめていたファイルのリンクを置き換える必要があり、APIを使って変換した話
めったにやらないでしょうが、APIの使い方が勉強になったのでまとめます

なおスピード重視だったのでプログラムにしたのは必要最低限で手作業の部分が多いです

処理の流れ

Notionに張られていたのはhttps://app.box.com/s/xxxxxxxという形式の共有リンクだった
これを一度フォルダ・ファイル名に変換し
移行先の共有ドライブ内でフォルダ・ファイル名で検索し
Googleドライブのリンクを生成する

Box API

アクセストークンの生成

このチュートリアルを使います
https://ja.developer.box.com/guides/tooling/postman/quick-start/

手順に従っていくとBoxのAPI仕様を理解せずともAPIコールに必要なアクセストークンが取得できます

Boxの共有リンクをファイルパスに変換する

「共有リンクのウェブリンクを検索」APIを使います
https://ja.developer.box.com/reference/get-shared-items--web-links/

知っておくべきAPI仕様はこれだけです

メソッド URL ヘッダー(boxapi) ヘッダー(Authorization)
GET https://api.box.com/2.0/shared_items shared_link=[link] Bearer [アクセストークン]

他のAPIについてはAPIリファレンスから探すのが正攻法だと思いますが
私は先のチュートリアルで生成したPostmannプロジェクトでそれらしいリクエストを実際に送って確認しました
(Boxをあまり使ったことがなく「共有リンク」や「ウェブリンク」などの言葉がわからずリファレンスから探よりこっちが速かった)

この仕様をもとにURLをファイルパスに変換する簡単なスクリプトを実装

box.js
/**
 * Boxの共有リンクをファイルパスに変換する
 *
 * 環境変数
 * BOX_TOKEN
 */

import axios from 'axios';

const sharedLinks = [
  // ここにURLをハードコーディング
];

for (const sharedLink of sharedLinks) {
  if (!sharedLink) {
    console.log('');
    continue;
  }
  try {
    const result = await axios.request({
      method: 'get',
      maxBodyLength: Infinity,
      url: 'https://api.box.com/2.0/shared_items',
      headers: {
        boxapi: `shared_link=${sharedLink}`,
        Authorization: `Bearer ${process.env.BOX_TOKEN}`,
      },
    });
    console.log(result.data.name);
  } catch (error) {
    console.log('error');
  }
}

これでコンソールには大量のファイルパスが出力される
URLとファイルパスの対応表を適当な表計算ソフトでまとめておきます

BoxのURL ファイルパス
https://app.box.com/s/xxxxxxx path/to/file

Google Drive API

パスが分かったのでこれをもとにGoogleドライブのURLを生成していきます

OAuthの仕組み

残念ながらBoxのようなチュートリアルはGoogleになかったので手動でアクセストークンを発行します
これに当たって簡単にOAuthによる認証フローをおさらい

参考

アクセストークンの生成

  1. Google CloudのコンソールでGoogle Drive APIを有効化します
  2. OAuth 同意画面を作成します
    • 承認済みドメインは適当にexample.comとしておきます
    • スコープにdrive.metadata.readonlyを追加します
  3. OAuthクライアントIDを作成します
    • アプリケーションの種類はウェブアプリケーションを選択
    • 承認済みのリダイレクトURIにhttps://oauth2.example.com/codeを指定
    • ここで作ったクライアントのIDとシークレットを以降使用します
  4. 以下のURLをブラウザのアドレスバーに打ち込んでアクセス
リクエストURL
https://accounts.google.com/o/oauth2/v2/auth
  ?scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly
  &access_type=offline
  &include_granted_scopes=true
  &response_type=code
  &state=state_parameter_passthrough_value
  &redirect_uri=https%3A//oauth2.example.com/code
  &client_id=[クライアントID]
  1. Googleにアクセス許可を与えていいか聞かれるので許可
  2. ブラウザのアドレスバーが以下のようなURLになる(はず)
リダイレクト先URL
https://oauth2.example.com/code
  ?state=state_parameter_passthrough_value
  &code=[認証コード]
  &scope=[許可されたスコープ]
  1. Postmanを使って認証コードをアクセストークンと交換

POST https://oauth2.googleapis.com/token

bodyはx-www-form-urlencodedで

Key Value
code 認証コード
client_id クライアントID
client_secret クライアントシークレット
redirect_uri https://oauth2.example.com/code
grant_type authorization_code

パスをもとにファイルを検索する

以下のAPIを利用しました
https://developers.google.com/drive/api/reference/rest/v3/files/list?hl=ja

パスをもとにフォルダ階層を探していってもよかったんですが
実装がめんどくさかったのでファイル名で検索しています
(後でこれが役に立ちます)
このために表計算ソフトでファイル名を抜いてきます

BoxのURL ファイルパス ファイル名
https://app.box.com/s/xxxxxxx path/to/file =SUBSTITUTE(RIGHT(SUBSTITUTE(B2,"/",REPT("/",256)),256),"/","")

そして以下のコードでファイルのIDを列挙します
DRIVE_IDには共有ドライブのIDを指定します
このIDはdrives.list APIで確認できます

drive.js
/**
 * ファイルパスからGoogle DriveのファイルIDを検索する
 *
 * 環境変数
 * DRIVE_ID
 * DRIVE_TOKEN
 */

import axios from 'axios';

const filenames = [
  // ここにファイル名をハードコーディング
];

for (const filename of filenames) {
  if (!filename) {
    console.log('');
    continue;
  }
  try {
    const result = await axios.request({
      method: 'get',
      maxBodyLength: Infinity,
      headers: {
        Authorization: `Bearer ${process.env.DRIVE_TOKEN}`,
      },
      url:
        `https://www.googleapis.com/drive/v3/files` +
        `?driveId=${process.env.DRIVE_ID}` +
        `&corpora=drive` +
        `&includeItemsFromAllDrives=true` +
        `&includeTeamDriveItems=true` +
        `&supportsAllDrives=true` +
        `&q=${encodeURIComponent(`name ='${filename}' and trashed = false`)}`,
    });
    console.log(result.data.files.map((e) => e.id).join(','));
  } catch (error) {
    console.log('error');
  }
}

GoogleドライブのURLは以下のフォーマットなので表計算ソフトでURLに変換します
https://drive.google.com/file/d/[ファイルID]

BoxのURL ファイルパス ファイル名 URL
https://app.box.com/s/xxxxxxx path/to/file (省略) ="https://drive.google.com/file/d/"&C2

検索することでファイルの重複チェックにも

今回の方式で結果的にファイルの重複チェックも行えました
Googleドライブはショートカットを作成できるので、別の目的でフォルダにまとめたい時はコピーではなくショートカットを使うといいですね

株式会社find | 落とし物クラウド

Discussion