841-biborokuWebフロントエンドの備忘録

効率アップ!GASで Google ドライブ 内の資料ディレクトリを見える化

Google スプレッドシートやドキュメントを開いているとき、今開いている資料がドライブのどのフォルダに入っているのか知りたいことがあります。

毎回移動アイコンをクリックして現在の場所を新しいタブで開くのは面倒です・・。特に、フォルダのURLが共有されておらず、資料のURLだけが共有された場合や、同じフォルダに新たな資料を追加したい場合には不便です。

そこで、今開いている資料のディレクトリを簡単に見えるようにするGoogle Apps Script (GAS)を作成しました。

※このページで紹介しているスクリプトは自己責任でお使い下さい。

※CSSや(一部)見た目のための処理は記載のコードに含まれていません。

完成したGAS

コード.gs

function doGet(e) {
  return HtmlService.createHtmlOutputFromFile('index');
}

function getParentFolders(url) {
  try {

    // URLからクエリパラメータを除去
    const cleanUrl = url.split('?')[0];

    // URLを「/」で分割し、配列に格納する
    const parts = cleanUrl.split('/');

    // "folders"または"d"と一致するindexを探す
    const foldersIndex = parts.indexOf('folders');
    const dIndex = parts.indexOf('d');

    // "folders"または"d"が見つかった場合、その次のindexの値を取得する
    let fileId = '';
    if (foldersIndex !== -1) {
      fileId = parts[foldersIndex + 1];
    } else if (dIndex !== -1) {
      fileId = parts[dIndex + 1];
    }
    if (fileId === "") {
      return { error: '該当するIDがありません。' };
    }

    // ファイルまたはフォルダを取得
    let item, name, type;
    if (foldersIndex !== -1) {
      item = DriveApp.getFolderById(fileId);
      name = item.getName();
      type = 'folders';
    } else {
      item = DriveApp.getFileById(fileId);
      name = item.getName();
      type = parts[dIndex - 1];
    }

    let parentFolders = [];
    let currentFolder = item.getParents();

    while (currentFolder.hasNext()) {
      const folder = currentFolder.next();
      parentFolders.push({
        name: folder.getName(),
        id: folder.getId(),
        url: folder.getUrl()
      });
      currentFolder = folder.getParents();
    }

    return {
      parents: parentFolders,
      name: name,
      type: type
    };
  } catch (e) {
    return { error: e.toString() };
  }
}

コード.gsの解説

  • doGet(e) 関数:
    • HTTP GET リクエストを処理し、index.html ファイルを表示します。
  • getParentFolders(url) 関数:
    • 渡されたURLから、Google Drive上のファイルまたはフォルダの親フォルダを取得します。
    • 渡されたURLからファイルまたはフォルダのIDを抽出し、そのIDを使用して対象のファイルまたはフォルダを特定します。
    • 対象のファイルまたはフォルダの親フォルダを取得し、それらの情報を配列に格納します。
    • 最終的に、親フォルダの情報、ファイルまたはフォルダの名前、およびそのタイプ(ファイルまたはフォルダ)を含むオブジェクトを返します。
    • 例外が発生した場合、エラーメッセージを含むオブジェクトを返します。

index.html

<!DOCTYPE html>
<html>

<head>
  <base target="_top">
  <style>
    /* スタイル */
  </style>
</head>

<body>
  <div class="wrapper">
    <div class="form">
      <input type="text" id="url" name="url">
      <button onclick="getParentFolders()">実行</button>
    </div>
    <div id="result"></div>
  </div>

  <script>
    const getParentFolders = () => {
      const url = document.getElementById('url').value;
      google.script.run.withSuccessHandler(result => {
        const resultDiv = document.getElementById('result');
        resultDiv.innerHTML = '';

        if (result.error) {
          resultDiv.innerHTML = `<p class="error">Error: ${result.error}</p>`;
        } else {
          // ファイル名を表示
          const nameParagraph = document.createElement('p');
          nameParagraph.textContent = result.name;
          resultDiv.appendChild(nameParagraph);

          // 親フォルダのリストを表示
          const list = document.createElement('ul');
          result.parents.forEach(folder => {
            const listItem = document.createElement('li');
            const folderLink = document.createElement('a');
            folderLink.href = folder.url;
            folderLink.target = '_blank';
            folderLink.textContent = folder.name;
            listItem.appendChild(folderLink);
            list.appendChild(listItem);
          });
          resultDiv.appendChild(list);
        }
      }).getParentFolders(url);
    }
  </script>

</body>

</html>

index.htmlの解説

  • 実行ボタンのクリック時の処理:
    • ユーザーが実行ボタンをクリックすると、getParentFolders() 関数が呼び出されます。
  • getParentFolders() 関数の処理:
    • 入力されたURLを取得します。
    • Google Apps Scriptの getParentFolders() 関数を呼び出します。これは、指定されたURLの親フォルダを取得するサーバー側の関数です。
    • withSuccessHandler() メソッドを使用して、サーバーからのレスポンスを処理します。
    • レスポンスがエラーを含む場合は、エラーメッセージを表示します。
    • エラーがない場合は、次の処理を行います:
      • 取得したファイルの名前を表示します。
      • ファイルの親フォルダのリンクをリスト表示します。リンクは新しいタブで開きます。

完成までの流れ

Google Apps Scriptファイルの作成

  1. Google Apps Scriptにアクセス
  2. 新しいプロジェクトをクリック
  3. コード.gsの画面が開く
    1. コード.gsに処理を書く
  4. ファイルを追加で「HTML」を選択
    1. 名前をindexにする(別のファイル名でもOK)
    2. URLを入力する<input>と実行する<button>を書く
    3. 実行結果を出力する処理を書く
    4. CSSで見た目を調整

OAuthのScopeの設定

作成したGASには、スコープによる承認が必要なメソッドが含まれています。ここではスコープを設定するためのマニュフェストの編集手順を記載します。

スコープによる承認が必要なメソッド

この方法を使用するスクリプトには、次の 1 つ以上のスコープによる承認が必要です。
https://www.googleapis.com/auth/drive.readonly
https://www.googleapis.com/auth/drive

引用元:https://developers.google.com/apps-script/reference/drive/file?hl=ja

Google Drive API のスコープを選択する」ページにスコープの説明が記載されています。今回はドライブのディレクトリを辿りたいだけなので、drive.readonlyのスコープを指定します。

スコープコード(省略)

説明

使用量

drive.readonly

ドライブのファイルを表示、ダウンロードする。

制限付き

drive

ドライブのファイルの表示と管理を行います。

制限付き

  1. 編集画面の左にあるプロジェクト設定(⚙アイコン)に移動
  2. 全般設定の「「appsscript.json」マニフェスト ファイルをエディタで表示する」を有効にする
  3. エディタに移動
    1. appsscript.jsonに移動
    2. oauthScopesを追記
"oauthScopes": [
  "https://www.googleapis.com/auth/drive.readonly"
]

使用量:制限付きとは?

「使用量」列は、各スコープの機密性を示しています。定義は次のとおりです。

制限付き: このスコープでは、Google ユーザーデータに幅広くアクセスできます。制限付きのスコープの検証プロセスを行う必要があります。この要件については、Google API サービスのユーザーデータに関するポリシー特定の API スコープの追加要件をご覧ください。制限付きのスコープのデータをサーバーに保存(または送信)する場合は、セキュリティ評価を行う必要があります。: このスコープでは、Google ユーザーデータに幅広くアクセスできます。制限付きのスコープの検証プロセスを行う必要があります。この要件については、Google API サービスのユーザーデータに関するポリシーと特定の API スコープの追加要件をご覧ください。制限付きのスコープのデータをサーバーに保存(または送信)する場合は、セキュリティ評価を行う必要があります。

引用元:https://developers.google.com/drive/api/guides/api-specific-auth?hl=ja#drive-scopes

drive.readonlyとdriveの認証画面はどう違う?

初回実行時に、このアプリがあなたのGoogleアカウントのデータにアクセスすることを許可するかどうかを確認する認証・承認画面が表示されます。スコープの設定によって、リクエストされるアクセス権の内容が変わります。

左)drive.readonly・・・表示、ダウンロード
右)drive・・・表示、編集、作成、削除

デプロイ

  1. デプロイボタンをクリックして「新しいデプロイ」を選択
    1. 種類の選択で「ウェブアプリ」を選択
    2. 説明(任意)、次のユーザーとして実行を「ウェブアプリケーションにアクセスしているユーザー」、アクセスできるユーザー「自分のみ」を設定する
  2. デプロイ
  3. ウェブアプリのURLが発行される
  4. URLにアクセスすると、作成したindex.htmlの内容が表示される

※制限付きのスコープのため、アクセスできるユーザーは自分のみにしておくのが安心かと思います。不安な点がある場合は、ご自身で詳細を調べて設定してください。

まとめ

今回Googleフォルダに関するGASを作成し、数多くのメソッドが用意されているということを知ることができました。

またスコープの設定について学んで、データへのアクセスと許可について考えさせられました。特に制限付きスコープを扱う際は、データの適切な使用や第三者への転送制限、広告目的でのデータ使用の禁止などに留意する必要があります。これらのポイントを考えると、作成者としてはデータの取り扱いに慎重さが求められることがわかります。

同時に、実行者としても、自身のデータにアクセスされる範囲を理解し、プライバシーを守るために注意が必要だと感じました。個人情報や機密データが含まれる場合には、特に慎重にならなければなりません。情報を守るために、正確な設定と適切なリクエスト許可が重要だと感じました。

アイコンは、Iconoir | Free IconsのSVGを利用しました。