From 7afbb1d56d9587a339cdc05fc6b49be031133cd6 Mon Sep 17 00:00:00 2001 From: Jeremiah Russell Date: Fri, 17 Oct 2025 17:00:28 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=93=9D=20docs(lib):=20add=20comprehensive?= =?UTF-8?q?=20library=20documentation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - introduce library's purpose, installation, and quick start guide - describe core types (gmailclient, clientconfig, rules) with usage examples - explain configuration options (oauth2, config file, environment variables) - detail error handling, async runtime requirements, and gmail query syntax - cover performance considerations (pagination, rate limits, batch operations) - provide logging setup, security considerations, and troubleshooting tips - include links to cli documentation, examples, api reference, and repository --- docs/readme/lib.md | 335 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 335 insertions(+) create mode 100644 docs/readme/lib.md diff --git a/docs/readme/lib.md b/docs/readme/lib.md new file mode 100644 index 0000000..0c4f184 --- /dev/null +++ b/docs/readme/lib.md @@ -0,0 +1,335 @@ +# 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`: + +```toml +[dependencies] +cull-gmail = "0.0.10" +tokio = { version = "1.0", features = ["macros", "rt-multi-thread"] } +``` + +## Quick Start + +Here's a minimal example to get started: + +```rust path=null start=null +use cull_gmail::{ClientConfig, GmailClient, Result}; + +#[tokio::main] +async fn main() -> Result<()> { + // Load configuration from file or environment + let config = ClientConfig::builder() + .with_credential_file("credential.json") + .build(); + + // Create Gmail client and authenticate + let mut client = GmailClient::new_with_config(config).await?; + + // List first 10 messages + client.set_max_results(10); + client.get_messages(1).await?; + client.log_messages().await?; + + Ok(()) +} +``` + +## Core Types + +### GmailClient + +The main client for interacting with Gmail API: + +```rust path=null start=null +use cull_gmail::{GmailClient, MessageList}; + +// Create client with configuration +let mut client = GmailClient::new_with_config(config).await?; + +// Query messages with Gmail search syntax +client.set_query("older_than:1y label:promotions"); +client.add_labels(&["INBOX".to_string()])?; +client.set_max_results(200); + +// Get messages (0 = all pages, 1 = first page only) +client.get_messages(0).await?; + +// Access message data +let messages = client.messages(); +let message_ids = client.message_ids(); +``` + +### ClientConfig + +Handles authentication and configuration: + +```rust path=null start=null +use cull_gmail::ClientConfig; + +// From credential file +let config = ClientConfig::builder() + .with_credential_file("path/to/credential.json") + .with_config_path(".cull-gmail") + .build(); + +// From individual OAuth2 parameters +let config = ClientConfig::builder() + .with_client_id("your-client-id") + .with_client_secret("your-client-secret") + .with_auth_uri("https://accounts.google.com/o/oauth2/auth") + .with_token_uri("https://oauth2.googleapis.com/token") + .add_redirect_uri("http://localhost:8080") + .build(); +``` + +### Rules and Retention Policies + +Define automated message lifecycle rules: + +```rust path=null start=null +use cull_gmail::{Rules, Retention, MessageAge, EolAction}; + +// Create a rule set +let mut rules = Rules::new(); + +// Add retention rules +rules.add_rule( + Retention::new(MessageAge::Years(1), true), + Some(&"old-emails".to_string()), + false // false = trash, true = delete +); + +rules.add_rule( + Retention::new(MessageAge::Months(6), true), + Some(&"promotions".to_string()), + false +); + +// Save rules to file +rules.save()?; + +// Load existing rules +let loaded_rules = Rules::load()?; +``` + +### Message Operations + +Batch operations on messages: + +```rust path=null start=null +use cull_gmail::{RuleProcessor, EolAction}; + +// Set up rule and dry-run mode +client.set_execute(false); // Dry run - no actual changes +let rule = rules.get_rule(1).unwrap(); +client.set_rule(rule); + +// Find messages matching rule for a label +client.find_rule_and_messages_for_label("promotions").await?; + +// Check what action would be performed +if let Some(action) = client.action() { + match action { + EolAction::Trash => println!("Would move {} messages to trash", client.messages().len()), + EolAction::Delete => println!("Would delete {} messages permanently", client.messages().len()), + } +} + +// Execute for real +client.set_execute(true); +match client.action() { + Some(EolAction::Trash) => client.batch_trash().await?, + Some(EolAction::Delete) => client.batch_delete().await?, + None => println!("No action specified"), +} +``` + +## Configuration + +### OAuth2 Setup + +1. Create OAuth2 credentials in [Google Cloud Console](https://console.cloud.google.com/) +2. Download the credential JSON file +3. Configure the client: + +```rust path=null start=null +let config = ClientConfig::builder() + .with_credential_file("path/to/credential.json") + .build(); +``` + +### Configuration File + +The library supports TOML configuration files (default: `~/.cull-gmail/cull-gmail.toml`): + +```toml +credentials = "credential.json" +config_root = "~/.cull-gmail" +rules = "rules.toml" +execute = 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: + +```bash +export APP_CREDENTIALS="/path/to/credential.json" +export APP_EXECUTE="true" +export APP_CLIENT_ID="your-client-id" +export APP_CLIENT_SECRET="your-client-secret" +``` + +## Error Handling + +The library uses a comprehensive error type: + +```rust path=null start=null +use cull_gmail::{Error, Result}; + +match client.get_messages(1).await { + Ok(_) => println!("Success!"), + Err(Error::NoLabelsFound) => println!("No labels found in mailbox"), + Err(Error::LabelNotFoundInMailbox(label)) => println!("Label '{}' not found", label), + Err(Error::GoogleGmail1(e)) => println!("Gmail API error: {}", e), + Err(e) => println!("Other error: {}", e), +} +``` + +Common error types: +- `NoLabelsFound`: Mailbox has no labels +- `LabelNotFoundInMailbox(String)`: Specific label not found +- `RuleNotFound(usize)`: Rule ID doesn't exist +- `GoogleGmail1(Box)`: Gmail API errors +- `StdIO(std::io::Error)`: File I/O errors +- `Config(config::ConfigError)`: Configuration errors + +## Async Runtime + +The library requires an async runtime (Tokio recommended): + +```toml +[dependencies] +tokio = { version = "1.0", features = ["macros", "rt-multi-thread"] } +``` + +```rust path=null start=null +#[tokio::main] +async fn main() -> cull_gmail::Result<()> { + // Your code here + Ok(()) +} +``` + +## Gmail Query Syntax + +The library supports Gmail's search syntax for message queries: + +```rust path=null start=null +// Date-based queries +client.set_query("older_than:1y"); // Older than 1 year +client.set_query("newer_than:30d"); // Newer than 30 days +client.set_query("after:2023/1/1"); // After specific date + +// Label-based queries +client.set_query("label:promotions"); // Has promotions label +client.set_query("-label:important"); // Does NOT have important label + +// Content queries +client.set_query("subject:newsletter"); // Subject contains "newsletter" +client.set_query("from:noreply@example.com"); // From specific sender + +// Combined queries +client.set_query("label:promotions older_than:6m -is:starred"); +``` + +## 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-gmail1` crate +- 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: + +```rust path=null start=null +use env_logger; + +// Initialize logging +env_logger::init(); + +# Set log level via environment variable +# RUST_LOG=cull_gmail=debug cargo run +``` + +Log levels: +- `error`: Critical errors +- `warn`: Warnings (e.g., missing labels, dry-run mode) +- `info`: General information (e.g., message subjects, action results) +- `debug`: Detailed operation info +- `trace`: Very detailed debugging info + +## Security Considerations + +### OAuth2 Token Storage +- Tokens are stored in `~/.cull-gmail/gmail1` by default +- Tokens are automatically refreshed when expired +- Revoke access in [Google Account settings](https://myaccount.google.com/permissions) + +### Required Scopes +The library requires the `https://mail.google.com/` scope for full Gmail access. + +### Credential File Security +- Store credential files securely (not in version control) +- Use restrictive file permissions (600) +- Consider using environment variables in production + +## Troubleshooting + +### Authentication Issues +1. Verify credential file path and format +2. Check OAuth2 client is configured for "Desktop Application" +3. Ensure redirect URI matches configuration +4. Clear token cache: `rm -rf ~/.cull-gmail/gmail1` + +### No Messages Found +1. Verify label names exist: `client.show_label()` +2. Test query syntax in Gmail web interface +3. Check for typos in label names or query strings + +### Rate Limiting +1. Reduce page size: `client.set_max_results(100)` +2. Add delays between operations +3. Check [Gmail API quotas](https://developers.google.com/gmail/api/reference/quota) + +## See Also + +- [CLI Documentation](main.md) - Complete guide to the command-line interface +- [Examples Directory](../examples/) - Additional code examples and sample configurations +- [API Documentation](https://docs.rs/cull-gmail) - Generated API reference +- [Repository](https://github.com/jerus-org/cull-gmail) - Source code and issue tracking