/* | |
This script, when used with Google Apps Scripts, will delete 400 emails and | |
can be triggered to run every few minutes without user interaction enabling you | |
to bulk delete email in Gmail without getting the #793 error from Gmail. | |
Google returns a maximum of 500 email threads in a single API call. | |
This script fetches 400 threads in case 500 threads is causing timeouts | |
Configure the search query in the code below to match the type of emails | |
you want to delete | |
See - https://developers.google.com/apps-script/reference/gmail/gmail-app#search(String) | |
and https://support.google.com/mail/answer/7190 | |
Browse to https://script.google.com/ | |
Start a script and paste in the code below. | |
After you paste it in, save it. | |
Now you need to set the authorized scopes for the script ( https://developers.google.com/apps-script/concepts/scopes ) | |
On the left side of the screen, hover over the gear symbol and then click on Project Settings. | |
Enable 'Show "appsscript.json" manifest file in editor' | |
On the left side of the screen, click on the < > to return to the code editor | |
You should see a new file appear, appscript.json. Click on it. | |
Edit the file to add an oauthScopes entry for mail.google.com. It should look something like this. | |
{ | |
"oauthScopes": [ | |
"https://mail.google.com/", | |
"https://www.googleapis.com/auth/gmail.readonly", | |
"https://www.googleapis.com/auth/gmail.modify" | |
], | |
"timeZone": "America/New_York", | |
"dependencies": { | |
"enabledAdvancedServices": [ | |
{ | |
"userSymbol": "Gmail", | |
"version": "v1", | |
"serviceId": "gmail" | |
} | |
] | |
}, | |
"exceptionLogging": "STACKDRIVER", | |
"runtimeVersion": "V8" | |
} | |
In the drop down at the top select the function you want | |
to run. For example, you could run the batchDeleteEmail function. | |
This gist contains a few different functions to give examples of how to do other actions | |
besides deleting emails. For example if you wanted to mark all mail with the "work" label as read | |
you could run the markReadLabelWork function | |
Next click the little clock looking button. | |
This is for your triggers. You can set up how frequently you want the script | |
to run (I did mine for every minute but others are seeing execution take longer than | |
a minute in which case you may want to run every 5 or 15 minutes). | |
This writeup from @timur-tabi goes into more detail : https://docs.google.com/document/d/1PLfAnNus-B87gHS1pkbmzFTkWckAPNcqmvO7hFo_gBc/edit | |
Source : # https://productforums.google.com/d/msg/gmail/YeQVDuPIQzA/kpZPDDj8TXkJ | |
This gist includes additions by @kulemantu found in their fork : https://gist.github.com/kulemantu/84682cfebe72eb925cfe/revisions | |
*/ | |
function batchDeleteEmail() { | |
processEmail('label:inbox from:user@example.com', 'moveThreadsToTrash'); | |
} | |
function markReadLabelWork() { | |
processEmail('label:work', 'markThreadsRead'); | |
} | |
function markReadFromInfoExample() { | |
processEmail('from:user@example.com', 'markThreadsRead'); | |
} | |
function processEmail(search, batchAction) { | |
var batchSize = 100; // Process up to 100 threads at once | |
var searchSize = 400; // Limit search result to a max of 400 threads. Use this if you encounter the "Exceeded maximum execution time" error | |
var threads = GmailApp.search(search, 0, searchSize); | |
for (j = 0; j < threads.length; j += batchSize) { | |
GmailApp[batchAction](threads.slice(j, j + batchSize)); | |
} | |
} |
This script changed my life
My script appears to be running but I don't see the overall count going down. Is there any code I can add which would allow me to log whether the threads were successfully removed?
Thank you for an amazing script. However, in my case, I have around 200k messages that I need to delete. Here is how I altered the code to keep it running continuously:
function processEmail(search, batchAction) {
var batchSize = 100; // Process up to 100 threads at once
var searchSize = 500; // Limit search result to a max of 500 threads. (google doesn't allow more)
do {
var threads = GmailApp.search(search, 0, searchSize);
console.log('processing ' + threads.length + ' threads');
for (j = 0; j < threads.length; j += batchSize) {
GmailApp[batchAction](threads.slice(j, j + batchSize));
}
} while (threads.length>0) // keep script running until there are no threads left
}
For the people like me that have thousands of emails to delete and don't have a fancy business account, if you use @ethaniel script you will get Exceeded maximum execution time after 6 minutes, a way to get over it is setting a trigger
For the people like me that have thousands of emails to delete and don't have a fancy business account, if you use @ethaniel script you will get Exceeded maximum execution time after 6 minutes, a way to get over it is setting a trigger
🕐 to execute every 5 minutes calling the function😄 Hope that helps!
And don’t forget to “deploy” the script, so the trigger would actually work!
hi! i'm getting this message when i run the program. i may not be getting the proper authorization scope. please advise. thanks
Error
Exception: The script does not have permission to perform that action. Required permissions: (https://www.googleapis.com/auth/gmail.metadata || https://www.googleapis.com/auth/gmail.readonly || https://www.googleapis.com/auth/gmail.modify || https://mail.google.com/)
batchDeleteEmail @ BatchDeleteEmails.gs:3
hi! i'm getting this message when i run the program. i may not be getting the proper authorization scope. please advise. thanks
Error Exception: The script does not have permission to perform that action. Required permissions: (https://www.googleapis.com/auth/gmail.metadata || https://www.googleapis.com/auth/gmail.readonly || https://www.googleapis.com/auth/gmail.modify || https://mail.google.com/) batchDeleteEmail @ BatchDeleteEmails.gs:3
it looks like i'm missing the authorization to log onto my gmail account. which i think should be built into the code.
no one has experienced that error message?
Error Exception: The script does not have permission to perform that action. Required permissions: (https://www.googleapis.com/auth/gmail.metadata || https://www.googleapis.com/auth/gmail.readonly || https://www.googleapis.com/auth/gmail.modify || https://mail.google.com/) batchDeleteEmail @ BatchDeleteEmails.gs:3
@jmjeanjm @timur-tabi have you guys solved this problem?
@jmjeanjm @LucipherVenus I've updated the comment section of the code to include the information @timur-tabi linked above
Try that and let me know if it resolves the issue for you.
I was getting the following error:
Exception: Access denied: : Metadata scope does not support 'q' parameter.
at processEmail(Code:70:26)
at batchDeleteEmail(Code:55:3)
But was able to fix after removing the following from oauthScopes:
"https://www.googleapis.com/auth/gmail.metadata",
@celestialeye Thanks, I'll update the instructions to remove that scope.
How nice it is to see the emails from that massive folder slowly but surely disappearing. Thanks for sharing.
Thank you! Deleted 1.6M emails in one night.
@Hectorhammett Indeed, @asifiqbal also mentions above encountering that limit.