← back to George Gmail
add trash-fleet-mailtests.js — one-off cleanup of 89 fleet delivery-test emails (modeled on trash-redfin-zillow.js)
c2bdfcadf1f33b1bdc0005cd766dfdabf5a3e027 · 2026-05-19 11:34:57 -0700 · Steve Abrams
Files touched
A trash-fleet-mailtests.js
Diff
commit c2bdfcadf1f33b1bdc0005cd766dfdabf5a3e027
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Tue May 19 11:34:57 2026 -0700
add trash-fleet-mailtests.js — one-off cleanup of 89 fleet delivery-test emails (modeled on trash-redfin-zillow.js)
---
trash-fleet-mailtests.js | 75 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 75 insertions(+)
diff --git a/trash-fleet-mailtests.js b/trash-fleet-mailtests.js
new file mode 100644
index 0000000..3bffaef
--- /dev/null
+++ b/trash-fleet-mailtests.js
@@ -0,0 +1,75 @@
+/**
+ * trash-fleet-mailtests.js — one-off cleanup.
+ *
+ * Trashes the fleet inbound-mail delivery TEST emails that piled up in the
+ * steve-office inbox while verifying the 44-domain dw-domain-fleet catch-all
+ * forwarding. Two batches were sent, each tagged with a unique random token:
+ * FLEETMAILTEST-75986316 (first delivery test)
+ * RETEST-a3cdc29a (re-test from a third-party account)
+ * Both tokens are cryptographically unique, so the query has zero
+ * false-positive risk against real mail.
+ *
+ * George's MCP exposes no delete tool, so this uses George's own OAuth creds
+ * directly (gmail.modify scope) — same pattern as trash-redfin-zillow.js.
+ * Trashing is reversible: messages sit in Trash for 30 days.
+ *
+ * node trash-fleet-mailtests.js
+ */
+const fs = require('fs');
+const path = require('path');
+const { google } = require('googleapis');
+
+const ENV_PATH = path.join(process.env.HOME || '', 'Projects/Designer-Wallcoverings/DW-MCP/.env');
+const env = {};
+fs.readFileSync(ENV_PATH, 'utf8').split('\n').forEach(l => {
+ const m = l.match(/^([^#=]+)=(.+)/);
+ if (m) env[m[1].trim()] = m[2].trim();
+});
+
+const QUERY = 'subject:(RETEST-a3cdc29a OR FLEETMAILTEST-75986316)';
+// sanity bounds: 44 RETEST + 44 FLEETMAILTEST + 1 bounced "Re:" = ~89.
+const MIN_EXPECTED = 60;
+const MAX_EXPECTED = 120;
+
+(async () => {
+ const oc = new google.auth.OAuth2(
+ env.GMAIL_CLIENT_ID, env.GMAIL_CLIENT_SECRET, 'http://localhost:9850/oauth2callback');
+ oc.setCredentials({ refresh_token: env.GMAIL_REFRESH_TOKEN });
+ const gm = google.gmail({ version: 'v1', auth: oc });
+
+ console.log('=== steve@designerwallcoverings.com ===');
+ console.log('query:', QUERY);
+
+ // 1. Collect matching message IDs
+ const ids = [];
+ let pageToken = null;
+ do {
+ const r = await gm.users.messages.list({
+ userId: 'me', q: QUERY, maxResults: 500, pageToken: pageToken || undefined });
+ (r.data.messages || []).forEach(m => ids.push(m.id));
+ pageToken = r.data.nextPageToken || null;
+ } while (pageToken);
+ console.log(` collected ${ids.length} message IDs`);
+
+ // 2. Safety gate — abort if the count is wildly off what we expect
+ if (ids.length === 0) { console.log(' nothing to trash — exiting.'); return; }
+ if (ids.length < MIN_EXPECTED || ids.length > MAX_EXPECTED) {
+ console.error(` ABORT: ${ids.length} is outside the expected ${MIN_EXPECTED}-${MAX_EXPECTED} range.`);
+ console.error(' Re-check the query before trashing. No messages were modified.');
+ process.exit(1);
+ }
+
+ // 3. Trash — add TRASH, remove INBOX
+ const BATCH = 1000;
+ let trashed = 0;
+ for (let i = 0; i < ids.length; i += BATCH) {
+ const chunk = ids.slice(i, i + BATCH);
+ await gm.users.messages.batchModify({
+ userId: 'me',
+ requestBody: { ids: chunk, addLabelIds: ['TRASH'], removeLabelIds: ['INBOX'] }
+ });
+ trashed += chunk.length;
+ console.log(` trashed ${trashed}/${ids.length}`);
+ }
+ console.log(`\n=== DONE: ${trashed} fleet test emails moved to Trash ===`);
+})().catch(e => { console.error('FAILED:', e.message); process.exit(1); });
← ab70d2e George: make the 'From job:' provenance banner opt-out (no_s
·
back to George Gmail
·
Snapshot-files cleanup: untrack server.js.bak-*, broaden .gi 941feb1 →