Created
August 15, 2025 05:23
-
-
Save r4um/b167de83593a1214139afb4d6f1073b3 to your computer and use it in GitHub Desktop.
gmailCleanup
This file contains hidden or 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
/ Cleanup emails. | |
// | |
// Create label ending with ;Na e.g. test;6m where Na is the age, N number 1,2,3.. etc a is d,m,w,y days,months,weekly,years | |
// Starred emails and emails label as indef are not deleted. | |
function gmailCleanup() { | |
function getDateBeforeToday(daysBefore) { | |
let today = new Date(); | |
// Subtract the specified number of days | |
today.setDate(today.getDate() - daysBefore); | |
// Extract year, month, and day | |
let year = today.getFullYear(); | |
let month = today.getMonth() + 1; // Months are zero-based | |
let day = today.getDate(); | |
// Format month and day with leading zero if needed | |
month = month < 10 ? '0' + month : month; | |
day = day < 10 ? '0' + day : day; | |
// Return the formatted date | |
return `${year}/${month}/${day}`; | |
} | |
function translateDurationToDays(durationString) { | |
const match = durationString.match(/^(\d+)([dwmy])$/); // Extract number and unit using regex | |
if (!match) { | |
Logger.log(`Invalid duration string: ${durationString}`); // Log invalid strings | |
return null; | |
} | |
const value = parseInt(match[1]); // Parse the number | |
const unit = match[2]; // Get the unit (d, w, m, or y) | |
switch (unit) { | |
case 'd': // Days | |
return value; | |
case 'w': // Weeks, multiply by 7 days | |
return value * 7; | |
case 'm': // Months, approximate as 30 days per month | |
return value * 30; | |
case 'y': // Years, approximate as 365 days per year | |
return value * 365; | |
default: | |
Logger.log(`Unknown duration unit: ${unit}`); | |
return null; | |
} | |
} | |
function autoTrash(emailLabel, emailAge) { | |
const labelInDef = 'indef' | |
var threads; | |
var counter = 0; | |
var errors = 0; | |
var query = `label:${emailLabel} before:${getDateBeforeToday(emailAge)} -is:starred -label:${labelInDef}` | |
do { | |
Logger.log(`Searching with query ${query}`) | |
threads = GmailApp.search(query); | |
if (threads.length > 0) { | |
console.log('Found ' + threads.length + ' emails marked for deletion.'); | |
try { | |
let nextProgressMark = 20; | |
for (var i = 0; i < threads.length; i++) { | |
try { | |
threads[i].moveToTrash(); | |
counter++; | |
const currentPercentage = Math.floor(((i + 1) / threads.length) * 100); | |
if (currentPercentage >= nextProgressMark) { | |
Logger.log(`${nextProgressMark}% done this iteration. Total Processed ${counter} emails.`); | |
nextProgressMark += 20; | |
} | |
} catch (e) { | |
Logger.log(`Error moving thread to trash: ${threads[i].getFirstMessageSubject()}`); | |
} | |
} | |
} catch (e) { | |
errors++; | |
console.error(`Could Not Complete Run: ${e}`); | |
} | |
} else { | |
console.log('No emails marked for deletion. Exiting.'); | |
} | |
} while (threads.length > 0); | |
console.log(`100% done. Moved ${counter} emails to the trash with ${errors} errors.`); | |
} | |
const labels = GmailApp.getUserLabels(); // Get all user-created labels | |
for (let i = 0; i < labels.length; i++) { | |
const label = labels[i]; | |
const fullLabelName = label.getName(); | |
let labelName = ""; | |
let labelAge = ""; | |
if (fullLabelName.includes(';')) { | |
const parts = fullLabelName.split(';'); | |
labelName = parts[0].trim(); | |
labelAge = parts[1].trim(); | |
} else { | |
labelName = fullLabelName.trim(); | |
labelAge = null; | |
} | |
if(labelAge) { | |
var labelDuration = translateDurationToDays(labelAge) | |
Logger.log(`Processing label ${fullLabelName} age ${labelAge} duration ${labelDuration} days.`) | |
autoTrash(fullLabelName, labelDuration) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment