无OAuth 2.0权限下,如何通过GAS导出Google Drive文件?
无OAuth 2.0权限时导出Google Drive文件的可行方案
问题背景
我用Google表单收集用户提交的PDF和图片,所有回复都存储在Google表格中。现在需要将这些文件连同其他文本字段一起发送到我的Web服务。我了解可以通过文件ID调用Google Drive API的export接口导出文件,但受公司政策限制,无法创建OAuth 2.0凭据。请问在没有OAuth 2.0权限的情况下,还有哪些方法可以导出Google Drive文件?
当前使用的Google Apps Script代码:
function Main() { let arr = new Array() let table = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(`Ответы на форму (1)`) let count = table.getLastRow() let record = table.getRange(count, 2, 1, 16).getValues() let email = record[0][0] let permission = record [0][1] let organization = record[0][2] let phone = record[0][3] phone = phone.substr(2) let target = record[0][6] let fullName = record[0][7].trim() let gender = record[0][8] let inn = record[0][9].toString() let snils = record[0][10].toString() let passport = record[0][11].toString() let issueDate = record[0][12] let issueOrganizationId = record[0][13].toString() let birthDate = record[0][14].toString() let file = record[0][15].replace('https://drive.google.com/open?id=', '').replace('https://drive.google.com/file/d/','').replace('/view?usp=sharing','').trim() arr.push(email, organization, phone, target, fullName, gender, inn, snils, passport, issueDate, issueOrganizationId,birthDate, file) Logger.log (arr) if (record[0][1] == 'Перевыпуск ЭП' && record[0][2] == 'Нет, не менялись') { try { //API_Renew(organization, email, phone) } catch (err) { SendEmail(err, email) } } else { try { //API_New(organization, email, fullName, phone, passport, inn, snils, target, gender, issueDate, issueOrganizationId, birthDate, file) } catch (err) { SendEmail(err, email) } } } function API_New (organization, email, fullName, phone, passport, inn, snils, target, gender, issueDate, issueOrganizationId, birthDate, file) { fullName = fullName.split(' ') let payload = [ { "Organization": organization, "LastName": fullName[0], "FirstName": fullName[1], "MiddleName": fullName[2], "Email": email, "Phone": phone, "Series": passport.substring(0, 4), "Number": passport.substring(4), "Inn": inn, "Snils": snils, "Target": target, "Gender": gender, "IssueDate": issueDate, "IssueOrganizationId": issueOrganizationId, "BirthDate": birthDate, "File": file } ] let options = { method: "POST", contentType: 'application/json; charset=utf-8', payload: JSON.stringify(payload) } return UrlFetchApp.fetch(URL, options) }
可行解决方案
1. 利用Google Apps Script内置DriveApp服务
Google Apps Script自带的DriveApp无需额外配置OAuth 2.0凭据,它的权限与脚本绑定(基于当前账号对目标文件的访问权限)。通过文件ID即可直接获取文件的Blob对象,后续可转为Base64编码嵌入JSON payload,或者直接作为附件传输。
代码修改示例:
function API_New (organization, email, fullName, phone, passport, inn, snils, target, gender, issueDate, issueOrganizationId, birthDate, fileId) { fullName = fullName.split(' ') // 通过DriveApp获取文件Blob let driveFile = DriveApp.getFileById(fileId); let fileBlob = driveFile.getBlob(); // 将Blob转为Base64编码,适配JSON传输 let fileBase64 = Utilities.base64Encode(fileBlob.getBytes()); let payload = [ { "Organization": organization, "LastName": fullName[0], "FirstName": fullName[1], "MiddleName": fullName[2], "Email": email, "Phone": phone, "Series": passport.substring(0, 4), "Number": passport.substring(4), "Inn": inn, "Snils": snils, "Target": target, "Gender": gender, "IssueDate": issueDate, "IssueOrganizationId": issueOrganizationId, "BirthDate": birthDate, "File": { "Id": fileId, "Name": driveFile.getName(), "MimeType": fileBlob.getContentType(), "ContentBase64": fileBase64 } } ] let options = { method: "POST", contentType: 'application/json; charset=utf-8', payload: JSON.stringify(payload) } return UrlFetchApp.fetch(URL, options) }
2. 使用文件公开下载链接
若可以调整提交文件的权限(设置为「知道链接的任何人可下载」),可直接构造公开下载链接,通过UrlFetchApp获取文件内容。注意此方法存在隐私风险,需确保文件内容无敏感信息。
代码修改示例:
// 辅助函数:获取公开文件内容 function getPublicFileContent(fileId) { const downloadUrl = `https://drive.google.com/uc?export=download&id=${fileId}`; const response = UrlFetchApp.fetch(downloadUrl); return response.getBlob(); } // 修改API_New函数 function API_New (organization, email, fullName, phone, passport, inn, snils, target, gender, issueDate, issueOrganizationId, birthDate, fileId) { fullName = fullName.split(' ') // 获取公开文件的Blob并转为Base64 let fileBlob = getPublicFileContent(fileId); let fileBase64 = Utilities.base64Encode(fileBlob.getBytes()); let payload = [ { "Organization": organization, "LastName": fullName[0], "FirstName": fullName[1], "MiddleName": fullName[2], "Email": email, "Phone": phone, "Series": passport.substring(0, 4), "Number": passport.substring(4), "Inn": inn, "Snils": snils, "Target": target, "Gender": gender, "IssueDate": issueDate, "IssueOrganizationId": issueOrganizationId, "BirthDate": birthDate, "File": { "Id": fileId, "Name": fileBlob.getName(), "MimeType": fileBlob.getContentType(), "ContentBase64": fileBase64 } } ] let options = { method: "POST", contentType: 'application/json; charset=utf-8', payload: JSON.stringify(payload) } return UrlFetchApp.fetch(URL, options) }
注意事项
- 使用
DriveApp时,需确保脚本关联的账号拥有目标文件的访问权限(表单提交的文件默认会共享给表单/表格所有者,因此一般无需额外设置)。 - 公开链接方式需谨慎使用,避免敏感数据泄露;若文件涉及隐私,优先选择
DriveApp方案。 - 大文件(超过10MB)可能触发
UrlFetchApp的限制,此时可考虑分块处理,但表单提交的文件通常不会超过此阈值。
内容的提问来源于stack exchange,提问作者Mikhail Gorbov
相关产品推荐
相关产品推荐

