Search code examples
google-apps-scriptgmail

Filter Gmail labels by parent for deletion after certain number of days


I've given up on trying to manage my Gmail by Categories as they don't filter well in third-party email tools on my phone, so I've resorted to filtering all of my newsletters, blog posts, coupons, etc. into labels and sub-labels.

I have a GScript function to delete labels after a certain amount of days, but I can't figure out how to have the code include the parent/child label as well.

For example, I have a label called "-Newsletters" and a bunch of sub-labels for the type of newsletter (i.e., -Newsletters/Blogs, -Newsletters/Coupon, -Newsletter/News, etc.). The code I have shown below works great when I'm searching for the exact label, but I'm trying to modify it so that it will run the code on all parent/child labels I may set up in the future.

Is there a way to do this with the GmailApp.search function? or do I just need to repeat the code for each separate search string?

The code below deletes all emails with a label "-Newsletters" older than 3 days, but not "-Newsletters/Blogs" or "-Newsletters/News". I'm not sure how I would setup a variable to capture the child label name or how to place that variable inside the GmailApp.search function.

Thanks in advance.

function cleanUpNewsletterLabel() {
  var delayDays = 3 // Enter # of days before messages are moved to trash
  var maxDate = new Date();
  maxDate.setDate(maxDate.getDate()-delayDays);
  var threads = GmailApp.search('label:-Newsletters -is:starred'); // filter all emails with -Newsletters label not starred
  for (var i = 0; i < threads.length; i++) {
    if (threads[i].getLastMessageDate()<maxDate)
      {
        threads[i].moveToTrash();
      }
  }
}

Solution

  • I don't think there is a search operator that you can use to get all child labels (only exact match seems to be supported).

    What you can do instead, is retrieve all the child labels the following way:

    • Retrieve all labels with getUserLabels().
    • Filter this labels with the condition that their names start with the parent label name, since child label names have this format: {parentLabelName}/{childLabelName}/.... Here, you could use filter() and startsWith().
    • For each filtered label, search the corresponding threads.

    It could be something like this:

    const parentLabelName = "-Newsletters";
    const labels = GmailApp.getUserLabels();
    const filteredLabels = labels.filter(label => label.getName().startsWith(parentLabelName));
    filteredLabels.forEach(filteredLabel => {
      const threads = GmailApp.search(`label:${filteredLabel.getName()} -is:starred`);
      // Delete threads (your code)
    });