diff --git a/inbox-zero/gmail-filter-cleanup.gs b/inbox-zero/gmail-filter-cleanup.gs new file mode 100644 index 0000000..79496bc --- /dev/null +++ b/inbox-zero/gmail-filter-cleanup.gs @@ -0,0 +1,261 @@ +/** + * Gmail Filter Cleanup Script + * Run from https://script.google.com + * + * SETUP REQUIRED: + * Before running, enable the Gmail Advanced Service: + * 1. Click "+" next to "Services" in the left sidebar + * 2. Find "Gmail API" and add it + * + * Run dryRun() first to see what will be deleted. + * Run deleteFilters() to actually delete them. + */ + +// Patterns to match against filter "from" criteria. +// Any filter whose "from" contains one of these strings will be deleted. +var DELETE_FROM_PATTERNS = [ + // Dead services + 'mozy.com', + 'ingdirect.com', + 'stumbleupon.com', + 'plaxo.com', + 'jott.com', + 'svpply.com', + 'alice@email.aliceupdates.com', + 'telltalegames.com', + 'gymboree.com', + 'landofnod.com', + 'evganews@evga.com', + 'thinkgeek.com', + 'recyclebank.com', + 'sharebuilder.com', + 'zulily.com', + + // Political / campaign (no longer relevant) + 'barackobama.com', + 'berniesanders.com', + 'democrats.org', + 'rockthevote.com', + 'rockthevote', + + // No longer relevant (uncertain ones user confirmed) + 'vacationsurvey@vargaresearch.com', + '5h4rpd0g@gmail.com', + 'mdegan@jacsmechanical.com', + 'ispcm-conf.org', + 'tntechnology.org', + 'Jason Mechler', + + // Duplicates / inbox-zero handles these via AI + 'nytimes@email.newyorktimes.com', + 'nytimes@e.newyorktimesinfo.com', + 'redcross-email@usa.redcross.org', + 'redcross-email@redcross.org', + 'redcross@theamericanredcross.org', + 'xfinity@info.xfinity.com', + 'xfinity@emails.xfinity.com', + 'kirkusreviews.com', + 'smarttoys@aol.com', + 'spotify@email.news.spotifymail.com', + 'no-reply@news.spotifymail.com', + 'newsletters@audible.com', + 'fightingback@messages.cancer.org', + '@messages.cancer.org', + + // Newsletter/marketing — inbox-zero AI handles these + 'eff.org', + 'rccetimes.com', + 'group-digests@linkedin.com', + 'info.knologyupclose.com', + 'newsletter@theorangepeel.net', + 'microsoft@e-mail.microsoft.com', + 'newsletters-no-reply@myfonts.com', + 'act@credoaction.com', + 'yourpowertip@powershell.com', + 'email@email.microsoftemail.com', + 'ramit@iwillteachyoutoberich.com', + 'mkt@manning.com', + 'deals@livingsocial.com', + 'idera.com', + 'newsletter@kirkusreviews.com', + 'email@earthfare-email.com', + 'gameinfo@email2.telltalegames.com', + 'no-reply@mail.goodreads.com', + 'angieslist@members.angieslist.com', + 'reply@e.taxact.com', + 'josabank@shop.josbank.com', + 'frenchpaperco@gmail.com', + 'csaimages@frenchpaper.com', + 'mailman@xoxide.com', + 'info@petsafe.net', + 'flor@news.flor.com', + 'info@launchtn.org', + 'alumni@tntech.edu', + 'info@rockthevote.com', + 'payscalemonitor@mail.payscale.com', + 'statefarm@e.statefarm.com', + 'mailer@svpply.com', + 'noreply@dontcrack.com', + 'info@paperandpolkadots.com', + 'dennis@adirondackguitar.com', + 'Yamaha_Corporation_of_America@mail.vresp.com', + 'carters.email@e.carters.com', + 'FTD@email.ftd.com', + 'info@email.glassdoor.com', + 'reply@glassdoor.com', + 'customerservice@1800petmeds.com', + 'news@crownclub.regmovies.com', + 'autonationspecials@autonation.chtah.com', + 'EddieBauerEmail@em.eddiebauer.com', + 'email@style.ballarddesigns.com', + 'barnesandnoble@m.bn.com', + 'sales@xoxide.com', + 'tripadvisor.com', + 'noreply@youtube.com', + 'donotreply@proguitarshop.com', + 'info@knoxvilleacademyofmusic.com', + 'artistupdates@reverbnation.com', + 'promotion@mwave.com', + 'deansbeans.com', + 'express@e.express.com', + 'alice@email.aliceupdates.com', + 'ispcm-conf.org', + 'no_reply@jetbrains.com', + 'noreply@roddenberry.com', + 'yourhondadealer@ahmdcms.com', + 'mdegan@jacsmechanical.com', +]; + +// Subject patterns — delete filters matching these subjects +// (only when combined with a dead/irrelevant from, handled separately below) +// For now these are standalone subject-only filters to delete +var DELETE_SUBJECT_PATTERNS = [ + 'Abandonia Newsletter', +]; + +// List patterns (mailing list ID in filter query) +var DELETE_LIST_PATTERNS = [ + 'oakridgemoms.googlegroups.com', + '14-days.googlegroups.com', + '120331169_84238_19051', + 'andrewbird.fanbridge.com', +]; + +// Specific from+subject combos — delete if BOTH match +var DELETE_FROM_SUBJECT_PAIRS = [ + { from: 'linkedin.com', subject: 'endorsed' }, + { from: 'updates@linkedin.com', subject: null }, // skip inbox only, no label + { from: 'connections@linkedin.com', subject: null }, // linkedin connection spam + { from: 'noreply@plaxo.com', subject: 'birthday' }, + { from: 'confirm+ye22mger@facebookmail.com', subject: null }, // old specific fb filter +]; + +// ───────────────────────────────────────────────────────────────────────────── + +function getFiltersToDelete_() { + var response = Gmail.Users.Settings.Filters.list('me'); + var filters = response.filter || []; + var toDelete = []; + + filters.forEach(function(f) { + var from = (f.criteria && f.criteria.from) ? f.criteria.from.toLowerCase() : ''; + var subject = (f.criteria && f.criteria.subject) ? f.criteria.subject.toLowerCase() : ''; + var query = (f.criteria && f.criteria.query) ? f.criteria.query.toLowerCase() : ''; + var shouldDelete = false; + var reason = ''; + + // Check from patterns + DELETE_FROM_PATTERNS.forEach(function(p) { + if (from.indexOf(p.toLowerCase()) !== -1) { + shouldDelete = true; + reason = 'from matches: ' + p; + } + }); + + // Check subject patterns + if (!shouldDelete) { + DELETE_SUBJECT_PATTERNS.forEach(function(p) { + if (subject.indexOf(p.toLowerCase()) !== -1) { + shouldDelete = true; + reason = 'subject matches: ' + p; + } + }); + } + + // Check list patterns in query + if (!shouldDelete) { + DELETE_LIST_PATTERNS.forEach(function(p) { + if (query.indexOf(p.toLowerCase()) !== -1) { + shouldDelete = true; + reason = 'list matches: ' + p; + } + }); + } + + // Check from+subject pairs + if (!shouldDelete) { + DELETE_FROM_SUBJECT_PAIRS.forEach(function(pair) { + var fromMatch = pair.from ? from.indexOf(pair.from.toLowerCase()) !== -1 : true; + var subjectMatch = pair.subject ? subject.indexOf(pair.subject.toLowerCase()) !== -1 : true; + if (fromMatch && subjectMatch && (pair.from || pair.subject)) { + shouldDelete = true; + reason = 'pair match: from=' + pair.from + ' subject=' + pair.subject; + } + }); + } + + if (shouldDelete) { + toDelete.push({ id: f.id, criteria: f.criteria, action: f.action, reason: reason }); + } + }); + + return { all: filters, toDelete: toDelete }; +} + +function dryRun() { + Logger.log('=== DRY RUN — no filters will be deleted ==='); + var result = getFiltersToDelete_(); + Logger.log('Total filters: ' + result.all.length); + Logger.log('Filters that WOULD be deleted: ' + result.toDelete.length); + Logger.log(''); + + result.toDelete.forEach(function(f) { + Logger.log('DELETE [' + f.id + ']'); + Logger.log(' From: ' + (f.criteria.from || '')); + Logger.log(' Subject: ' + (f.criteria.subject || '')); + Logger.log(' Query: ' + (f.criteria.query || '')); + Logger.log(' Reason: ' + f.reason); + Logger.log(''); + }); + + Logger.log('=== Filters that will be KEPT ==='); + var kept = result.all.filter(function(f) { + return !result.toDelete.some(function(d) { return d.id === f.id; }); + }); + kept.forEach(function(f) { + Logger.log('KEEP [' + f.id + '] from=' + (f.criteria.from || '') + + ' subject=' + (f.criteria.subject || '') + + ' query=' + (f.criteria.query || '')); + }); +} + +function deleteFilters() { + Logger.log('=== Deleting filters ==='); + var result = getFiltersToDelete_(); + Logger.log('Deleting ' + result.toDelete.length + ' of ' + result.all.length + ' filters...'); + + var deleted = 0; + result.toDelete.forEach(function(f) { + try { + Gmail.Users.Settings.Filters.remove('me', f.id); + Logger.log('Deleted [' + f.id + '] from=' + (f.criteria.from || '') + ' (' + f.reason + ')'); + deleted++; + Utilities.sleep(200); + } catch(e) { + Logger.log('ERROR deleting [' + f.id + ']: ' + e.message); + } + }); + + Logger.log('Done. Deleted ' + deleted + ' filters.'); + Logger.log('Remaining: ' + (result.all.length - deleted) + ' filters.'); +}