This is more of a supporting comment to @JonathanY's https://mcmap.net/q/630972/-google-apps-script-gmail-delete-forever-e-mails-in-trash-with-specific-label :
**** Pre-requisite****
Note that being able to permanently delete messages or threads relies on Gmail
class which is only accessible once that Service has been added to the project like so:
Step 1: Click on +
in Services
(Note that there are no Services currently listed here)
Step 2:
Scroll down to the Gmail Service, select it and then click Add
Step 3:
Finally, confirm that the service now appears in the list of Services:
Sample Code
To re-iterate, the following sample code needs to be in a project which has the Gmail
service added to it as above.
To test this code, choose any message in Bin and label it with deleteForever
(create this label if needed).
Leave dryRun
as true and execute the function. The output will show which threads and/or messages will get deleted.
In actual usage, if you are planning to delete entire threads via Gmail.Users.Threads.remove
then you wouldn't use checkMessagesForContentBeforeDeleting
since the latter checks individual message bodies for content before deleting them (i.e. will only delete individual messages matching 'body content has the specified regex' criteria) and not whole threads.
var dryRun = true;
String.prototype.indexOfRegex = function (regex) {
var match = this.match(regex);
return match ? this.indexOf(match[0]) : -1;
}
function testDeleteForever() {
var labelName = "deleteForever"
var badContentFilterForMessages = ".*08:29.*"
var gmailSearchString = `in:trash label:${labelName}`
var threads = GmailApp.search(gmailSearchString);
const n = threads.length;
if (n <= 0) {
Logger.log("No threads matching search string \"%s\"", gmailSearchString);
return
} else {
Logger.log("Found %s threads matching action **%s**", n, gmailSearchString);
}
for (var i = 0; i < threads.length; i++) {
var thread = threads[i];
Logger.log(`\t Processing Thread#${i} [ID: ${thread.getId()}]: [First message subject: ${thread.getFirstMessageSubject()}]`)
if (!dryRun) {
Logger.log(`\t \t Will delete forever the THREAD: ${thread.getFirstMessageSubject()}`)
Gmail.Users.Threads.remove('me', thread.getId())
} else {
Logger.log(`\t \t **DRY RUN** would have deleted forever the THREAD: ${thread.getFirstMessageSubject()}`)
}
checkMessagesForContentBeforeDeleting(thread, badContentFilterForMessages);
}
}
function checkMessagesForContentBeforeDeleting(thread, badContentFilterForMessages){
Logger.log(`\t \t Checking messages in ${thread.getId()} for content matching "${badContentFilterForMessages}" before deleting forever`)
var messages = thread.getMessages();
Logger.log(`\t \t Number of messages in ${thread.getId()}: ${messages.length} `)
for (var j = 0; j < messages.length; j++) {
var message = messages[j];
Logger.log(`\t \t \t Checking Message#${j}: [Subject: ${message.getSubject()}]`)
var body = message.getRawContent();
var containsSearchString = body.indexOfRegex(badContentFilterForMessages) > -1;
if (containsSearchString) {
Logger.log(`\t \t \t \t Message#${j} is a match! Will be deleted!`)
if (!dryRun) {
Logger.log(`\t \t \t \t Will delete forever the MESSAGE: ${message.getSubject()}`)
Gmail.Users.Messages.remove('me', message.getId());
} else {
Logger.log(`\t \t \t \t **DRY RUN** would have deleted forever.`)
Gmail.Users.Messages.remove('me', message.getId());
}
} else {
Logger.log(`\t \t \t \t NOT deleting the MESSAGE (content does not match)`)
}
}
}