How to query for NOT trashed emails with Google App Scripts?

Viewed 317

I'm trying to create a script for Gmail to get only "NOT trashed" emails but I'm getting the thashed emails too.

Why?

function fromGmailToDrive() {
    var query = "in:inbox -in:trash has:attachment";
    var threads = GmailApp.search(query);

    threads.forEach((t) => {
        const messages = t.getMessages()
        messages.forEach((m) => {
            console.log("m.isInTrash():", m.isInTrash()) //<- some are true, why?
        })
    })
}

That query is working if I use it in Gmail browser app.

2 Answers

Updated answer:

The method isInTrash() is supported for both threads and messages. In your solution you are checking for the trashed messages, not the trashed threads.

If you want to check whether a thread is trashed or not, you should apply the isInTrash() method on the threads instead:

function fromGmailToDrive() {
    var query = "-in:trash has:attachment";
    var threads = GmailApp.search(query);

    threads.forEach((t) => {
            console.log("m.isInTrash():", t.isInTrash());
    })
}

Optional workaround

Get all the trashed threads and exclude them (! includes) from threads:

function fromGmailToDrive() {
    var query = "-in:trash has:attachment";
    var threads = GmailApp.search(query);
    var trashThreadsIDs = GmailApp.getTrashThreads().map(t=>t.getId());
    var clean_threads = threads.filter(t=>!trashThreadsIDs.includes(t.getId()));

    clean_threads.forEach((t) => {
        const messages = t.getMessages()
        messages.forEach((m) => {
            console.log("m.isInTrash():", m.isInTrash()) //<- some are true, why?
        })
    })
}

As per Marios mentioned in the comment, you want to have -in:trash. But since you added in:inbox and has:attachment, it added those emails that meet those criteria as well.

If you want to find only the messages containing attachments and is not in trash, then use:

Code:

function fromGmailToDrive() {
    var query = "-in:trash has:attachment";
    var threads = GmailApp.search(query);

    threads.forEach((t) => {
        const messages = t.getMessages()
        messages.forEach((m) => {
            console.log("m.isInTrash():", m.isInTrash()) 
        })
    })
}

Note:

  • You can also add OR or AND in between the query conditions/criteria to be explicit. Use them accordingly.

EDIT:

  • If all else fails, you might just need to have a condition that checks when message is not in trash. This is not a good answer and should be considered last resort, but it will still solve your issue.

Code:

if (!m.isInTrash())
  // do something when message not in trash
Related