簡體   English   中英

列出 Google 應用腳本項目

[英]List Google app script projects

我正在嘗試使用 此處記錄的 Google Drive File API 列出我所有的 google 腳本文件。 但是我總是得到一個空的 [] 列表。 我認為我的令牌和范圍很好,因為我從 Google OAuth2 取回了這個:

{ "access_token": "xxxxx", "expires_in": 3600, "refresh_token": "yyyyy",
"scope": "https://www.googleapis.com/auth/drive.scripts https://www.googleapis.com/auth/drive.appdata https://www.googleapis.com/auth/drive",
"token_type": "Bearer"
}

但是當我使用 mimeType 過濾發出查詢時(我只想獲取 google 應用程序腳本列表):

mimeType = 'application/vnd.google-apps.script'

即使我剛剛在 Google Sheet 中創建了一個 google 腳本,我也只會返回一個空的項目列表 ([]):

{ "kind": "drive#fileList", "etag": "....", "selfLink": "https://www.googleapis.com/drive/v2/files?q=mimeType+%3D+'application/vnd.google-apps.script'", "incompleteSearch": false, "items": []}

我猜 app-script 的意思不是谷歌腳本代碼,它是谷歌表的一部分......感謝任何幫助:)

關於檢索容器綁定腳本類型的項目的文件列表並從項目中導出每個腳本,請查看以下答案。

檢索容器綁定腳本類型的項目的文件列表

  • 遺憾的是,目前還無法檢索到容器綁定腳本類型的項目文件列表,而可以使用Drive API 的drive.files.list 檢索獨立類型的項目文件列表。

導出項目中的腳本

  • 當您想從容器綁定腳本類型和獨立類型的項目中導出每個腳本時,您可以使用Google Apps Script API 來完成
    • 這可能會成為適合您情況的 GAS 示例腳本。 在這里
    • 你也可以使用這樣的 GAS 庫來做到這一點

一個拼湊而成的工作區,以獲取獨立和綁定項目 ID 的列表

我把這個貼在這里是因為我在過去幾天里多次瀏覽這個頁面,以防其他人真的想得到他們項目的完整列表並且不介意跳過幾個箍得到它然后這可能對他們有用。

我找到了一種方法來獲取我所有的 Apps 腳本項目文件 ID。 它不是很漂亮,但我把 1393 個都綁定了,並且是獨立的。 我進入 Google Developer Hub 並注意到我的項目 ID 可以在屬性名稱data-script-id="project id" ,通過繼續向下翻到列表底部,我能夠保留該頁面尋找更多的頁面,直到沒有剩下的頁面。 然后我進入 Chrome 開發人員工具,我找到了包含所有具有上述屬性的 div 的 div,對我來說,這個名為<div class="uBvHbd"並且我復制了整個 div 並嘗試將它粘貼到一個 ascii 文件中我的 Google 帳戶,但我發現這是一個問題,所以我打開了 UltraEdit 的副本並將其粘貼到那里。 我玩了一段時間的正則表達式,花了一天時間重新訓練自己使用 UltraEdit 文檔模型和它們的 Javascript 引擎版本,並開發了以下例程,使我能夠構建完整的 projectid 列表。

UltraEdits 腳本語言:

function getDocumentPaths() {
  UltraEdit.outputWindow.write('File Paths:');
  for(var i=0;i<UltraEdit.document.length;i++) {
    UltraEdit.outputWindow.write('[' + i + ']: ' + UltraEdit.document[i].path);
  }
}

function getFileNames() {
  var nA=[];
  var fnToIdx={fnA:[]};
  for(var i=0;i<UltraEdit.document.length;i++) {
    var p=UltraEdit.document[i].path;
    var pA=p.split(/\\/);
    var fn=pA[pA.length-1].split('.')[0];
     fnToIdx.fnA.push(fn);
     fnToIdx[fn]=i;
  }
   UltraEdit.outputWindow.write('FileNames: \r\n' + fnToIdx.fnA.join('\r\n'));
   return fnToIdx;
}

function getScriptIdsIndex() {
  for(var i=0;i<UltraEdit.document.length;i++) {
    if(UltraEdit.document[i].isName('ScriptIds')) {
      return i;
    }
  }
}

function getFileIndexByName(name) {
  var name=name||'ScriptIds';
  if(name) {
    for(var i=0;i<UltraEdit.document.length;i++) {
      if(UltraEdit.document[i].isName(name)) {
        return i;
      }
    }
  }else{
    UltraEdit.messageBox("Invalid or Missing Inputs at getFileIndexByName().","Alert")
  }
}

function getAllFileIndices(obj) {
  UltraEdit.outputWindow.write('File Indices:');
  var fnIndicesA=[]
  for(var j=0;j<obj.fnA.length;j++) {
    fnIndicesA.push({name:obj.fnA[j] , index:obj[obj.fnA[j]]})
  }
  var_dump(fnIndicesA);
}

function updateWorkingTabs(index) {
  UltraEdit.outputWindow.write('Index: ' + index);
  UltraEdit.document[index].selectAll();
  UltraEdit.document[index].copy();
  var workingTabsA=[];
  for(var i=0;i<UltraEdit.document.length;i++) {
    if(UltraEdit.document[i].path.slice(0,-1)=='Edit') {
      UltraEdit.document[i].paste();
      workingTabsA.push(i);
    }
  }
  return workingTabsA;
}

function findAllIds() {
  var fnToIndex=getFileNames();
  UltraEdit.document[fnToIndex['ScriptIds']].selectAll();
  UltraEdit.document[fnToIndex['ScriptIds']].copy();
  var s=UltraEdit.clipboardContent;
  var re=/data-script-id="[^"]+"/g;
  var matchA=s.match(re);
  UltraEdit.document[fnToIndex['FileIds']].selectAll();
  UltraEdit.document[fnToIndex['FileIds']].cut();
  for(var i=0;i<matchA.length;i++) {
    UltraEdit.document[fnToIndex['FileIds']].write(matchA[i].slice(16,-1)  + '\r\n');
  }
}

function removeDuplicates() {
  var fnToIndex=getFileNames();
  UltraEdit.document[fnToIndex['FileIds']].selectAll();
  UltraEdit.document[fnToIndex['FileIds']].copy();
  var fnA=UltraEdit.clipboardContent.split('\r\n');
  if(!fnA[fnA.length-1]) {
    fnA.pop();
  }
  var uA=[];
  for(var i=0;i<fnA.length;i++) {
    if(uA.indexOf(fnA[i])==-1) {
      uA.push(fnA[i]);
    }
  }
  var s='';  
  for(var i=0;i<uA.length;i++) {
    if(i>0){
      s+='\r\n';
    }
    s+=uA[i];
  }
  UltraEdit.document[fnToIndex['FileIds']].selectAll();
  UltraEdit.document[fnToIndex['FileIds']].cut();
  UltraEdit.document[fnToIndex['FileIds']].write(s);
 }

UltraEdit.outputWindow.clear();
//UltraEdit.open('E:\\Projects\\ScriptIds\\ScriptIds.txt');
//var ScriptIds_idx=getScriptIdsIndex();
//var wtA=updateWorkingTabs(ScriptIds_idx);

//findAllIds()

removeDuplicates();

輸入文件為 24 MB,輸出列表為 81KB,在我的筆記本電腦上運行的腳本用了不到 5 秒的時間來去除 ID 並刪除重復項(也沒有找到)。

我在 Google Apps Script 中運行這兩個例程以從 Google Apps Script API 獲取腳本信息,以便我可以確定哪些是獨立的,哪些是容器綁定的。 對於容器綁定,我能夠獲得容器文件名和 ID。

