Created
February 10, 2021 18:53
-
-
Save kelnos/100b1af165a6b6cdaf01dbd53a5483a4 to your computer and use it in GitHub Desktop.
GMail Auto-Purge Script
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// The name of the Gmail labels and categories that are to be auto-purged | |
var GMAIL_LOCATIONS = { | |
"label": [ | |
"<some-label>" | |
], | |
"category": [ | |
"promotions" | |
] | |
}; | |
// Purge messages automatically after how many days? | |
var PURGE_AFTER = 60; | |
// Max to purge in one go | |
var PURGE_LIMIT = 100; | |
// If more than PURGE_LIMIT mails to purge, when to schedule the next purge (minutes) | |
var PURGE_RESCHEDULE_AFTER = 10; | |
// Email address to send error/debug logs to | |
var LOG_EMAIL = "<some-email-here>"; | |
// Set to true to always email the execution log | |
var DEBUG_EMAIL = false; | |
// How we identify the last trigger set | |
var LAST_TRIGGER_ID = "GMAIL_AUTO_PURGE_LAST_TRIGGER_ID"; | |
function purgeGmail() { | |
var age = new Date(); | |
age.setDate(age.getDate() - PURGE_AFTER); | |
var purge = Utilities.formatDate(age, Session.getTimeZone(), "yyyy-MM-dd"); | |
var threads = []; | |
try { | |
// We are processing a max of PURGE_LIMIT messages in a batch to prevent script errors, | |
// else it may throw an Exceeded Maximum Execution Time exception. | |
for (location in GMAIL_LOCATIONS) { | |
for (var i = 0; i < GMAIL_LOCATIONS[location].length; ++i) { | |
if (PURGE_LIMIT - threads.length > 0) { | |
var search = location + ": " + GMAIL_LOCATIONS[location][i] + " before:" + purge; | |
threads = threads.concat(GmailApp.search(search, 0, PURGE_LIMIT - threads.length)); | |
} | |
} | |
} | |
Logger.log("Got " + threads.length + " threads to delete"); | |
try { | |
// Attempt to clean up the last one-off trigger, since Google won't, and | |
// there is a limit on the number of (even expired) triggers you can have. | |
var lastTriggerId = PropertiesService.getUserProperties().getProperty(LAST_TRIGGER_ID); | |
if (lastTriggerId != null) { | |
Logger.info('Got last trigger ID to delete: ' + lastTriggerId); | |
var allTriggers = ScriptApp.getProjectTriggers(); | |
for (var i = 0; i < allTriggers.length; ++i) { | |
if (allTriggers[i].getUniqueId() == lastTriggerId) { | |
Logger.info('Deleting trigger'); | |
ScriptApp.deleteTrigger(allTriggers[i]); | |
break; | |
} | |
} | |
} | |
} catch (e) { | |
Logger.log('Failed to fetch/delete last trigger; continuing: ' + e); | |
} | |
// For large batches, create another time-based trigger that will | |
// activate the auto-purge process after PURGE_RESCHEDULE_AFTER minutes. | |
if (threads.length == PURGE_LIMIT) { | |
var trigger = ScriptApp.newTrigger("purgeGmail") | |
.timeBased() | |
.after(1000 * 60 * PURGE_RESCHEDULE_AFTER) | |
.create(); | |
PropertiesService.getUserProperties().setProperty(LAST_TRIGGER_ID, trigger.getUniqueId()); | |
} | |
// An email thread may have multiple messages and the timestamp of | |
// individual messages can be different. | |
var nDeleted = 0; | |
for (var i = 0; i < threads.length; i++) { | |
Logger.log("Processing thread " + i+1); | |
var messages = GmailApp.getMessagesForThread(threads[i]); | |
for (var j = 0; j < messages.length; j++) { | |
Logger.log("Deleting message " + j+1); | |
var email = messages[j]; | |
if (email.getDate() < age) { | |
email.moveToTrash(); | |
nDeleted += 1; | |
} | |
} | |
} | |
Logger.log('Purge complete for ' + nDeleted + ' messages'); | |
if (DEBUG_EMAIL && LOG_EMAIL) { | |
GmailApp.sendEmail(LOG_EMAIL, "GMail Auto Purge Debug Logs", Logger.getLog()); | |
} | |
} catch (e) { | |
// If the script fails for some reason or catches an exception, | |
// it will simply defer auto-purge until the next run. | |
Logger.log("Failed to complete purge: " + e); | |
if (LOG_EMAIL) { | |
GmailApp.sendEmail(LOG_EMAIL, "GMail Auto Purge Error Logs", Logger.getLog()); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment