The cull-gmail provides a software library and command line program to enable the culling of emails using the Gmail API.
Quick Start
Get started with cull-gmail in minutes using the built-in setup command:
- Get OAuth2 credentials from Google Cloud Console
- Initialize cull-gmail with guided setup:
# Interactive setup (recommended) # Or preview first - Verify your setup:
Main Features
- Easy initialization: Guided setup with OAuth2 credential validation and secure file handling
- Flexible configuration: Support for file-based config, environment variables, and ephemeral tokens
- Safety first: Dry-run mode by default, interactive confirmations, and timestamped backups
- Label management: List and inspect Gmail labels for rule planning
- Message operations: Query, filter, and perform batch operations on Gmail messages
- Rule-based automation: Configure retention rules with time-based filtering and automated actions
- Token portability: Export/import OAuth2 tokens for containerized and CI/CD environments
Running the optional Gmail integration test
An optional, ignored integration test exercises the Gmail API end-to-end (networked). It is ignored by default and will not run in CI.
Steps to run locally:
- Ensure you have valid OAuth client credentials configured for the library (see
ClientConfig::builder()usage in docs). - Run the test explicitly with the ignored flag:
Notes:
- The test performs a lightweight listing (max 10 messages) and should be safe, but it still uses your Gmail account.
- Do not run this in CI; it is intended only for local verification.
cull-gmail CLI Documentation
A command-line program for managing Gmail messages using the Gmail API. The tool provides subcommands for label querying, message querying, rule configuration, and rule execution to trash/delete messages with built-in safety features like dry-run mode.
Installation
From Crates.io
From Source
Verify Installation
Authentication Setup
1. Google Cloud Console Setup
- Visit the Google Cloud Console
- Create a new project or select an existing one
- Enable the Gmail API:
- Go to "APIs & Services" > "Library"
- Search for "Gmail API" and enable it
- Create OAuth2 credentials:
- Go to "APIs & Services" > "Credentials"
- Click "Create Credentials" > "OAuth client ID"
- Choose "Desktop application"
- Download the JSON file
2. Configure cull-gmail
-
Create the configuration directory:
-
Copy your OAuth2 credential file:
-
Create configuration file
~/.cull-gmail/cull-gmail.toml:= "client_secret.json" = "~/.cull-gmail" = "rules.toml" = false # Start in dry-run mode
3. First Run Authentication
Run any command to trigger the OAuth flow:
This will:
- Open your browser for Google authentication
- Prompt you to grant Gmail access
- Save tokens to
~/.cull-gmail/gmail1/
Configuration
Configuration File
Location: ~/.cull-gmail/cull-gmail.toml
# OAuth2 credential file (relative to config_root)
= "client_secret.json"
# Configuration directory
= "~/.cull-gmail"
# Rules file
= "rules.toml"
# Default execution mode (false = dry-run, true = execute)
= false
# Alternative: Direct OAuth2 configuration
# client_id = "your-client-id.apps.googleusercontent.com"
# client_secret = "your-client-secret"
# token_uri = "https://oauth2.googleapis.com/token"
# auth_uri = "https://accounts.google.com/o/oauth2/auth"
Environment Variables
Override any configuration setting:
Command Structure
Global Options
-v, --verbose...: Increase logging verbosity (can be used multiple times)-q, --quiet...: Decrease logging verbosity-h, --help: Show help-V, --version: Show version
Commands
labels: List available Gmail labelsmessages: Query and operate on messagesrules: Configure and run retention rules
Command Reference
Labels Command
List all labels in your Gmail account:
Example Output:
INBOX: INBOX
IMPORTANT: IMPORTANT
CHAT: CHAT
SENT: SENT
DRAFT: DRAFT
promotions: Label_1234567890
old-emails: Label_0987654321
Messages Command
Query and operate on Gmail messages.
Syntax
Options
-l, --labels <LABELS>: Filter by labels (can be used multiple times)-m, --max-results <MAX_RESULTS>: Maximum results per page [default: 200]-p, --pages <PAGES>: Maximum number of pages (0=all) [default: 1]-Q, --query <QUERY>: Gmail query string
Actions
list: Display message informationtrash: Move messages to trashdelete: Permanently delete messages
Examples
List recent messages:
List promotional emails older than 6 months:
Move old promotional emails to trash:
Permanently delete very old messages:
Query with multiple labels:
Process all pages (not just first page):
Rules Command
Manage retention rules for automated email lifecycle management.
Syntax
Subcommands
config: Configure retention rulesrun: Execute configured rules
Rules Config Command
Configure retention rules:
Config Actions
rules: Manage rule definitionslabel: Add/remove labels from rulesaction: Set action (trash/delete) on rules
Example Rules Configuration:
Create/edit ~/.cull-gmail/rules.toml:
[]
= 1
= { = "y:1", = true }
= ["old-emails"]
= "Trash"
[]
= 2
= { = "m:6", = true }
= ["promotions", "newsletters"]
= "Trash"
[]
= 3
= { = "y:5", = true }
= ["archive"]
= "Delete"
Rules Run Command
Execute configured rules:
Options
-e, --execute: Actually perform actions (without this, runs in dry-run mode)-t, --skip-trash: Skip rules with "trash" action-d, --skip-delete: Skip rules with "delete" action
Examples
Dry-run all rules (safe, no changes made):
Execute all rules:
Execute only delete rules:
Execute only trash rules:
Gmail Query Syntax
The -Q, --query option supports Gmail's powerful search syntax:
Date Queries
# Relative dates
# Absolute dates
Label Queries
# Has label
# Does NOT have label (note the minus sign)
Content Queries
# Subject line
# From/To
# Message content
Status Queries
# Read status
# Star status
# Size
Combined Queries
# Complex combinations
Common Workflows
1. Clean Up Promotional Emails
# Step 1: Preview what will be affected
# Step 2: Move to trash (can be recovered for 30 days)
2. Archive Old Conversations
# Archive conversations older than 2 years (excluding starred)
3. Delete Very Old Messages
# Permanently delete messages older than 5 years (be careful!)
4. Rule-Based Automation
# Set up rules in ~/.cull-gmail/rules.toml, then:
# Preview what rules will do
# Execute rules
5. Scheduled Cleanup
Add to your crontab for weekly cleanup:
# Edit crontab
# Add this line (runs every Sunday at 2 AM)
Safety Features
Dry-Run Mode
- Default behaviour: All operations are dry-run unless explicitly executed
- Messages: Use
listaction to preview what would be affected - Rules: Run without
--executeflag to see what would happen
Confirmation and Logging
- All operations are logged with detailed information
- Use
-vfor verbose logging to see exactly what's happening - Check log output before running destructive operations
Recoverable Operations
- Trash: Messages moved to trash can be recovered for 30 days
- Delete: Permanent deletion - cannot be undone
Logging and Debugging
Environment Variables
# Set log level
# Enable all logging
Verbosity Levels
# Quiet (errors only)
# Normal (default)
# Verbose (info level)
# Very verbose (debug level)
# Maximum verbosity (trace level)
Log Information
- Error: Critical issues
- Warn: Non-fatal issues, dry-run notifications
- Info: General operation info, message subjects, counts
- Debug: Detailed API calls, query strings
- Trace: Very detailed debugging information
Troubleshooting
Authentication Issues
Problem: "Authentication failed" or "Invalid credentials"
Solutions:
- Verify OAuth2 credential file exists and is valid JSON
- Check OAuth client is configured as "Desktop Application"
- Clear token cache:
rm -rf ~/.cull-gmail/gmail1 - Re-run authentication:
cull-gmail labels
Problem: "Access denied" or "Insufficient permissions"
Solutions:
- Verify Gmail API is enabled in Google Cloud Console
- Check OAuth scopes include Gmail access
- Re-authenticate with proper permissions
Query Issues
Problem: "No messages found" when you expect results
Solutions:
- Test query in Gmail web interface first
- Check label names:
cull-gmail labels - Verify query syntax (no typos)
- Use
-vflag to see the actual query being sent
Problem: Query returns unexpected results
Solutions:
- Use
messages listto preview beforetrash/delete - Check for operator precedence in complex queries
- Test simpler queries first, then combine
Performance Issues
Problem: Operations are slow or timeout
Solutions:
- Reduce page size:
-m 100 - Limit pages:
-p 5instead of-p 0 - Use more specific queries to reduce result sets
- Check Gmail API quotas in Google Cloud Console
Configuration Issues
Problem: "Configuration not found" or "Config parse error"
Solutions:
- Verify config file path:
~/.cull-gmail/cull-gmail.toml - Check TOML syntax
- Ensure OAuth2 credential file path is correct
- Use absolute paths if relative paths fail
Exit Codes
- 0: Success
- 101: Error (check stderr for details)
Examples
Basic Message Management
# List all labels
# List first 50 messages
# List promotional emails from last year
Batch Operations
# Move old promotional emails to trash
# Permanently delete very old messages (careful!)
Rule-Based Management
# Preview all rules
# Execute only trash rules
# Execute all rules
See Also
- Library Documentation - Rust API reference and programming examples
- API Documentation - Generated API reference
- Repository - Source code, examples, and issue tracking
- Gmail API Documentation - Google's official API docs
- Gmail Search Operators - Complete Gmail query syntax
cull-gmail Library Documentation
The cull-gmail library provides a Rust API for managing Gmail messages through the Gmail API. It enables programmatic email culling operations including authentication, message querying, filtering, and batch operations (trash/delete).
Installation
Add the library to your Cargo.toml:
[]
= "0.0.16"
= { = "1.0", = ["macros", "rt-multi-thread"] }
Quick Start
Here's a minimal example to get started:
use ;
async
Core Types
GmailClient
The main client for interacting with Gmail API:
use ;
// Create client with configuration
let mut client = new_with_config.await?;
// Query messages with Gmail search syntax
client.set_query;
client.add_labels?;
client.set_max_results;
// Get messages (0 = all pages, 1 = first page only)
client.get_messages.await?;
// Access message data
let messages = client.messages;
let message_ids = client.message_ids;
ClientConfig
Handles authentication and configuration:
use ClientConfig;
// From credential file
let config = builder
.with_credential_file
.with_config_path
.build;
// From individual OAuth2 parameters
let config = builder
.with_client_id
.with_client_secret
.with_auth_uri
.with_token_uri
.add_redirect_uri
.build;
Rules and Retention Policies
Define automated message lifecycle rules:
use ;
// Create a rule set
let mut rules = new;
// Add retention rules
rules.add_rule;
rules.add_rule;
// Save rules to file
rules.save?;
// Load existing rules
let loaded_rules = load?;
Message Operations
Batch operations on messages:
use ;
// Set up rule and dry-run mode
client.set_execute; // Dry run - no actual changes
let rule = rules.get_rule.unwrap;
client.set_rule;
// Find messages matching rule for a label
client.find_rule_and_messages_for_label.await?;
// Check what action would be performed
if let Some = client.action
// Execute for real
client.set_execute;
match client.action
Configuration
OAuth2 Setup
- Create OAuth2 credentials in Google Cloud Console
- Download the credential JSON file
- Configure the client:
let config = builder
.with_credential_file
.build;
Configuration File
The library supports TOML configuration files (default: ~/.cull-gmail/cull-gmail.toml):
= "credential.json"
= "~/.cull-gmail"
= "rules.toml"
= false
# Alternative: direct OAuth2 parameters
# client_id = "your-client-id"
# client_secret = "your-client-secret"
# token_uri = "https://oauth2.googleapis.com/token"
# auth_uri = "https://accounts.google.com/o/oauth2/auth"
Environment Variables
Override configuration with environment variables:
Error Handling
The library uses a comprehensive error type:
use ;
match client.get_messages.await
Common error types:
NoLabelsFound: Mailbox has no labelsLabelNotFoundInMailbox(String): Specific label not foundRuleNotFound(usize): Rule ID doesn't existGoogleGmail1(Box<google_gmail1::Error>): Gmail API errorsStdIO(std::io::Error): File I/O errorsConfig(config::ConfigError): Configuration errors
Async Runtime
The library requires an async runtime (Tokio recommended):
[]
= { = "1.0", = ["macros", "rt-multi-thread"] }
async
Gmail Query Syntax
The library supports Gmail's search syntax for message queries:
// Date-based queries
client.set_query; // Older than 1 year
client.set_query; // Newer than 30 days
client.set_query; // After specific date
// Label-based queries
client.set_query; // Has promotions label
client.set_query; // Does NOT have important label
// Content queries
client.set_query; // Subject contains "newsletter"
client.set_query; // From specific sender
// Combined queries
client.set_query;
Performance & Limits
Pagination
- Default page size: 200 messages
- Use
client.set_max_results(n)to adjust - Use
client.get_messages(0)to get all pages - Use
client.get_messages(n)to limit to n pages
Rate Limits
- The library uses the official
google-gmail1crate - Built-in retry logic for transient errors
- Respects Gmail API quotas and limits
Batch Operations
- Batch delete/trash operations are more efficient than individual calls
- Operations are atomic - either all succeed or all fail
Logging
The library uses the log crate for logging:
use env_logger;
// Initialize logging
init;
# Set log level via environment variable
# RUST_LOG=cull_gmail=debug cargo run
Log levels:
error: Critical errorswarn: Warnings (e.g., missing labels, dry-run mode)info: General information (e.g., message subjects, action results)debug: Detailed operation infotrace: Very detailed debugging info
Security Considerations
OAuth2 Token Storage
- Tokens are stored in
~/.cull-gmail/gmail1by default - Tokens are automatically refreshed when expired
- Revoke access in Google Account settings
Required Scopes
The library requires the https://mail.google.com/ scope for full Gmail access.
OAuth2 File Security
- Store OAuth2 credential files securely (not in version control)
- Use restrictive file permissions (600)
- Consider using environment variables in production
Troubleshooting
Authentication Issues
- Verify OAuth2 credential file path and JSON format
- Check OAuth2 client is configured for "Desktop Application"
- Ensure redirect URI matches configuration
- Clear token cache:
rm -rf ~/.cull-gmail/gmail1
No Messages Found
- Verify label names exist:
client.show_label() - Test query syntax in Gmail web interface
- Check for typos in label names or query strings
Rate Limiting
- Reduce page size:
client.set_max_results(100) - Add delays between operations
- Check Gmail API quotas
See Also
- CLI Documentation - Complete guide to the command-line interface
- Examples Directory - Additional code examples and sample configurations
- API Documentation - Generated API reference
- Repository - Source code and issue tracking
License
By contributing to cull-gmail, you agree that your contributions will be licensed under the MIT License. This means:
- You grant permission for your contributions to be used, modified, and distributed under the terms of the MIT License
- You confirm that you have the right to submit the code under this license
- You understand that your contributions will become part of the project and available to all users under the MIT License
Contribution
Thank you for your interest in contributing to cull-gmail! We welcome contributions from the community and appreciate your help in making this project better.
Further details can be found in the contribution document.