@alfayad/gmail-cleaner
v1.0.1
Published
Securely clean your Gmail inbox by searching and bulk trashing or deleting emails
Maintainers
Readme
@alfayad/gmail-cleaner
Securely clean your Gmail inbox by searching and bulk trashing or permanently deleting emails using Gmail search queries.
Warning: Always run with
--dry-runfirst (the default). PermanentDELETEcannot be undone. PreferTRASHwhen possible — messages stay recoverable from Gmail Trash for about 30 days.
Features
- Gmail search query support (same syntax as the Gmail search box)
- Dry-run by default — preview matching message counts before any changes
- Trash (
TRASH) or permanently delete (DELETE) - OAuth 2.0 authentication with token persistence
- Paginated search, batch processing, rate limiting, and retry on quota errors
- Beautiful CLI with spinner, progress bar, and interactive confirmation
- Programmatic API for use in scripts
Prerequisites
- Node.js 18+
- A Google Cloud project with the Gmail API enabled
- OAuth 2.0 Desktop client credentials
Google Cloud setup
1. Create a project
- Go to the Google Cloud Console.
- Create a new project (or select an existing one).
2. Enable the Gmail API
- Open APIs & Services → Library.
- Search for Gmail API and click Enable.
3. Configure OAuth consent screen
- Go to APIs & Services → OAuth consent screen.
- Choose External (unless you use Google Workspace internally).
- Fill in the required app information.
- On Scopes, add:
https://www.googleapis.com/auth/gmail.modify - On Test users, add your Gmail address (required while the app is in Testing mode).
- Save.
4. Create OAuth credentials
- Go to APIs & Services → Credentials.
- Click Create Credentials → OAuth client ID.
- Application type: Desktop app.
- Download the JSON file and save it to your config directory:
mkdir -p ~/.config/gmail-cleaner
cp ~/Downloads/client_secret_*.json ~/.config/gmail-cleaner/credentials.jsonFor local development you can also keep credentials.json in the project folder and pass --credentials ./credentials.json.
Redirect URI: Desktop credentials should include
http://localhost:3000/oauth2callback(used by@google-cloud/local-auth). If missing, add it under your OAuth client's authorized redirect URIs.
5. First-time authentication
On first run, a browser window opens for Google sign-in. The OAuth token is saved to token.json for subsequent runs.
To re-authenticate (e.g. after invalid_grant errors), delete token.json and run again.
Installation
# From npm (when published)
npm install -g @alfayad/gmail-cleaner
# From source
git clone <repo-url>
cd gmail-inbox-cleaner
npm install
npm run build
npm link # optional: install CLI globallyConfiguration
Copy .env.example to .env or set environment variables:
GMAIL_CLEANER_CREDENTIALS_PATH=~/.config/gmail-cleaner/credentials.json
GMAIL_CLEANER_TOKEN_PATH=~/.config/gmail-cleaner/token.json
GMAIL_CLEANER_BATCH_DELAY_MS=250CLI flags --credentials and --token override these paths.
CLI usage
Preview (dry-run — default)
gmail-cleaner clean --query="older_than:1y label:promotions"Trash matching emails
gmail-cleaner clean \
--query="category:promotions older_than:6m" \
--no-dry-runPermanently delete (irreversible)
gmail-cleaner clean \
--query="from:[email protected]" \
--action=DELETE \
--no-dry-run \
--yesAll options
| Flag | Description | Default |
|------|-------------|---------|
| -q, --query <string> | Gmail search query | required |
| -a, --action <TRASH\|DELETE> | Trash or permanently delete | TRASH |
| --dry-run | Preview without modifying | true |
| --no-dry-run | Apply changes | — |
| -y, --yes | Skip interactive confirmation | false |
| -b, --batch-size <n> | Messages per API batch (max 1000) | 500 |
| -m, --max-results <n> | Cap messages processed | unlimited |
| --credentials <path> | OAuth credentials JSON | ~/.config/gmail-cleaner/credentials.json |
| --token <path> | Saved OAuth token JSON | ~/.config/gmail-cleaner/token.json |
Safe query cookbook
| Goal | Example query |
|------|---------------|
| Old promotions | older_than:1y label:promotions |
| Promotions category | category:promotions older_than:6m |
| Social updates | category:social older_than:1y |
| Specific sender | from:[email protected] |
| Large attachments | larger:10M older_than:1y |
| Read mail older than 2 years | is:read older_than:2y |
| Unread newsletters | is:unread label:newsletters |
Always preview with --dry-run before using --no-dry-run.
Programmatic usage
import { cleanGmail } from '@alfayad/gmail-cleaner';
// Preview
const preview = await cleanGmail({
query: 'older_than:1y label:promotions',
dryRun: true,
});
console.log(`Matched ${preview.matched} messages`);
// Trash (after verifying count)
const result = await cleanGmail({
query: 'older_than:1y label:promotions',
action: 'TRASH',
dryRun: false,
batchSize: 500,
onProgress: (info) => console.log(info.message),
});
console.log(`Processed ${result.processed}, failed ${result.failed}`);API reference
cleanGmail(options: CleanOptions): Promise<CleanResult>
getGmailClient(options?): Promise<Gmail>
listMessageIds(gmail, query, options?): Promise<{ ids: string[]; total: number }>CleanOptions:
query— Gmail search string (required)action—'TRASH'|'DELETE'(default:'TRASH')dryRun— defaulttruebatchSize— default500, max1000maxResults— optional capcredentialsPath,tokenPath— optional path overridesonProgress— progress callback
Security
- Never commit
credentials.jsonortoken.json— they are listed in.gitignore. - Keep OAuth credentials out of version control and CI logs.
- Use the minimum scope needed (
gmail.modify). - While your OAuth app is in Testing mode, only added test users can authenticate.
Troubleshooting
Credentials file not found
Download OAuth Desktop client JSON from Google Cloud Console and save to ~/.config/gmail-cleaner/credentials.json:
mkdir -p ~/.config/gmail-cleaner
cp ~/Downloads/client_secret_*.json ~/.config/gmail-cleaner/credentials.jsonOr pass --credentials /path/to/file.json.
invalid_grant or token errors
Delete token.json and run again to re-authenticate:
rm token.json
gmail-cleaner clean --query="older_than:1y" --dry-runQuota / rate limit errors
The tool retries with exponential backoff automatically. If errors persist:
- Reduce
--batch-size - Increase
GMAIL_CLEANER_BATCH_DELAY_MS - Wait a few minutes and retry
Access blocked: app has not been verified
Your OAuth app is in Testing mode. Add your account under OAuth consent screen → Test users, or publish the app (requires Google verification for sensitive scopes).
@google-cloud/local-auth deprecation
Google has deprecated @google-cloud/local-auth in favor of google-auth-library directly. This package still uses it for the interactive local OAuth flow. Re-authenticate by deleting token.json if you encounter auth issues.
Development
npm install
npm run build
npm run typecheck
node dist/cli.js clean --helpLicense
MIT
