使用Google Apps Script获取Gmail文件夹大小及消息数的问题求助
问题与修复方案
问题现状
当前脚本无法正确统计Gmail标签(文件夹)的消息总数folderMessageCount和总大小folderSize,返回结果全为0.0或0.00 MB。即使替换message.getRawContent().length为Utilities.newBlob(message.getRawContent()).getBytes().length也无效果。最终需求是按月份(如Jan-2018、Feb-2023等)统计各标签的消息数量与存储占用。
核心问题分析
- 线程获取方式错误:原代码通过
GmailApp.search("label:" + folder.getName())获取标签下的线程,但对于带空格的标签名(如[Gmail]/Sent Items)或系统内置标签,该搜索语法会失效,导致无法找到任何线程,统计结果全为0。 - 邮件大小计算冗余且不准确:原代码手动累加原始内容长度与附件大小,不仅重复计算(原始内容已包含附件的编码数据),还可能因字符编码问题导致字节数统计偏差。
修复后的完整代码
function getGmailFoldersWithStorageSize() { var folders = GmailApp.getUserLabels(); var foldersWithSize = []; for (var i = 0; i < folders.length; i++) { var folder = folders[i]; var folderName = folder.getName(); var folderSize = getFolderStorageSize(folder); var folderSizeMB = folderSize / (1024 * 1024); var folderSizeGB = folderSize / (1024 * 1024 * 1024); var folderMessageCount = getFolderMessageCount(folder); foldersWithSize.push([folderName, folderMessageCount, folderSizeMB.toFixed(2) + " MB", folderSizeGB.toFixed(2) + " GB"]); } Logger.log(foldersWithSize); return foldersWithSize; } function getFolderStorageSize(folder) { var threads = folder.getThreads(); // 直接通过标签对象获取线程,避免搜索语法错误 var totalSize = 0; for (var i = 0; i < threads.length; i++) { var messages = threads[i].getMessages(); for (var j = 0; j < messages.length; j++) { totalSize += messages[j].getSize(); // 使用内置方法直接获取邮件总大小(含附件) } } return totalSize; } function getFolderMessageCount(folder) { var threads = folder.getThreads(); // 直接通过标签对象获取线程 var messageCount = 0; for (var i = 0; i < threads.length; i++) { messageCount += threads[i].getMessageCount(); // 使用内置方法直接获取线程内消息数,更高效 } return messageCount; }
关键修复点说明
- 替换
GmailApp.search为folder.getThreads():直接从标签对象获取关联线程,彻底解决搜索语法错误问题,支持所有类型的标签(包括系统内置标签、带空格/特殊字符的标签)。 - 用
message.getSize()替代手动计算:该方法由Google提供,直接返回邮件的总字节大小(包含邮件正文、附件等所有内容),准确且高效。 - 用
thread.getMessageCount()替代遍历消息:减少循环层级,提升统计效率。
后续需求:按月份统计的实现思路
要实现按月份分组统计,只需在遍历消息时提取邮件的发送时间,格式化为MMM-YYYY格式(如Jan-2023),然后按「标签+月份」维度分组累加数据:
- 定义一个对象存储分组统计结果,键为
标签名|月份,值为包含消息数、总大小的对象。 - 在遍历消息时,获取
message.getDate(),用Utilities.formatDate()将日期格式化为MMM-YYYY。 - 根据当前标签和月份更新统计对象中的计数与大小。
- 最终将统计对象转换为数组格式输出。
示例代码片段(可整合到修复后的代码中):
// 按月份统计的核心逻辑示例 function getMonthlyFolderStats() { var folders = GmailApp.getUserLabels(); var monthlyStats = {}; for (var i = 0; i < folders.length; i++) { var folder = folders[i]; var folderName = folder.getName(); var threads = folder.getThreads(); for (var t = 0; t < threads.length; t++) { var messages = threads[t].getMessages(); for (var m = 0; m < messages.length; m++) { var msg = messages[m]; var date = msg.getDate(); // 格式化月份为Jan-2023格式(注意时区,可根据需求调整) var monthKey = Utilities.formatDate(date, "GMT", "MMM-yyyy"); var statsKey = `${folderName}|${monthKey}`; if (!monthlyStats[statsKey]) { monthlyStats[statsKey] = { messageCount: 0, totalSize: 0 }; } monthlyStats[statsKey].messageCount++; monthlyStats[statsKey].totalSize += msg.getSize(); } } } // 转换为易读的数组格式 var result = []; for (var key in monthlyStats) { var [folder, month] = key.split("|"); var stats = monthlyStats[key]; var sizeMB = (stats.totalSize / (1024*1024)).toFixed(2); var sizeGB = (stats.totalSize / (1024*1024*1024)).toFixed(2); result.push([folder, month, stats.messageCount, `${sizeMB} MB`, `${sizeGB} GB`]); } Logger.log(result); return result; }
内容的提问来源于stack exchange,提问作者naren
相关产品推荐
相关产品推荐

