如何用Gmail API V1与Drive API V3高效上传Gmail中Xlsx附件至Drive
解决方案:Gmail API批量获取Xlsx附件并转存Google Sheets优化
一、修复Sample1的Xlsx附件损坏问题
你遇到的字节数组保存后文件损坏,核心原因是Gmail API返回的附件data是URL安全的Base64编码(替换了+为-、/为_,可能省略=),直接转字节数组会破坏文件结构。正确处理步骤:
- 将API返回的
data转换为标准Base64格式 - 解码为Blob后再上传到Drive并转换为Google Sheets
示例代码:
function getAndSaveValidAttachment() { const userId = 'me'; const messageId = '目标邮件ID'; const attachmentId = '目标附件ID'; // 获取附件原始数据 const attachment = Gmail.Users.Messages.Attachments.get(userId, messageId, attachmentId); // 转换为标准Base64编码 const standardBase64 = attachment.data.replace(/-/g, '+').replace(/_/g, '/'); // 解码为Blob对象 const blob = Utilities.newBlob(Utilities.base64Decode(standardBase64), attachment.mimeType, attachment.filename); // 上传到Drive并自动转换为Google Sheets const convertedFile = Drive.Files.create({ title: attachment.filename.replace('.xlsx', ''), mimeType: 'application/vnd.google-apps.spreadsheet', parents: ['指定目标文件夹ID'] // 可选:指定保存位置 }, blob); console.log('转换完成,文件ID:' + convertedFile.id); }
二、批量处理速度优化方案
Sample2处理大量附件慢的核心问题是单次API调用仅处理单个邮件/附件,高频请求导致连接开销累积。优化方向如下:
1. 精准过滤目标邮件
用Gmail API的list接口,通过q参数直接筛选带.xlsx附件的邮件,减少无效请求:
const filterQuery = 'has:attachment filename:xlsx'; const targetMessages = Gmail.Users.Messages.list('me', {q: filterQuery, maxResults: 100}).messages;
2. 使用批量请求打包操作
将多个附件获取请求打包成批量请求,大幅减少HTTP连接次数。示例:
function batchProcessXlsxAttachments() { const userId = 'me'; const filterQuery = 'has:attachment filename:xlsx'; const messages = Gmail.Users.Messages.list(userId, {q: filterQuery, maxResults: 50}).messages; const batchRequest = Gmail.newBatchRequest(); // 批量添加邮件详情获取请求 messages.forEach(msg => { batchRequest.add(Gmail.Users.Messages.get(userId, msg.id, { format: 'metadata', fields: 'payload/parts' }), { callback: (res, err) => { if (err) { console.error('获取邮件失败:' + err.message); return; } // 提取邮件中的Xlsx附件 const xlsxParts = res.payload.parts.filter(part => part.filename?.endsWith('.xlsx')); xlsxParts.forEach(part => { // 处理单个附件并转存 const attachment = Gmail.Users.Messages.Attachments.get(userId, msg.id, part.body.attachmentId); const standardBase64 = attachment.data.replace(/-/g, '+').replace(/_/g, '/'); const blob = Utilities.newBlob(Utilities.base64Decode(standardBase64), part.mimeType, part.filename); // 异步上传转换(可进一步打包为Drive批量请求) Drive.Files.create({ title: part.filename.replace('.xlsx', ''), mimeType: 'application/vnd.google-apps.spreadsheet' }, blob); }); } }); }); // 执行批量请求 Gmail.newBatchRequest().execute(batchRequest); }
3. 额外优化点
- 限制单次处理的邮件数量(建议50-100),避免脚本超时
- 用
CacheService缓存已处理的邮件ID,防止重复操作 - 开启Drive API批量上传,将多个文件上传请求打包进一步提速
内容的提问来源于stack exchange,提问作者Antonio
相关产品推荐
相关产品推荐

