I have created a script that will delete messages over 400 days old (approx 13 months). I have searched the available GS help and cannot find a method of getting a handle to the "All Mail" folder, which is where I want to delete the messages from. Is there a way to do this that I am not seeing?
-
I think you can use `getUserLabelByName()` [Google Documentation](https://developers.google.com/apps-script/reference/gmail/gmail-app#getUserLabelByName(String)) Gmail doesn't call a folder a folder, it's a "label" – Alan Wells Jun 24 '15 at 19:51
-
2@SandyGood - "All messages" isn't a "User Label", so it's not accessible this way. However, very important distinction between labels & folders! – Mogsdad Jun 24 '15 at 21:16
-
I have been trying to get around this problem since yesterday and "s l o w l y" realized the key word in the function is USER. I also found that all Google labels are accessible except All Mail and Sent. There are GET functions for Spam and Trash. Go figure that you can get to the stuff you don't want (and gets deleted in 30 days) and can't get to the stuff you do want. – Bob Vezzuso Jun 25 '15 at 22:08
4 Answers
Perform a search. It works in the same way as the GMail UI.
var threads = GmailApp.search('older_than:400d … plus whatever other criteria you want');
It will give the same results as GMail i.e. using All Mail as the search repository.
If you want to find mail that hasn't been filed into any labels then ad 'has:nouserlabels'
as a criteria, but beware threads are tricksy fellows particularly when filters have auto labeled incoming messages in a conversation without labels etc.
This call may require paging if it is likely to return large numbers of results.
Update
Loop through results checking that the last message in each thread returned also meets your age criteria using .getLastMessageDate()

- 3,966
- 4
- 32
- 52
-
That give threads, not messages. A thread's age is determined by the oldest message, so the result may include new messages. With each thread, you'd need to examine each message individually to ensure it met your age criteria. – Mogsdad Jun 24 '15 at 21:16
-
1True. Though as the intent is likely to be to leave the entire thread intact if it contains a newer message you only have to check one message from each thread. Answer amended. – JSDBroughton Jun 24 '15 at 21:19
-
Thanks for the info and heads up. I will test this to make sure I don't fall in to any these traps. – Bob Vezzuso Jun 25 '15 at 22:17
In GMail, "All Mail" isn't a folder, and it isn't a user label either. It's just, well, all your mail.
If your goal is to identify all messages that are of a certain age, there is no method in the GMail Service to do so. However, you can use the GMail API to list all messages, and by supplying a query string you can filter the results.
Here's a function that does just that. Be warned, though... it can exhaustively list all your messages, and if there are enough of them it will exceed your execution limits.
/**
* Retrieve Messages in user's mailbox matching query.
*
* @param {String} query String used to filter the Messages listed.
* @param {String} userId (optional) User's email address. Default: The special
* value 'me' is used to indicate the authenticated user.
*/
function listMessages(query, userId) {
query = query || '';
userId = userId || 'me';
var msglist = [];
// see https://developers.google.com/gmail/api/v1/reference/users/messages/list
var url = 'https://www.googleapis.com/gmail/v1/users/${userId}/messages'
.replace("${userId}", userId) // The user's email address. The special value me can be used to indicate the authenticated user.
var headers = {
Authorization: 'Bearer ' + ScriptApp.getOAuthToken()
};
var request = {
'q': query
};
var params = {
method: "get",
contentType: "application/json",
headers: headers,
muteHttpExceptions: true
};
do {
// For GET, params must be URI Encoded in URL.
var urlPlus = url + "?" + serializeParams(request);
//var check = UrlFetchApp.getRequest(urlPlus, params); // for debugging
var response = UrlFetchApp.fetch(urlPlus, params);
var result = response.getResponseCode();
if (result == '200') { // OK
var resp = JSON.parse(response.getContentText());
msglist = msglist.concat(resp.messages);
request.pageToken = resp.nextPageToken;
} else {
// This is only needed when muteHttpExceptions == true
var err = JSON.parse(response.getContentText());
throw new Error('Error (' + result + ") " + err.error.message);
}
} while (resp.nextPageToken);
return msglist;
}
// From http://stackoverflow.com/a/23639793
function serializeParams( obj ) {
var str = Object.keys(obj).map(function(key) {
return key + '=' + obj[key];
}).join('&');
return encodeURIComponent(str);
}
So your deletion function becomes something like this:
function deleteOldMessages( ageInDays ) {
if (!ageInDays || typeof ageInDays !== "number")
throw new TypeError( "Expecting number" );
// Build query and get all matching messages
var query = "older_than:{$age}d".replace("{$age}",ageInDays);
var messages = listMessages(query);
for (var i=0; i<messages.length; i++) {
GmailApp.getMessageById(messages[i].id).moveToTrash();
}
}

- 44,709
- 21
- 151
- 275
-
technically much better than my answer, though doesn't address the A/B problem of thread fidelity vs. exact rule observation – JSDBroughton Jun 25 '15 at 11:22
-
@Jonathon - whachutalkinaboutwillis? (I sense a learning opportunity...) – Mogsdad Jun 25 '15 at 12:29
-
Meaning it is the correct solution to what they asked i.e. the OP asks for a way to delete all messages over a particular age. so the answer above shows elegantly how this might be done. The unasked question of "why you'd want to be doing that?" might reveal that the technical solution being sought may not address the real problem even if complete and correct. I suspect deleting all messages over a days-old criteria may not be a great solution to a problem I'm guessing the OP has. http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem < XY problem AB problem, you say tomato etc. – JSDBroughton Jun 25 '15 at 12:36
-
@Jonathon - Ah, bingo. "Why isn't there a solution for _this_?" "Because _that_ isn't the problem." – Mogsdad Jun 25 '15 at 13:16
-
Thanks for the information and the code. I will look in to retrofitting this in to my code and hopefully get the result I'm looking for. The reason for this is that, since day one of my using e-mail (early 1990's with company based private e-mail system) anything over 14 months is useless. It removes clutter and keeps the mailbox to a minimum. It's a personal thing with a touch of OCD ... (smile) – Bob Vezzuso Jun 25 '15 at 22:15
-
old mail may be useless for day to day tasks, but its important as historical backup. sometimes you do need to dig a 2year old email. – Zig Mandel Jun 26 '15 at 13:23
Thanks for the info. Was able to build a function that does exactly what I want.
function delOldMail() {
var email = Session.getActiveUser().getEmail();
var subject = 'GS delOldMail: ' + Session.getActiveUser();
var body = 'Messages Deleted:';
var breakPoint = 50;
var breakCntr = 0;
var threads = GmailApp.search('!is:starred older_than:400d');
if (threads.length > 0) {
for (var delCntr = 0; delCntr < threads.length; delCntr++) {
var message = threads[delCntr].getMessages()[0];
var messageId = message.getId();
var messageById = GmailApp.getMessageById(messageId);
var messagedate = messageById.getDate();
var seqnum = "0000" + delCntr;
var seqstrt = seqnum.length - 4;
var body = body + "\n threads: " + seqnum.substr(seqstrt,4) + " " + threads[delCntr].getFirstMessageSubject() + ':::' + messagedate;
if (breakCntr = breakPoint) {
breakPoint = breakPoint + 50
Utilities.sleep(1000);
}
var breakCntr = breakCntr++
threads[delCntr].moveToTrash();
}
} else {
var body = body + '\n Nothing to delete today ...';
}
GmailApp.sendEmail(email, subject, body);
}

