Skip to content

hasankhan/trash-cleaner

Repository files navigation

Trash Cleaner

A program to delete trash emails based on keyword and label filters.

Prerequisites

Node.js & npm (Node 18+)

Installation

Via NPM

npm install -g trash-cleaner

Via GitHub

git clone https://github.com/hasankhan/trash-cleaner
cd trash-cleaner
# If you want to try out the development version then 'git checkout dev'
npm install -g

IMAP Configuration (Recommended)

The simplest way to get started. Works with any email provider.

Option 1: Secure Login (Recommended)

Store credentials securely in your OS keychain (macOS Keychain, Windows Credential Manager, Linux Secret Service):

trash-cleaner init          # Create config directory with sample files
trash-cleaner login         # Prompts for IMAP credentials, saves to OS keychain

For other services:

trash-cleaner login -s gmail
trash-cleaner login -s outlook

To remove stored credentials:

trash-cleaner logout        # Remove IMAP credentials from keychain
trash-cleaner logout -s gmail

Option 2: File-based Configuration

If your system doesn't have a keychain, credentials fall back to JSON files:

  1. Run trash-cleaner init to create sample config files
  2. Edit config/imap.credentials.json with your email settings:
    {
        "host": "imap.gmail.com",
        "port": 993,
        "user": "your-email@gmail.com",
        "password": "your-app-password"
    }

App Passwords

  • Gmail: Create an App Password (requires 2FA)
  • Outlook: Use your regular password or an app password
  • Yahoo: Account Security → Generate app password

Common IMAP servers:

Provider Host Port
Gmail imap.gmail.com 993
Outlook/Hotmail outlook.office365.com 993
Yahoo imap.mail.yahoo.com 993
iCloud imap.mail.me.com 993

Note: Some features (undo) are only available with the Gmail/Outlook API backends. Use --service gmail or --service outlook for those.

Gmail API Configuration (Advanced)

  1. Create a Google Cloud Platform project with the API enabled.
  2. Create Authorization credentials for a desktop application and download gmail.credentials.json file in the config directory.
  3. Rename keywords.json.sample file in the config directory to keywords.json and update its contents.

Outlook API Configuration (Advanced)

  1. Register an application with the Microsoft identity platform.
  2. Rename outlook.credentials.json.sample file in the config directory to outlook.credentials.json and update its contents.
  3. Rename keywords.json.sample file in the config directory to keywords.json and update its contents.

Get Started

Initialize the config directory with sample files:

trash-cleaner init [configDirPath]

This creates starter keywords.json, imap.credentials.json, gmail.credentials.json, and outlook.credentials.json files. Edit them to match your setup (see configuration sections above).

Configuring Rules

Rules live in keywords.yaml in your config directory (~/.config/trash-cleaner/ by default). The file is a YAML list of rule objects. Each rule tells trash-cleaner which emails to match and what to do with them.

Note: JSON config files (keywords.json, etc.) are also supported for backward compatibility. If both exist, YAML takes priority.

Rule Fields

Field Required Description
value Yes Keyword rules: A regex pattern to match. LLM rules: A natural language description.
title No A human-readable name for the rule, shown when it matches. Defaults to value if omitted.
fields No Comma-separated email fields to search: from, subject, snippet, body, or * for all. Default: *
labels No Comma-separated folder/label names to scope the rule: inbox, spam, trash, junk email, or * for all. Default: *
action No What to do with matches: delete, archive, or mark-as-read. Default: delete
type No Rule type: keyword (regex, default) or llm (external LLM classification).
llm For LLM rules Name of the LLM provider (must match a key in llm-providers.yaml).

Keyword Rules (Regex)

Keyword rules use regular expressions to match email content. They are fast and precise.

- value: casino
  fields: "*"
  labels: "*"
  title: Casino spam

- value: credit|loan
  fields: subject
  labels: spam, junk email
  title: Credit scams

- value: newsletter
  fields: subject
  labels: inbox
  action: archive
  title: Newsletters

- value: notification
  fields: subject
  labels: inbox
  action: mark-as-read
  • Delete all trash: value: "." with labels: trash, deleted items — the . regex matches any character.
  • Match multiple words: value: lucky|winner|prize — uses regex | (OR) to match any of the words.
  • Match emoji in subject: value: "[\\u{1F600}-\\u{1F64F}]" — uses Unicode character ranges.
  • Matching is case-insensitive and diacritic-insensitive (e.g., "café" matches "cafe").

LLM Rules (External CLI)

LLM rules invoke an external AI tool (Claude, Copilot, Ollama, etc.) to classify emails by meaning. Write a natural language description of what you want to match — the tool decides if each email fits.

- value: marketing or promotional email
  labels: "*"
  type: llm
  llm: claude
  action: archive
  title: Marketing emails

- value: someone selling me something
  labels: inbox
  type: llm
  llm: claude

LLM Provider Configuration

Create llm-providers.yaml in your config directory (~/.config/trash-cleaner/):

claude:
  command: claude
  args: ["--print", "{{prompt}}"]

copilot:
  command: copilot-cli
  args: ["-p", "{{prompt}}"]

ollama:
  command: ollama
  args: ["run", "llama3", "{{prompt}}"]

Each provider needs:

  • command — the CLI executable name (must be in your PATH)
  • args — arguments array with {{prompt}} as a placeholder for the rendered prompt
  • prompt (optional) — custom prompt template; defaults to asking "does this email match?" with true/false response