function getInfo(projectId) {
  var projectId=projectId||pid;
  var rObj={'ProjectId':projectId};
  var params = {muteHttpExceptions:true,headers: {"Authorization": "Bearer " + ScriptApp.getOAuthToken()}};
  try {
    var url=Utilities.formatString('https://script.googleapis.com/v1/projects/%s',projectId);
  }
  catch(e) {
    return rObj['Error']=e;
  }
  var resp=UrlFetchApp.fetch(url,params);
  var data=JSON.parse(resp.getContentText());
  if(data.hasOwnProperty('parentId')) {
    var pFile=DriveApp.getFileById(data.parentId)
    var parentName=pFile.getName();
    var pfldrA=[];
    var pFolders=pFile.getParents();
    while(pFolders.hasNext()) {
      var folder=pFolders.next();
      pfldrA.push({id:folder.getId(),name:folder.getName()});
    }
    rObj['ProjectName']=data.title;
    rObj['ParentName']=parentName;
    rObj['ParentId']=data.parentId;
    rObj['ParentFolders']='';
    rObj['ParentFolderIds']='';
  //var html=Utilities.formatString('<br /><b>Project Name:</b>%s<br /><b>ParentName:</b> %s<br /><b>ParentId:</b> %s',data.title,parentName,data.parentId);
  //html+=Utilities.formatString('<br /><b>Parent Folders:</b>');
    for(var i=0;i<pfldrA.length;i++) {
      if(i>0) {
        rObj.ParentFolders+=', ';
        rObj.ParentFolderIds+=', ';
      }
      //html+=Utilities.formatString('<br /><b>Name:</b> %s <b>Id:</b> %s',pfldrA[i].name,pfldrA[i].id);
      rObj.ParentFolders+=pfldrA[i].name;
      rObj.ParentFolderIds+=pfldrA[i].id;
    }
  }else{
    rObj['ProjectName']=data.title;
    //var html=Utilities.formatString('<br /><b>StandAlone Project</b><br /><b>Project Name:</b>%s<br /><b>ProjectId:</b>%s',data.title,projectId);
  }
  //Logger.log(data);
  //var userInterface=HtmlService.createHtmlOutput(html);
  //SpreadsheetApp.getUi().showModelessDialog(userInterface, "Project Info");
  return rObj;
}

function updateProjects() {
  var ss=SpreadsheetApp.getActive();
  var sh=ss.getSheetByName('Projects');
  var idx={hA:[],hr:1}
  idx.hA=sh.getRange(1,1,1,sh.getLastColumn()).getValues()[0];
  idx.hA.forEach(function(e,i){idx[e]=i;});
  var lr=sh.getLastRow();
  var sr=getColumnHeight(1,sh,ss) + 1;
  var cnt=25;
  setGlobal('count',cnt);
  if(lr-sr+1<cnt) {
    cnt=lr-sr+1;
  }
  if(sr>=lr) {
    setGlobal('count',0);
    return;
  }
  //Item    ProjectId   ProjectName ParentId    ParentName  ParentFolders   ParentFolderIds
  var rg=sh.getRange(sr,1,cnt,sh.getLastColumn());
  var vA=rg.getValues();
  for(var i=0;i<vA.length;i++) {
    if(!vA[i][idx.Item] && vA[i][idx.ProjectId]) {
      var pObj=getInfo(vA[i][idx.ProjectId]);
      if(!pObj.hasOwnProperty('Error') && pObj.hasOwnProperty('ParentId')) {
        vA[i][idx.Item]=i+sr;
        vA[i][idx.ProjectName]=pObj.ProjectName;
        vA[i][idx.ParentId]=pObj.ParentId;
        vA[i][idx.ParentName]=pObj.ParentName;
        vA[i][idx.ParentFolders]=pObj.ParentFolders;
        vA[i][idx.ParentFolderIds]=pObj.ParentFolderIds;
      }else if(!pObj.hasOwnProperty('Error') && !pObj.hasOwnProperty('ParentId')){
        vA[i][idx.Item]=i+sr;
        vA[i][idx.ProjectName]=pObj.ProjectName;
        vA[i][idx.ParentName]='Standalone Project';
      }else{
        vA[i][idxItem]=i+sr;
        vA[i][idx.ProjectName]=(pObj.hasOwnProperty('Error'))?pObj.Error:"Unknown Problem";
      }
      Utilities.sleep(1000);
    }
  }
  rg.setValues(vA);
}

稍后我會回來並在代碼中添加一些注釋。 這不是很好,但我現在有我所有項目的列表,以及在哪里可以找到它們以及它們的容器的名稱(如果有的話)。 我要感謝 @Tanaike 提供 Apps 腳本庫。 它確實幫助我弄清楚了如何訪問 Apps Script API,結果證明它比我想象的要容易得多。

部分最終名單一覽:

在此處輸入圖片說明

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM