GoogleAppsScript
gas
BOX
boxapi

Google App ScriptでBoxフォルダーオーナー一覧を調査する

はじめに

boxを長く使っていると、色んな人に招待されてルートフォルダが若干カオスな状態になりがちです。
整理をしようにもフォルダーオーナーが誰なのか分からず、確認したくても一個一個目視していくのも結構大変
管理者に頼んでリストを出してもらうのありだけど、管理者もヒマじゃないだろうし、出来ることなら自分でリストを出したい。

Google App Scriptを使ってフォルダーオーナーの一覧を出力する

一覧が欲しいだけなら、Box APIを叩いて一覧をjsonで取得は出来るが可読性が低いし、情報量が多すぎる。
もっと手軽にリスト化する方法はないか。

💡ピコーンッ!Google App Script使って欲しい情報だけセルに落とし込めばいいんじゃね?
それと、生成されたレポートをBox上にアップロード出来るようにしたら、二度うまい。

デモ動画:やってみた。

Google App Script

Google App Sciprt通称GAS(ガースー黒光り探偵社じゃないよ)は、平たく言うとOfficeでいうところのマクロにあたる存在。
大きな違いはGapps上で実行されることと、基本構文がJavascriptに近い
参考:はじめてのGoogle App Scripts

まずは、自分のフォルダ一覧を取得するスクリプト

getNames,folderOwner
function getNames(){
  //box api: folder一覧をリストするエンドポイント
  aUrl = 'https://api.box.com/2.0/folders/0/items';
  //box API Access Tokenの入力をプロンプトで求める
  //開発者トークンでも可能
  var atoken = Browser.inputBox('Access token?', 'access token', Browser.Buttons.OK_CANCEL);

  //Get requestのヘッダー情報を用意
  headers = {'Authorization' : 'Bearer ' + atoken};
  params = {'headers' : headers};  

  //Folder情報を取得
  var response = UrlFetchApp.fetch(aUrl ,params); // get api endpoint
  var dataAll = JSON.parse(response.getContentText()); //
  var data = dataAll.entries; //parse text into json

  //Google Sheetの取得
  var ss = SpreadsheetApp.getActiveSpreadsheet(); //get active spreadsheet
  var sheet = ss.getActiveSheet(); //get sheet by name from active spreadsheet
 Logger.log(data); //log data to logger to check

  //ヘッダーカラム情報を入力
  var columns=[];
  columns.push('Folder name');
  columns.push('Folder ID');
  columns.push('Folder Owned By');
  sheet.appendRow(columns);
  columns.splice(0, columns.length);

  //Folder情報の取得
  for (i in data){
    if (data[i].type === 'folder'){
    folderOwner(data[i].id, atoken);
    }
  }
}

function folderOwner(folderid,atoken){
  //Folder情報取得するためのエンドポイント
  aUrl = 'https://api.box.com/2.0/folders/';
  headers = {'Authorization' : 'Bearer ' + atoken};
  params = {'headers' : headers};  
  var response = UrlFetchApp.fetch(aUrl + folderid ,params); // get api endpoint
  var dataAll = JSON.parse(response.getContentText()); //
  var stats=[]; //create empty array to hold data points
  var ss = SpreadsheetApp.getActiveSpreadsheet(); //get active spreadsheet
  var sheet = ss.getActiveSheet(); //get sheet from active spreadsheet
 Logger.log(dataAll); //log data to logger to check

  stats.push(dataAll.name);
  stats.push(dataAll.id);
  stats.push(dataAll.owned_by.login);
  sheet.appendRow(stats)           
  stats.splice(0, stats.length);
}

*今回のスクリプトでは、Access Tokenを直接入れるよう求めているが、OAuth認証フローをGoogle App Scriptに入れることも技術テジュには可能。
これを使うと出来るらしい。。。が時間がなく試していない
https://github.com/googlesamples/apps-script-oauth2

次に、出力したGsheetをExcelに変換して、Boxにアップロードするスクリプト

exportFile
function exportFile(){

  //box API Access Tokenの入力をプロンプトで求める
  //開発者トークンでも可能
  var atoken = Browser.inputBox('Access token?', 'access token', Browser.Buttons.OK_CANCEL);
  var ss = SpreadsheetApp.getActive();

  //GsheetをExcelに変換するためのエンドポイント
  var url = 'https://docs.google.com/feeds/download/spreadsheets/Export?key=' + ss.getId() + '&exportFormat=xlsx';

  //Gsheetの認証情報を用意する
  var params = {
  method      : 'get',
  headers     : {'Authorization': 'Bearer ' + ScriptApp.getOAuthToken()},
  //muteHttpExceptions: true
  };

  //Excelデータを取得
  var blob = UrlFetchApp.fetch(url, params).getBlob();
  var blobName = blob.setName(ss.getName() + '.xlsx');


  //Boxにファイルをアップロードする準備。Multipart formアップロードにするため色々用意
  //詳しくはこちら→https://developer.box.com/v2.0/reference#upload-a-file
  var aURL = 'https://upload.box.com/api/2.0/files/content';
  var boundary = 'boxob';
  //アップロードするFolderID直打ちにしていますが、好きにカスタマイズ出来る。
  var attributes = "{\"name\":\"FolderList.xlsx\", \"parent\":{\"id\":\"40985326479\"}}";

  var requestBody = Utilities.newBlob(
    "--"+boundary+"\r\n"
    + "Content-Disposition: form-data; name=\"attributes\"\r\n\r\n"
    + attributes+"\r\n"+"--"+boundary+"\r\n"
    + "Content-Disposition: form-data; name=\"file\"; filename=\""+blobName+"\"\r\n"
  + "Content-Type: " + blob.getContentType()+"\r\n\r\n").getBytes()
  .concat(blob.getBytes())
  .concat(Utilities.newBlob("\r\n--"+boundary+"--\r\n").getBytes());

  var options = {
    method: 'post',
    contentType: "multipart/form-data; boundary="+boundary,
    payload: requestBody,
    muteHttpExceptions: true,
    headers: {'Authorization': 'Bearer ' + atoken}
  };

  //Boxにアップロード
  var request = UrlFetchApp.fetch(aURL, options);

  Logger.log(request.getContentText());

}

この連携にあたって参考にした情報

Google Apps ScriptからHTTP POST
External APIs