The {{prompt}} placeholder in args is replaced with the full prompt containing the rule description and email content. The tool must respond with "true" or "false".

  • LLM rules are slower than keyword rules (network call per email) but can catch things regex can't.
  • No data is sent to trash-cleaner servers — classification goes through your configured CLI tool.
  • Run trash-cleaner init to create a sample llm-providers.yaml.

Scoping Rules with Labels and Fields

Use labels to limit which folders a rule applies to:

  • "labels": "inbox" — only match emails in your inbox
  • "labels": "spam,junk email" — only match emails in spam/junk folders
  • "labels": "trash,deleted items" — only match emails in trash
  • "labels": "*" — match emails in any folder

Use fields to limit which parts of an email are searched (keyword rules only):

  • "fields": "subject" — only search the subject line
  • "fields": "subject,body" — search subject and body
  • "fields": "*" — search all fields (from, subject, snippet, body)

Example Configuration

- value: "."
  fields: "*"
  labels: trash, deleted items
  title: Clean trash folder

- value: casino|lottery|winner
  fields: "*"
  labels: spam, junk email
  title: Gambling spam

- value: unsubscribe
  fields: body
  labels: inbox
  action: archive
  title: Bulk mail

- value: notification
  fields: subject
  labels: inbox
  action: mark-as-read

- value: marketing or promotional email
  labels: inbox
  type: llm
  llm: claude
  action: archive
  title: Marketing emails

Rules are evaluated in order — the first matching rule wins. Place more specific rules before general ones.

To get the list of all parameters type trash-cleaner -h

Usage: trash-cleaner [options]

Options:
  -V, --version               output the version number
  -r, --reconfig              reconfigures the auth for a service
  -t, --dry-run               perform a dry-run cleanup without deleting the emails
  -d, --debug                 output extra debugging info
  -l, --launch                launch the auth url in the browser
  -q, --quiet                 suppress verbose output (for cron/scripts)
  -i, --interactive           preview matches and confirm before acting
  -f, --format <format>       output format: text or html (default: "text")
  -m, --min-age <days>        only process emails older than N days
  -c, --configDirPath <path>  the path to config directory (default: "config")
  -s, --service <service>     the email service to use (choices: "imap", "gmail", "outlook", default: "imap")
  -a, --account <name>        the account name for multi-account support (default: "default")
  -h, --help                  display help for command

Commands

trash-cleaner init [configDirPath]

Creates a config directory with sample configuration files.

trash-cleaner list-rules [configDirPath]

Displays all active keyword rules and allowlist patterns.

trash-cleaner validate [configDirPath]

Validates configuration files and reports any issues.

trash-cleaner undo [configDirPath]

Shows the last batch of processed emails and offers to restore them.

trash-cleaner login [-s service] [-a account]

Prompts for credentials and saves them securely in the OS keychain. Supports --service imap (default), gmail, or outlook.

trash-cleaner logout [-s service] [-a account]

Removes stored credentials from the OS keychain.

Features

Multi-Account Support

Run against different accounts using the -a flag:

trash-cleaner -s gmail -a work
trash-cleaner -s gmail -a personal

Each account stores its own credentials (e.g., gmail.credentials.work.json).

Sender Allowlist

Create config/allowlist.json to protect specific senders from any actions:

[
  "boss@company\\.com",
  ".*@important\\.org"
]

Patterns are case-insensitive regular expressions matched against the sender.

Interactive Mode

Use --interactive to preview matched emails before taking action:

trash-cleaner --interactive

Quiet Mode

Use --quiet for cron jobs or scripts — suppresses spinner and verbose output:

trash-cleaner --quiet

HTML Reports

Generate an HTML report instead of console output:

trash-cleaner --format html

This creates a timestamped HTML file in the current directory.

Retry Logic

API calls automatically retry with exponential backoff on transient failures (429, 5xx, network errors).

Email Age Filter

Only process emails older than a certain number of days:

trash-cleaner --min-age 7

Config Validation

Check your configuration files for errors before running:

trash-cleaner validate

Undo

After processing, actions are logged. Use trash-cleaner undo to restore the last batch:

trash-cleaner undo

Scheduling

To run trash-cleaner automatically on a schedule:

Linux/macOS (cron)

Run crontab -e and add a line. For example, to run every hour:

0 * * * * /usr/local/bin/trash-cleaner --quiet -c /path/to/config

macOS (launchd)

Create ~/Library/LaunchAgents/com.trash-cleaner.plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.trash-cleaner</string>
    <key>ProgramArguments</key>
    <array>
        <string>/usr/local/bin/trash-cleaner</string>
        <string>--quiet</string>
        <string>-c</string>
        <string>/path/to/config</string>
    </array>
    <key>StartInterval</key>
    <integer>3600</integer>
</dict>
</plist>

Load it with: launchctl load ~/Library/LaunchAgents/com.trash-cleaner.plist

Windows (Task Scheduler)

schtasks /create /tn "TrashCleaner" /tr "trash-cleaner --quiet -c C:\path\to\config" /sc hourly

Development

npm install        # Install dependencies
npm test           # Run tests
npm run lint       # Run ESLint
npm run typecheck  # Run JSDoc type checking
npm run coverage   # Generate coverage report

Releasing

Releases are automated via GitHub Actions. To publish a new version:

npm version patch   # or minor, or major
git push --follow-tags

This triggers the publish workflow which runs tests and publishes to npm. Requires NPM_TOKEN secret configured in the repository settings.

About

A program to delete trash emails based on keyword and label filters.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages