Google Drive: Search Folder
Searches for a folder with a specific name directly under the specified folder on Google Drive.
Configs: Common
  • Step Name
  • Note
Configs
  • C1: OAuth2 Setting *
  • C2: Parent Folder ID (When empty, search in My Drive root)#{EL}
  • C3: Folder Name to search for *#{EL}
  • C4: Data item that will save Folder ID
  • C5: Data item that will save web view URL of Folder

Notes

Capture

See also

Script (click to open)
  • An XML file that contains the code below is available to download
    • google-drive-folder-search.xml (C) Questetra, Inc. (MIT License)
    • If you are using Professional, you can modify the contents of this file and use it as your own add-on

main();
function main() {
  //// == 工程コンフィグ・ワークフローデータの参照 / Config & Data Retrieving ==
  let parentFolderId = configs.get("ParentFolderId");
  if (parentFolderId === "" || parentFolderId === null) {
    parentFolderId = "root";
  }
  const folderName = configs.get("FolderName");
  if (folderName === "" || folderName === null) {
    throw "Folder Name is blank";
  }
  const idDataDef = configs.getObject("FolderIdItem");
  const urlDataDef = configs.getObject("WebViewUrlItem");
  // If neither C4 nor C5 are set, throw error
  if (idDataDef === null && urlDataDef === null) {
    throw "Neither of Data Items to save result are set.";
  }
  const oauth = configs.get("OAuth");

  //// == 演算 / Calculating ==
  const driveId = getDriveId(oauth, parentFolderId);
  const folders = searchFolder(oauth, driveId, parentFolderId, folderName);
  const folderNum = folders.length;
  if (folderNum === 0) {
    throw `Could not find Folder ${folderName} with Parent Folder ID ${parentFolderId}`;
  }
  const folderIdList = [];
  const folderUrlList = [];
  for (let i = 0; i < folderNum; i++) {
    folderIdList.push(folders[i].id);
    folderUrlList.push(folders[i].webViewLink);
  }

  //// == ワークフローデータへの代入 / Data Updating ==
  setFolderData(idDataDef, folderIdList);
  setFolderData(urlDataDef, folderUrlList);
}

/**
 * 親フォルダのドライブ ID を取得する
 * @param {String} oauth OAuth2 認証設定
 * @param {String} parentFolderId 親フォルダの ID
 * @return {String} driveId ドライブ ID (共有ドライブになければ null)
 */
function getDriveId(oauth, parentFolderId) {
  if (parentFolderId === "root") {
    return null;
  }
  const url = `https://www.googleapis.com/drive/v3/files/${parentFolderId}`;
  const response = httpClient
    .begin()
    .authSetting(oauth)
    .queryParam("fields", "driveId")
    .queryParam("supportsAllDrives", "true")
    .get(url);
  const status = response.getStatusCode();
  const responseTxt = response.getResponseAsString();
  if (status >= 300) {
    const error = `Failed to get parent folder with parent folder ID ${parentFolderId}. status:${status}`;
    engine.log(responseTxt);
    throw error;
  }
  const driveId = JSON.parse(responseTxt).driveId;
  if (driveId === undefined) {
    return null;
  }
  return driveId;
}

/**
 * Google ドライブのフォルダを検索
 * @param {String} oauth OAuth2 認証設定
 * @param {String} driveId 親フォルダのドライブ ID (共有ドライブになければ null)
 * @param {String} parentFolderId 親フォルダの ID
 * @param {String} folderName 検索するフォルダの名前
 * @return {Array} folders 検索結果一覧
 * @return {String} folders[].id フォルダの ID
 * @return {String} folders[].webViewLink フォルダの表示 URL
 */
function searchFolder(oauth, driveId, parentFolderId, folderName) {
  const folderNameRep = folderName.replace(/['\\]/g, "\\$&"); // ' と \ をエスケープ
  const q = `mimeType = 'application/vnd.google-apps.folder' and trashed = false and name = '${folderNameRep}' and '${parentFolderId}' in parents`;
  const url = "https://www.googleapis.com/drive/v3/files";
  let request = httpClient
    .begin()
    .authSetting(oauth)
    .queryParam("q", q)
    .queryParam("pageSize", "1000")
    .queryParam("fields", "files(id,webViewLink)");
  if (driveId !== null) { // 親フォルダが共有ドライブにある場合
    request = request
      .queryParam("includeItemsFromAllDrives", "true")
      .queryParam("supportsAllDrives", "true")
      .queryParam("corpora", "drive")
      .queryParam("driveId", driveId);
  }
  const response = request.get(url);
  const status = response.getStatusCode();
  const responseTxt = response.getResponseAsString();
  if (status >= 300) {
    const error = `Failed to search. status:${status}`;
    engine.log(responseTxt);
    throw error;
  }
  const folders = JSON.parse(responseTxt).files;
  return folders;
}

/**
 * フォルダの情報をデータ項目にセットする
 * @param {ProcessDataDefinitionView} dataDef 保存先データ項目の ProcessDataDefinitionView
 * @param {Array<String>} folderInfoList 保存するフォルダ情報の配列
 */
function setFolderData(dataDef, folderInfoList) {
  if (dataDef !== null) {
    //Multiple Judge
    if (dataDef.matchDataType("STRING_TEXTFIELD") && folderInfoList.length > 1) {
      throw "Multiple folders are found. Can't set data to single-line string Data Item.";
    }
    const folderInfoStr = folderInfoList.join("\n");
    engine.setData(dataDef, folderInfoStr);
  }
}
%d bloggers like this: