Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Here's a gmail extractor google apps script that does the same thing, but for not $30!

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 < threads.length; i++) {
      const messages = threads[i].getMessages();
      for (let j = 0; j < messages.length; j++) {
        const attachments = messages[j].getAttachments();
        for (let k = 0; k < attachments.length; k++) {
          const attachment = attachments[k];
          const name = attachment.getName().toLowerCase();
          const type = attachment.getContentType();
          const size = attachment.getSize();
          
          // Apply size threshold (102,400 bytes = 100KB) and file type filter
          if (size > 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]); } } }



Clever. But Gmail and Google Drive share the exact same 15 gb storage quota. If a user has 10 gigs of photos in their Gmail and runs this script, it'll create another 10 gb of files in their Drive.

Instead of saving space, this script doubles their storage usage to 20 gb, breaking through the 15 gb free tier and forcing them to buy a Google One subscription.

That’s one of the reasons this desktop app exists, it streams the files straight to your hard drive so you can avoid this


> breaking through the 15 gb free tier and forcing them to buy a Google One subscription

Which is like... $2 for 100GB and you can cancel immediately after, or if you get the same offer I got: $0.50.

$27 in savings and 100GB of storage, sounds like a good deal to me!


I'm stuck enough in the gecosystem that the storage is of small worry there but good point. It's a cute idea for the main topic - I saw some pictures I'd forgotten about for 20 years so that was fun.




Consider applying for YC's Fall 2026 batch! Applications are open till July 27.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: