Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
function gmailAutoarchive() {
var delayDays = 2; // will only impact emails more than 48h old
var maxDate = new Date();
maxDate.setDate(maxDate.getDate()-delayDays); // what was the date at that time?
// Get all the threads labelled 'autoarchive'
var label = GmailApp.getUserLabelByName("autoarchive");
var threads = label.getThreads(0, 400);
// we archive all the threads if they're unread AND older than the limit we set in delayDays
for (var i = 0; i < threads.length; i++) {
if (threads[i].getLastMessageDate()<maxDate)
{
threads[i].moveToArchive();
}
}
}
@kamermans

This comment has been minimized.

Copy link

kamermans commented Jan 30, 2017

Instead of moving them one by one like you're doing:

  var threads = label.getThreads(0, 400);

  // we archive all the threads if they're unread AND older than the limit we set in delayDays
  for (var i = 0; i < threads.length; i++) {
    if (threads[i].getLastMessageDate()<maxDate)
    {
      threads[i].moveToArchive();
    }
  }

You can alternatively move them in large batches (up to 100) like this:

  var threads = label.getThreads(0, 400).filter(function(thread) {
    // Only include threads older than the limit we set in delayDays
    return (thread.getLastMessageDate() < maxDate);
  });

  var batch_size = 100;
  while (threads.length) {
    var this_batch_size = Math.min(threads.length, batch_size);
    var this_batch = threads.splice(0, this_batch_size);
    GmailApp.moveThreadsToArchive(this_batch);
  }
@jason-riddle

This comment has been minimized.

Copy link

jason-riddle commented Feb 28, 2017

In addition to the above tweak, add a check to see if label is null or undefined.

function gmailAutoarchive() {
  
  var delayDays = 2; // will only impact emails more than 48h old
  var maxDate = new Date();
  maxDate.setDate(maxDate.getDate()-delayDays); // what was the date at that time?

  // Get all the threads labelled 'autoarchive'
  var label = GmailApp.getUserLabelByName("autoarchive");
  if (label == null || label == undefined) return -1; 
  
  var threads = label.getThreads(0, 400).filter(function(thread) {
    // Only include threads older than the limit we set in delayDays
    return (thread.getLastMessageDate() < maxDate);
  });
  
  var batch_size = 100;
  while (threads.length) {
    var this_batch_size = Math.min(threads.length, batch_size);
    var this_batch = threads.splice(0, this_batch_size);
    GmailApp.moveThreadsToArchive(this_batch);
  }
}
@GabeBenjamin

This comment has been minimized.

Copy link

GabeBenjamin commented May 6, 2017

Made some tweaks based on some of the suggestions above and also adding the ability to have different labels for different number of days: https://gist.github.com/GabeBenjamin/3ef20889fa37ae97e9492e58e90db892

@soxofaan

This comment has been minimized.

Copy link

soxofaan commented Oct 11, 2017

Thanks for the inspiration.
My script to autodelete old threads with different lifetimes is here: https://gist.github.com/soxofaan/92fab6776c1bfcac060544ba0c9dd59c

@hcon94

This comment has been minimized.

Copy link

hcon94 commented Oct 17, 2017

Made one that just archives all labeled threads:

function gmailAutoarchive() {
  // Get all the threads that are labelled
  var labels = GmailApp.getUserLabels();
  for (var a = 0; a < labels.length; a++) {
    var threads = labels[a].getThreads(0, 400);
    // Archive all the labelled threads
    for (var i = 0; i < threads.length; i++) {
      threads[i].moveToArchive();
    }
  }
}
@lawson2305

This comment has been minimized.

Copy link

lawson2305 commented Nov 20, 2017

I'm having an issue and it appears to be because I have nested labels. Can someone assist with how to properly enter a nested label? If I search the label if finds the email but the script itself does not work.
Example of nested label:
Archive
Sunday

Archive-Sunday - is how Google handles it in a search.
var label = GmailApp.getUserLabelByName("archive-sunday");

I found this and will be testing:
http://www.skipser.com/p/2/p/auto-delete-email-in-any-gmail-label-.html
"TIP: If your label is a nested label, you need to give it in the format "parent/child" where "parent" is the main label and "child" is the nested label."

Initial testing the above tip does not change the behavior. This may not be the issue I do not know. I have tried multiple versions of the script and the only difference is my labels and I just can't seem to get the scripts to actually archive mail.

@stephcoding

This comment has been minimized.

Copy link

stephcoding commented Apr 17, 2018

Thank you so much for help

@mrdlcastle

This comment has been minimized.

Copy link

mrdlcastle commented Jul 6, 2018

Thanks for this, I tweaked it for my needs and it is available here
Archives any read message that is older than 24 hours.

@simon57nz

This comment has been minimized.

Copy link

simon57nz commented Sep 8, 2018

I used a set of labels nested under a parent "autoarchive" and added the following into my fuction:

var labels = GmailApp.getUserLabels();
for (var a = 0; a < labels.length; a++) {
var curr_label = labels[a].getName();
var curr_label_parts = curr_label.split("/");
if (curr_label_parts[0] == "autoarchive") {
...// rest of archive function
}
}

@akamyshanov

This comment has been minimized.

Copy link

akamyshanov commented Sep 18, 2018

Or just leverage GMail's built in search features:

var threads = GmailApp.search("in:inbox label:auto-archive older_than:2d");

https://gist.github.com/akamyshanov/88e0bfa936296d14febe4cb7d5c37c78

@jaseinatl

This comment has been minimized.

Copy link

jaseinatl commented Apr 13, 2019

I would like to do something similar, but I only want threads that I have read. Is there a way to filter read messages?

@ukmercanary

This comment has been minimized.

Copy link

ukmercanary commented Apr 14, 2019

Cool script two questions first is this script safe as with respect it looks like we are giving permissions to a stranger on the internet!
Next, how do we set it to archive more than 400 older emails? I have going back to 2018 which need archiving.

@codeslubber

This comment has been minimized.

Copy link

codeslubber commented Apr 15, 2019

Script runs for me, and then there are clearly items with the autoarchive tag that are older than 2d. What a joke.

@codeslubber

This comment has been minimized.

Copy link

codeslubber commented Apr 15, 2019

Got this to work. The filter method suggested by @akamyshanov works. Wrote a single line in the script that applied the filter then output the match count. Then dropped into the loop and archived the ones that were found. The tools could be a lot better, jeez. ANyway thanks for this.

@superfawkes

This comment has been minimized.

Copy link

superfawkes commented Jun 30, 2019

Thank you! I've adapted it into a more generic cleanup script - the initial setup needs a bit of personal tweaking...
Edit - too many versions. I've added my gist here

@CognitiveCaesar

This comment has been minimized.

Copy link

CognitiveCaesar commented Jul 14, 2019

Thanks for this, I tweaked it for my needs and it is available here
Archives any read message that is older than 24 hours.

Hi mrdlcastle
Thank you for the tweaked version of the script .
However, shouldn't the last message be greater than max date? #14 of your script.

@superfawkes

This comment has been minimized.

Copy link

superfawkes commented Jul 14, 2019

@CognitiveCaesar Messages more X days old is the same as date of message < today - X days.

@CognitiveCaesar

This comment has been minimized.

Copy link

CognitiveCaesar commented Jul 14, 2019

@superfawkes thanks for clearing that up. My script was not working according to plan, so I thought that it might have something to do with the setup. However, once you pointed out the concept, I checked the trigger and found that its execution has failed for some reason. Still don't know why. But the script itself, once manually run, works fine.

@KamiinBlack

This comment has been minimized.

Copy link

KamiinBlack commented Oct 2, 2019

I used a set of labels nested under a parent "autoarchive" and added the following into my fuction:

var labels = GmailApp.getUserLabels();
for (var a = 0; a < labels.length; a++) {
var curr_label = labels[a].getName();
var curr_label_parts = curr_label.split("/");
if (curr_label_parts[0] == "autoarchive") {
...// rest of archive function
}
}

If you have nested labels just use :
var threads = GmailApp.search("in:inbox label:label_parent-label_child1-label_child2"); ("-" -> use this as 'conector' between nested labels)

If you want to archive only read email add this code to condtition:
if (threads[i].isUnread()==false)

@dkim457

This comment has been minimized.

Copy link

dkim457 commented Oct 15, 2019

Is there a way to tweak this where it'll auto archive an email to a specific label, but only after it's been read by the user?

@KamiinBlack

This comment has been minimized.

Copy link

KamiinBlack commented Oct 15, 2019

Is there a way to tweak this where it'll auto archive an email to a specific label, but only after it's been read by the user?

I have put this piece of additional cide in my previous post ( use function isUnread() ) ->
If you want to archive only read email add this code to condition:
if (threads[i].isUnread()==false)

@joshkadis

This comment has been minimized.

Copy link

joshkadis commented Apr 25, 2020

I definitely overthought by this by a lot! But here's a version with the option to set different cutoff days per label. (Note that it maxes at 100 threads and doesn't batch them.)

// Will be checked against lowercased label names
var autoarchiveLabels = {
  newsletters: 2
};

// Get cutoff date for a specific label
function labelDelayDate(labelName) {
  if (!autoarchiveLabels[labelName.toLowerCase()]) {
    return false;
  }
  var delayDays = autoarchiveLabels[labelName.toLowerCase()];
  var maxDate = new Date();
  maxDate.setDate(maxDate.getDate() - delayDays);
  return maxDate;
}

// Archive thread after cutoff dat
function shouldArchive(thread, label) {
  var maxDate = labelDelayDate(label.getName());
  if (!maxDate) {
    return false;
  }
  
  // Being in the inbox already is implicit but helps with logging
  // on the threads that are affected
  var shouldArchive = thread.getLastMessageDate() < maxDate && thread.isInInbox();

  if (shouldArchive) {
    Logger.log('Will archive: ' + thread.getFirstMessageSubject());
  }

  return shouldArchive;
}

// Check threads against cutoff date and archive them
function archiveLabel(label) {    
  Logger.log('Archiving ' + label.getName());
  var threads = label.getThreads(0, 100).filter(
    function (thread) { return shouldArchive(thread, label) }
  );
  Logger.log('Found ' + threads.length + ' archivable threads');
  if (threads.length) {
    GmailApp.moveThreadsToArchive(threads);
  }
}

// Find archivable labels
function gmailAutoarchive() {  
  var labels = GmailApp.getUserLabels();
  for (var i = 0; i < labels.length; i++) {
    var label = labels[i];
    if (Object.keys(autoarchiveLabels).indexOf(label.getName().toLowerCase()) !== -1) {
      archiveLabel(label);
    }
  }
}

https://gist.github.com/anonymous/2cca33d376f7f924fdaa67891ad098cc

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.