236 lines
7.9 KiB
JavaScript
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! ===');
|
|
}
|