Skip to content

Instantly share code, notes, and snippets.

Created January 8, 2017 16:39
Show Gist options
  • Star 74 You must be signed in to star a gist
  • Fork 13 You must be signed in to fork a gist
  • Save anonymous/2cca33d376f7f924fdaa67891ad098cc to your computer and use it in GitHub Desktop.
Save anonymous/2cca33d376f7f924fdaa67891ad098cc to your computer and use it in GitHub Desktop.
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();
}
}
}
@KamiinBlack
Copy link

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
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

@franprince
Copy link

franprince commented Sep 15, 2020

I slightly modified the original script because I needed to archive threads after a couple of hours.

function gmailAutoarchive() {
  var hours = 3600000;
  var days = 86400000;
  var delay = 4 * hours;  //Select quantity and time unit i.e. 7 days
  var maxDate = new Date();
  maxDate.setTime(maxDate.getTime()-delay); 

  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);
  }
}

@jututt
Copy link

jututt commented Nov 18, 2020

Here's my version taking care of all inbox email, irrespective of the label

function gmailAutoarchive() {
  
  var delayDays = 3; // only impact emails older than 3 days
  var maxDate = new Date();
  maxDate.setDate(maxDate.getDate()-delayDays); // what was the date at that time?

  // Get all inbox threads
  var threads = GmailApp.getInboxThreads();
  
  // archive all the threads older than the limit set in delayDays
  for (var i = 0; i < threads.length; i++) {
    if (threads[i].getLastMessageDate()<maxDate)
    {
      threads[i].moveToArchive();
    }
  }
}

@ChristiaanScheermeijer
Copy link

A small addition to @jututt's version, this will not auto archive "starred" and "important" threads:

function gmailAutoarchive() {
  
  var delayDays = 3; // only impact emails older than 3 days
  var maxDate = new Date();
  maxDate.setDate(maxDate.getDate()-delayDays); // what was the date at that time?

  // Get all inbox threads
  var threads = GmailApp.getInboxThreads();
  
  // archive all the threads older than the limit set in delayDays which are not marked as imported or have starred messages
  for (var i = 0; i < threads.length; i++) {
    if (threads[i].getLastMessageDate()<maxDate && !threads[i].isImportant() && !threads[i].hasStarredMessages()) {
      threads[i].moveToArchive();
    }
  }
}

@matthewoden
Copy link

Has anyone run into an issue where you have to reauthenticate weekly?

@dancapper
Copy link

Hi all, after playing around with this I came up with a more efficient version which uses search to find all affected threads instead of iterating through threads belonging to the label. Hope it helps someone.

Replace moveThreadsToArchive with moveThreadsToTrash if you want to trash the threads instead.

function gmailAutoarchive() {
  
  var rules = { // Each label with number of days to keep
    "billsbillsbills" : 2,
    "newslettersandstuff" : 28
  }

  var batch_size = 100;

  for (let label in rules) {
    
    var keepdays = rules[label];
  
    Logger.log(`Archiving all threads in ${label} older than ${keepdays} Days`);

    var threads = GmailApp.search(`label:${label} older-than:${keepdays}d`);

    Logger.log(`Identified ${threads.length.toString()} threads for archival in ${label}`);

    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);
    }
  }
}

@BLiTyvr
Copy link

BLiTyvr commented Jul 17, 2021

Hi all, after playing around with this I came up with a more efficient version which uses search to find all affected threads instead of iterating through threads belonging to the label. Hope it helps someone.

Replace moveThreadsToArchive with moveThreadsToTrash if you want to trash the threads instead.

function gmailAutoarchive() {
  
  var rules = { // Each label with number of days to keep
    "billsbillsbills" : 2,
    "newslettersandstuff" : 28
  }

  var batch_size = 100;

  for (let label in rules) {
    
    var keepdays = rules[label];
  
    Logger.log(`Archiving all threads in ${label} older than ${keepdays} Days`);

    var threads = GmailApp.search(`label:${label} older-than:${keepdays}d`);

    Logger.log(`Identified ${threads.length.toString()} threads for archival in ${label}`);

    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);
    }
  }
}

Note that the search operator is older_than: not older-than:
per https://support.google.com/mail/answer/7190?hl=en

Otherwise, this code works well. :) Thanks @dancapper

