Files

236 lines
7.9 KiB
JavaScript

/**
* Gmail Label Cleanup Script
* Run from https://script.google.com
*
* What this does:
* 1. Merges old labels into inbox-zero categories (relabels all threads)
* 2. Archives + relabels cvlp threads to Newsletter
* 3. Merges purchases into Receipt, deletes purchases
* 4. Moves donations top-level, selling under business
* 5. Deletes contract label (threads stay under business)
* 6. Deletes empty/unused labels
*
* Safe to run multiple times - skips labels that don't exist.
*/
// ─── STEP 1: Merge old labels into inbox-zero categories ─────────────────────
function mergeLabels() {
var merges = [
{ from: 'promo', to: 'Marketing' },
{ from: 'mailing list', to: 'Newsletter' },
{ from: 'twitter', to: 'Notification' },
{ from: 'facebook', to: 'Notification' },
{ from: 'tech', to: 'Newsletter' },
{ from: 'To Reply', to: 'Awaiting Reply' },
];
merges.forEach(function(m) {
var fromLabel = GmailApp.getUserLabelByName(m.from);
if (!fromLabel) {
Logger.log('Skipping (not found): ' + m.from);
return;
}
var toLabel = GmailApp.getUserLabelByName(m.to);
if (!toLabel) {
Logger.log('Creating label: ' + m.to);
toLabel = GmailApp.createLabel(m.to);
}
Logger.log('Merging ' + m.from + ' -> ' + m.to);
var threads = fromLabel.getThreads(0, 100);
var total = 0;
while (threads.length > 0) {
toLabel.addToThreads(threads);
fromLabel.removeFromThreads(threads);
total += threads.length;
Utilities.sleep(1000);
threads = fromLabel.getThreads(0, 100);
}
Logger.log('Moved ' + total + ' threads: ' + m.from + ' -> ' + m.to);
fromLabel.deleteLabel();
Logger.log('Deleted label: ' + m.from);
});
}
// ─── STEP 2: cvlp → Newsletter + archive ─────────────────────────────────────
function archiveCvlp() {
var cvlpLabel = GmailApp.getUserLabelByName('cvlp');
if (!cvlpLabel) {
Logger.log('cvlp label not found, skipping');
return;
}
var newsletterLabel = GmailApp.getUserLabelByName('Newsletter');
if (!newsletterLabel) {
newsletterLabel = GmailApp.createLabel('Newsletter');
}
Logger.log('Processing cvlp: relabeling to Newsletter and archiving...');
var threads = cvlpLabel.getThreads(0, 100);
var total = 0;
while (threads.length > 0) {
newsletterLabel.addToThreads(threads);
cvlpLabel.removeFromThreads(threads);
threads.forEach(function(t) { t.moveToArchive(); });
total += threads.length;
Utilities.sleep(1000);
threads = cvlpLabel.getThreads(0, 100);
}
Logger.log('Archived ' + total + ' cvlp threads');
cvlpLabel.deleteLabel();
Logger.log('Deleted label: cvlp');
}
// ─── STEP 3: Merge purchases into Receipt ────────────────────────────────────
function mergePurchasesIntoReceipt() {
var purchasesLabel = GmailApp.getUserLabelByName('purchases');
if (!purchasesLabel) {
Logger.log('purchases label not found, skipping');
return;
}
var receiptLabel = GmailApp.getUserLabelByName('Receipt');
if (!receiptLabel) {
receiptLabel = GmailApp.createLabel('Receipt');
}
Logger.log('Merging purchases -> Receipt...');
var threads = purchasesLabel.getThreads(0, 100);
var total = 0;
while (threads.length > 0) {
receiptLabel.addToThreads(threads);
purchasesLabel.removeFromThreads(threads);
total += threads.length;
Utilities.sleep(1000);
threads = purchasesLabel.getThreads(0, 100);
}
Logger.log('Moved ' + total + ' threads: purchases -> Receipt');
purchasesLabel.deleteLabel();
Logger.log('Deleted label: purchases');
}
// ─── STEP 4: Restructure business nested labels ───────────────────────────────
function restructureBusinessLabels() {
// Move donations top-level: rename business/donations -> donations
var bizDonations = GmailApp.getUserLabelByName('business/donations');
if (bizDonations) {
var donationsLabel = GmailApp.getUserLabelByName('donations');
if (!donationsLabel) {
donationsLabel = GmailApp.createLabel('donations');
}
Logger.log('Moving business/donations -> donations (top-level)');
var threads = bizDonations.getThreads(0, 100);
var total = 0;
while (threads.length > 0) {
donationsLabel.addToThreads(threads);
bizDonations.removeFromThreads(threads);
total += threads.length;
Utilities.sleep(1000);
threads = bizDonations.getThreads(0, 100);
}
Logger.log('Moved ' + total + ' threads to top-level donations');
bizDonations.deleteLabel();
} else {
Logger.log('business/donations not found - skipping');
}
// Move selling under business: rename selling -> business/selling
var sellingLabel = GmailApp.getUserLabelByName('selling');
if (sellingLabel) {
var bizSelling = GmailApp.getUserLabelByName('business/selling');
if (!bizSelling) {
bizSelling = GmailApp.createLabel('business/selling');
}
Logger.log('Moving selling -> business/selling');
var threads = sellingLabel.getThreads(0, 100);
var total = 0;
while (threads.length > 0) {
bizSelling.addToThreads(threads);
sellingLabel.removeFromThreads(threads);
total += threads.length;
Utilities.sleep(1000);
threads = sellingLabel.getThreads(0, 100);
}
Logger.log('Moved ' + total + ' threads to business/selling');
sellingLabel.deleteLabel();
}
// Delete contract label (threads already have business label)
var contractLabel = GmailApp.getUserLabelByName('business/contract');
if (!contractLabel) {
contractLabel = GmailApp.getUserLabelByName('contract');
}
if (contractLabel) {
Logger.log('Removing contract label from all threads...');
var threads = contractLabel.getThreads(0, 100);
var total = 0;
while (threads.length > 0) {
contractLabel.removeFromThreads(threads);
total += threads.length;
Utilities.sleep(1000);
threads = contractLabel.getThreads(0, 100);
}
contractLabel.deleteLabel();
Logger.log('Deleted contract label (' + total + ' threads unaffected)');
}
}
// ─── STEP 5: Delete unused labels ────────────────────────────────────────────
function deleteUnusedLabels() {
var toDelete = [
'Notes',
'[Mailbox]',
'Later',
'To Buy',
'To Read',
'To Watch',
'Cold Email',
'Oak Ridge Moms',
'music',
];
toDelete.forEach(function(name) {
var label = GmailApp.getUserLabelByName(name);
if (!label) {
Logger.log('Not found (already gone?): ' + name);
return;
}
var threads = label.getThreads(0, 100);
var total = 0;
while (threads.length > 0) {
label.removeFromThreads(threads);
total += threads.length;
Utilities.sleep(500);
threads = label.getThreads(0, 100);
}
if (total > 0) {
Logger.log('Removed label from ' + total + ' threads: ' + name);
}
label.deleteLabel();
Logger.log('Deleted: ' + name);
});
}
// ─── RUN ALL ──────────────────────────────────────────────────────────────────
function runAll() {
Logger.log('=== Starting Gmail label cleanup ===');
Logger.log('--- Step 1: Merging labels ---');
mergeLabels();
Logger.log('--- Step 2: Archiving cvlp ---');
archiveCvlp();
Logger.log('--- Step 3: Merging purchases into Receipt ---');
mergePurchasesIntoReceipt();
Logger.log('--- Step 4: Restructuring business labels ---');
restructureBusinessLabels();
Logger.log('--- Step 5: Deleting unused labels ---');
deleteUnusedLabels();
Logger.log('=== Done! ===');
}