function autoExtractGmailMedia() { const START_TIME = Date.now(); const TIME_LIMIT = 1000 * 60 * 5; // 5 minutes (leaves a 1-minute safety buffer) const BATCH_SIZE = 50; const FOLDER_NAME = "Gmail_Media_Export";
// 1. Retrieve our current position from the script's property store
const scriptProperties = PropertiesService.getScriptProperties();
let startIndex = parseInt(scriptProperties.getProperty('START_INDEX')) || 0;
// Locate or create the destination folder
let folder;
const folders = DriveApp.getFoldersByName(FOLDER_NAME);
if (folders.hasNext()) {
folder = folders.next();
} else {
folder = DriveApp.createFolder(FOLDER_NAME);
}
// 2. Process batches in a loop
// Updated search query to ignore USPS and non-primary tabs
const searchQuery = 'has:attachment -from:usps.gov -category:promotions -category:updates -category:social (filename:jpg OR filename:jpeg OR filename:png OR filename:zip)';
while (true) {
const threads = GmailApp.search(searchQuery, startIndex, BATCH_SIZE);
// If the search returns empty, we've hit the end of the inbox
if (threads.length === 0) {
console.log("Extraction completely finished.");
scriptProperties.deleteProperty('START_INDEX');
deleteTriggers(); // Clean up so it doesn't keep running
return;
}
for (let i = 0; i 102400) {
if (type.includes('image/') || name.endsWith('.zip')) {
folder.createFile(attachment);
}
}
}
}
}
// Increment our starting index for the next batch
startIndex += BATCH_SIZE;
// 3. The Stopwatch Check
if (Date.now() - START_TIME > TIME_LIMIT) {
console.log(`Approaching timeout at index ${startIndex}. Saving state and passing the baton...`);
scriptProperties.setProperty('START_INDEX', startIndex.toString());
scheduleNextRun();
return; // Exit to avoid the hard timeout exception
}
}
}function scheduleNextRun() { deleteTriggers(); // Prevent duplicate overlapping triggers ScriptApp.newTrigger("autoExtractGmailMedia") .timeBased() .after(60 * 1000) // Fire a new execution 1 minute from now .create(); }
function deleteTriggers() { const triggers = ScriptApp.getProjectTriggers(); for (let i = 0; i < triggers.length; i++) { if (triggers[i].getHandlerFunction() === "autoExtractGmailMedia") { ScriptApp.deleteTrigger(triggers[i]); } } }