@dancapper
Copy link

Thanks @BLiTyvr - quite right. I fixed this in my code when I noticed it wasn't working, but forgot to come back and update my comment.

You can find my final version at https://github.com/dancapper/gmailArchiveScript/ if it's a help to anyone, I made it easier to update the rules to suit your needs, and set a flag to archive or trash the matching threads.

@maheshmnj
Copy link

Hey, can someone please tell me does labelling an email would move it from the inbox?
Let's say I am getting emails from a particular email everyday email@example.com, I would like to keep them under the label example and don't want to see them in my inbox.

@franprince
Copy link

franprince commented Aug 25, 2021

Hey, can someone please tell me does labelling an email would move it from the inbox?
Let's say I am getting emails from a particular email everyday email@example.com, I would like to keep them under the label example and don't want to see them in my inbox.

You can do that using filters on Gmail, no need for a script. Just adding a label won't move it from the inbox, you need to archive it too.
https://support.google.com/mail/answer/6579?hl=en#zippy=%2Ccreate-a-filter

@maheshmnj
Copy link

maheshmnj commented Aug 26, 2021

Thanks, @fanprince its working beautifully.

@giftedsiege
Copy link

do you know if this impact snoozed emails? (let's say an email that older than 2 days that has been snoozed to reappear in two weeks)

@blhoward2
Copy link

blhoward2 commented Apr 22, 2023

Hi all, after playing around with this I came up with a more efficient version which uses search to find all affected threads instead of iterating through threads belonging to the label. Hope it helps someone.

Replace moveThreadsToArchive with moveThreadsToTrash if you want to trash the threads instead.

function gmailAutoarchive() {
  
  var rules = { // Each label with number of days to keep
    "billsbillsbills" : 2,
    "newslettersandstuff" : 28
  }

  var batch_size = 100;

  for (let label in rules) {
    
    var keepdays = rules[label];
  
    Logger.log(`Archiving all threads in ${label} older than ${keepdays} Days`);

    var threads = GmailApp.search(`label:inbox label:${label} older-than:${keepdays}d`);

    Logger.log(`Identified ${threads.length.toString()} threads for archival in ${label}`);

    while (threads.length) {
      var this_batch_size = Math.min(threads.length, batch_size);
      var this_batch = threads.splice(0, this_batch_size);
      GmailApp.markThreadsRead(this_batch);
      GmailApp.moveThreadsToArchive(this_batch);
    }
  }
}

I know this is very old, but if anyone else finds this you're actually reprocessing all of the archived emails every time. Adding label:inbox limits the search to the emails not already archived. I've modified the above to do that, and also to mark the messages as read while moving them.

@Avocadososemix
Copy link

Thank you for the solutions everyone. I had to change older-than to older_than in @blhoward2's solution and it worked perfectly.

function gmailAutoarchive() {
  
  var rules = { // Each label with number of days to keep
    "autoarchive" : 2,
    "newslettersandstuff" : 28
  }

  var batch_size = 100;

  for (let label in rules) {
    
    var keepdays = rules[label];
    Logger.log(`Archiving all threads in ${label} older than ${keepdays} Days`);

    var threads = GmailApp.search(`label:inbox label:${label} older_than:${keepdays}d`);

    Logger.log(`Identified ${threads.length.toString()} threads for archival in ${label}`);

    while (threads.length) {
      var this_batch_size = Math.min(threads.length, batch_size);
      var this_batch = threads.splice(0, this_batch_size);
      GmailApp.markThreadsRead(this_batch);
      GmailApp.moveThreadsToArchive(this_batch);
    }
  }
}

@101legend101
Copy link

Hey, i am looking to archive all my "read" mails which have "user labels" after 2 days, can anyone help with that?. i want to do it for all mails user labels instead of doing individually for all the labels i have. i also do not want to create a separate label to use as an archived inbox if possible. if not i will go this way

@bo33b
Copy link

bo33b commented Feb 21, 2024

@101legend101 this is my approach, quite simple really. Cheers.

function gmailAutoarchive() {

  // Build the query
  var query = "in:inbox is:read has:userlabels older_than:2d";
  
  // Get the threads
  var threads = GmailApp.search(query);
  
  // Archive the threads
  for (var thread of threads) thread.moveToArchive();

}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment