Add Gmail filter cleanup script to remove dead/redundant filters
This commit is contained in:
@@ -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.');
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user