使用Google Apps Script Advanced Drive API-Drive.Files.get获取文件内容-或导出 [英] Get file content with Google Apps Script Advanced Drive API - Drive.Files.get - or export
问题描述
我需要使用Google Apps脚本高级驱动器服务获取文本文件的文件内容.此问题特定于Google Apps脚本.
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.
可以通过使用Drive API发出HTTPS请求来获取文件内容,但是我不想发出HTTPS请求.因此,我不要求变通"解决方案.或不使用高级驱动器服务的方式.
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.
有可能使用HTTPS请求(使用文件的自身链接和"alt = media")获取对Drive REST API的文件内容.选项.但是我不想那样做,因为我想避免用户授权外部请求.
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.
这是我现在使用Drive REST API的方式.
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)
}
}
这是我尝试过的:
function getFileContent() {
try{
var content = Drive.Files.get('File ID Here',{alt:'media'});
}catch(e) {
Logger.log('message: ' + e.message)
}
}
上面的代码生成错误:
消息:响应码:200.消息:文件内容在这里
message: Response Code: 200. Message: File content is here
还可以获取"Web Content Link"(网络内容链接)从文件元数据中,然后使用webContentLink进行以下操作:
It is also possible to get a "Web Content Link" from the files metadata, and to then use the webContentLink to:
报价:
用于在浏览器中下载文件内容的链接.这是 仅适用于Google云端硬盘中具有二进制内容的文件
A link for downloading the content of the file in a browser. This is only available for files with binary content in Google Drive
文档位于: https://developers.google.com/drive/api/v3/reference/files
我尝试过:
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');
似乎高级驱动器API无法获取文件内容.即使REST API能够获取文件内容,高级驱动器API似乎也有意忽略了此功能.
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
如果可以在"https://www.googleapis.com/auth/drive.file"
范围内使用DriveApp
,我会很乐意使用,但是 DriveApp.getFileById('ID')
不适用于该范围.以下代码:
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();
返回以下错误:
异常:您无权调用DriveApp.getFileById. 所需权限:( https://www.googleapis.com/auth/drive.readonly || https://www.googleapis.com/auth/drive )
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)
即使是只读" https://www.googleapis.com/auth/drive.readonly
的范围受到限制.请参阅:"Gmail和云端硬盘API"在以下链接的部分中: https://support.google.com/cloud/answer /9110914#restricted-scopes
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=zh_CN#getFileById(String)
推荐答案
我测试了不同的范围:Files.export()
和Files.get()
的 drive 和 drive.file
I tested different scopes : drive and drive.file for Files.export()
and Files.get()
只有 drive.file 范围为我提供了404
Only drive.file scope gave me 404
为什么?
因为 drive.file 用于由应用创建或打开的文件
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));
}