问题
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