Bob Vezzuso
Bob Vezzuso

Reputation: 21

Need a handle to the 'All Mail' folder to delete old messages

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?

Upvotes: 1

Views: 447

Answers (4)

Anthony Metzidis
Anthony Metzidis

Reputation: 412

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('[email protected]', 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()}));
    }
  }  
}

Upvotes: 0

Bob Vezzuso
Bob Vezzuso

Reputation: 21

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

Upvotes: 1

Mogsdad
Mogsdad

Reputation: 45720

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

Upvotes: 1

JSDBroughton
JSDBroughton

Reputation: 4034

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

Upvotes: 1

Related Questions