- 21
- 4
-
-
Just an old habit from the days I was a Lotus Notes developer to keep my mailbox to a minimum. When I need to see the oldest messages, I don't want to search back too far. – Bob Vezzuso Jul 12 '15 at 16:29
-
I guess I'm comfortable with the GMail way of archive not delete coupled with boolean search. – JSDBroughton Jul 15 '15 at 04:03
For bulk processing of mail, it's best to use the complete aka "Advanced" Gmail api. Make sure this is enabled first under "Resources->Advanced Google Services".
// set MAX_RUNS according to 6min script execution limit
var MAX_RUNS=1;
var MAX_RESULTS = 10;
function ScanMessages() {
var messageList = {'nextPageToken' : null};
for(var i = 0; i < MAX_RUNS; i++){
var options = {
maxResults: MAX_RESULTS,
// set this to your desired date range
q: 'before after:2015/12/25 before:2016/1/1'
};
// init nextPageToken
if(messageList.nextPageToken != null){
options.pageToken = messageList.nextPageToken;
}
// Use the "advanced" Gmail API to get messages directly.
messageList = Gmail.Users.Messages.list('YOURGMAIL@gmail.com', options);
if(messageList.messages == undefined || messageList.messages.length < 1){
continue;
}
for(var j = 0; j < messageList.messages.length; j++){
var curMessage = GmailApp.getMessageById(messageList.messages[j].id);
//curMessage.moveToTrash();
Logger.log("deleting message: " + JSON.stringify({subject: curMessage.getSubject(), date: curMessage.getDate()}));
}
}
}

- 3,240
- 7
- 31
- 45

- 402
- 3
- 10