I have something like this hacked up. I probably based it off something someone else wrote, but it was so long ago I don't remember.
It has chugged away reliably since. Here's how it works:
Generally, it looks for messages with certain tags and then replaces that tag with another and then archives them.
Specifically, messages are tagged with inbox filters to indicate how they will be "expired." In the example below this is based on how old they are, and the label is called Bulk/Expires/[Daily|Weekly|Monthly]
. (Note: this is a nested tag, but they don't need to be nested, I just like to keep them organized like this). Every day some Google Apps Scripts will run to check if threads within those labels match some condition, generally a date. It will then replace that tag with another tag (called Bulk/Expired
below) and archive it. You could also just have it delete the message.
This is code (with extra comments) which will clean up messages more than a day old. It's setup to trigger every day at like 4am:
function cleanUpDaily() {
// Enter # of days before messages are archived
var delayDays = 1
// make an empty Date() object
var maxDate = new Date();
// Set that date object ('maxDate')to the current data minus 'delayDays'.
// In this case it's a date 1 day before the time when this runs.
maxDate.setDate(maxDate.getDate()-delayDays);
// this is the label that finds messages eligible for this filter
var currLabel = GmailApp.getUserLabelByName("Bulk/Expires/Daily");
// this is the new label so I know a message has already been "Expired"
var newLabel = GmailApp.getUserLabelByName("Bulk/Expired");
// Get the message threads which might need to be expired.
var threads = currLabel.getThreads();
// Iterate over those threads and check if they need to be expired
for (var i = 0; i < threads.length; i++) {
// You can put whatever kinds of conditions in here,
// but this is just going to check if they were recieved before
// 'maxDate' which here is 1 day before runtime.
if (threads[i].getLastMessageDate()<maxDate)
{
// If they're old, archive them
threads[i].moveToArchive();
// Remove the old label, they won't need to be expired again
// This isn't required, but it will make it slow, and Google will
// time-out things that take too long, in my experaince it will
// become slow and start timing out if there are more than a few
// dozen threads to process, YMMV.
threads[i].removeLabel(currLabel);
// Label the thread with a new label indicating it's gone through this
// process. Also not strictly necessary, but it's useful if you'd like
// to do some more processing on them in the future.
threads[i].addLabel(newLabel);
}
}
}
Here's the code for doing this for things which should expire in a week or a month, you setup triggers to run these functions either weekly or monthly.
function cleanUpWeekly() {
var delayDays = 7 // Enter # of days before messages are moved to archive
var maxDate = new Date();
maxDate.setDate(maxDate.getDate()-delayDays);
var currLabel = GmailApp.getUserLabelByName("Bulk/Expires/Weekly"); // this is the label that finds messages eligible for this filter
var newLabel = GmailApp.getUserLabelByName("Bulk/Expired"); // this is the new label so I know a message was expired and thats why its archived
var threads = currLabel.getThreads();
for (var i = 0; i < threads.length; i++) {
if (threads[i].getLastMessageDate()<maxDate)
{
threads[i].moveToArchive();
threads[i].removeLabel(currLabel); // I take the label off so there's not an infinitely growing "threads" variable with time
threads[i].addLabel(newLabel);
}
}
}
function cleanUpMonthly() {
var delayDays = 30 // Enter # of days before messages are moved to archive
var maxDate = new Date();
maxDate.setDate(maxDate.getDate()-delayDays);
var currLabel = GmailApp.getUserLabelByName("Bulk/Expires/Monthly"); // this is the label that finds messages eligible for this filter
var newLabel = GmailApp.getUserLabelByName("Bulk/Expired"); // this is the new label so I know a message was expired and thats why its archived
var threads = currLabel.getThreads();
for (var i = 0; i < threads.length; i++) {
if (threads[i].getLastMessageDate()<maxDate)
{
threads[i].moveToArchive();
threads[i].removeLabel(currLabel); // I take the label off so there's not an infinitely growing "threads" variable with time
threads[i].addLabel(newLabel);
}
}
}
Right now I'm working on one which will take the Bulk/Expired
messages and if they have a Purge
tag it will delete them permanently. I'm disinclined to ever delete an email (crazy), but lots of archived mailing list things tend to pollute search results. This annoyance has started to overwhelm my digital hoarding tendencies. The only change is that the for
loop checks to see if a message has the 'Purge' tag. This is not trivial, because the labels a given thread has are returned as an array, and so I have to check that array which will add a few lines of code. Unless I find some slicker way.
I mainly use this to manage newsletters with Google Inbox. I setup a message bundle for the `Bulk/Expires/Daily' tag, and the filter makes sure only today's newsletter is there. Then whether I read it on a given day or not, the latest is there. It's kinda like hacking Inbox into an RSS reader. I do the same thing for regular newsletters/bulk mailings which come out weekly or monthly. Generally I expire them when their age removes their relevance.