Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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 authorize 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)

like image 882
Alan Wells Avatar asked Feb 10 '20 15:02

Alan Wells


People also ask

How do I download files from Google API?

To download a file stored on Google Drive, use the files. get method with the ID of the file to download and the alt=media URL parameter. The alt=media URL parameter tells the server that a download of content is being requested.

How do I download a file using API?

In this article, I will use a demo Web API application in ASP.NET Core to show you how to transmit files through an API endpoint. In the final HTML page, end users can left-click a hyperlink to download the file or right-click the link to choose “ Save Link As ” in the context menu and save the file.


1 Answers

I cannot totally solve you problem, but hope it could provide some help.

Files.export() should be as the following format:

const content = Drive.Files.export(id, 'text/plain', {alt:'media'});

If you try to open a .txt file:

GoogleJsonResponseException: API call to drive.files.export failed with error: Export only supports Docs Editors files.

If it is converted into a document file:

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

Which is the same as Files.get() with {alt:'media'}

like image 106
idfurw Avatar answered Oct 09 '22 15:10

idfurw