Get file content with Google Apps Script Advanced Drive API - Drive.Files.get - or export

丶灬走出姿态 提交于 2020-03-21 06:57:22

问题


I need to get the file content of a text file using the Google Apps Script Advanced Drive Service. This question is specific to Google Apps Script.

It is possible to get file content by making an HTTPS Request using the Drive API, but I don't want to make an HTTPS Request. So, I'm not asking for a "work around" or a way that does not use the Advanced Drive Service.

It is possible to get file content using an HTTPS Request to the Drive REST API using the file's self link and the "alt=media" option. But I don't want to do it that way, because I want to avoid the need for the user to authorized an external request.

Here is the way that I am doing it now with the Drive REST API.

function getContentsOfTxtFile_(po) {
try{
  var i,options,rtrnObj,selfLink,tkn,url;
  /*
    PASSED IN PARAMETERS
    po.id - the file id of the text file to get
  */

  selfLink = 'https://www.googleapis.com/drive/v3/files/' + po.id;
  url = selfLink + '?alt=media';//using alt=media returns the file content instead of the metadata resource

  tkn = ScriptApp.getOAuthToken();//Get the OAuth token

  options = {};
  options.headers = {Authorization: 'Bearer ' + tkn}
  options.muteHttpExceptions = true;

  for (i=1;i<3;i++) {//Only loop twice because sometimes there will legitimately not be a file
  try{
    rtrnObj = UrlFetchApp.fetch(url,options);//Make an external request to get the file content
    break;//If successful break out of the loop
  } catch(e) {
    if (i!==2) {Utilities.sleep(i*1500);}
    if (i>=2) {
      console.log('ERROR getting file content: ' + e + "Stack: " + e.stack)
    }
  };
  }

  if (!rtrnObj) {
    return false;
  }

  if (rtrnObj.getResponseCode() !== 200) { 
    return false;
  }
  return rtrnObj.getContentText();
}catch(e){
  console.error('Error ' + e)
}
}

Here is what I have tried:

function getFileContent() {
  try{
    var content = Drive.Files.get('File ID Here',{alt:'media'});
  }catch(e) {
    Logger.log('message: ' + e.message)
  } 

}

The above code generates the error:

message: Response Code: 200. Message: File content is here

It is also possible to get a "Web Content Link" from the files metadata, and to then use the webContentLink to:

Quote:

A link for downloading the content of the file in a browser. This is only available for files with binary content in Google Drive

Documentation at: https://developers.google.com/drive/api/v3/reference/files

I have tried:

function getFileContentW_Export() {
  try{
    var content = Drive.Files.export('FileID?alt=media','text/plain');
  }catch(e) {
    Logger.log('message: ' + e.message)
  } 

  Logger.log('content: ' + content)
}

OR:

var content = Drive.Files.export('FileID','text/plain');

It seems that the Advanced Drive API is not able to get file content. It seems like this capability was intentionally omitted from the Advanced Drive API, even though the REST API is capable of getting file content.

I issued a bug report in the issue tracker, but the lack of this capability is not considered to be a bug.

https://issuetracker.google.com/issues/149104685

I'd gladly use DriveApp if I could use it with the scope "https://www.googleapis.com/auth/drive.file" but DriveApp.getFileById('ID') won't work with that scope. The following code:

var content = DriveApp.getFileById('ID').getAs(MimeType.PLAIN_TEXT).getDataAsString();

Returns an error of:

Exception: You do not have permission to call DriveApp.getFileById. Required permissions: (https://www.googleapis.com/auth/drive.readonly || https://www.googleapis.com/auth/drive)

Even the "readonly" scope of https://www.googleapis.com/auth/drive.readonly is restricted. See: "Gmail and Drive APIs" in section at link: https://support.google.com/cloud/answer/9110914#restricted-scopes

https://developers.google.com/apps-script/reference/drive/drive-app?hl=en#getFileById(String)


回答1:


I tested different scopes : drive and drive.file for Files.export() and Files.get()

Only drive.file scope gave me 404

Why?

Because drive.file is used for files created or opened by the app

Check it here : Authenticate your users

function fileExport(auth) {
  const drive = google.drive({ version: 'v3', auth });
  drive.files.export({
      fileId: fileId,
      mimeType: "text/plain"
    }).then(res => console.log(res))
    .catch(e => console.log(e));
}

for files created in drive, use:

function fileGet(auth) {
  const drive = google.drive({ version: 'v3', auth });
  drive.files.get({
      fileId: fileId
    }).then(res => console.log(res))
    .catch(e => console.log(e));
}

Reference:

  • Files: get
  • Files: export


来源:https://stackoverflow.com/questions/60153938/get-file-content-with-google-apps-script-advanced-drive-api-drive-files-get

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!