Invoice Pilot is a fully automated invoice and bank statement management tool built with Rust. This project is completely free to use, modify, and distribute under the MIT License.
- What It Does
- Features
- Prerequisites
- Installation
- Configuration
- Usage
- How It Works
- Supported Financial Institutions
- Scheduling
- Troubleshooting
- Development
- Contributing
- License
✅ Fetches invoices and bank statements from Gmail
✅ Automatically detects financial institutions (banks, brokerages, exchanges, payment processors)
✅ Downloads all attachments from matching emails
✅ Organizes files by institution in Google Drive with proper capitalization
✅ Creates smart filenames with sender names (e.g., langfuse-gmbh-invoice-12345.pdf)
✅ Prevents duplicates by checking existing files
✅ Runs manually or on schedule
- Dual Google account support (separate accounts for Gmail and Drive)
- OAuth2 authentication with token caching
- Automatic token refresh
- Gmail search for invoices/faturas/bank statements with attachments
- Smart filename prefixing with sender names
- Automatic financial institution detection for banks, brokerages, exchanges, and payment processors
- Financial institution folder organization (separate folders per institution with proper capitalization)
- Google Drive upload with automatic folder creation
- Manual and scheduled execution modes with Docker-based automation
- Automatic monthly scheduling - runs on configured day without user interaction
- Duplicate detection and skipping
- Comprehensive error handling and logging
- Install Rust: https://rustup.rs/
- Cargo will be installed automatically with Rust
- Install Just: https://github.com/casey/just#installation
- Or:
cargo install just@1.43.0
You need TWO Google Cloud projects (or one project with two OAuth2 clients):
- Go to Google Cloud Console
- Create a new project or select existing one
- Enable Gmail API:
- Navigate to "APIs & Services" > "Library"
- Search for "Gmail API"
- Click "Enable"
- Create OAuth2 Credentials:
- Go to "APIs & Services" > "Credentials"
- Click "Create Credentials" > "OAuth client ID"
- Application type: Desktop app
- Name: "invoice pilot - Gmail"
- Click "Create"
- Save the Client ID and Client Secret
- Configure OAuth consent screen:
- Go to "APIs & Services" > "OAuth consent screen"
- Add scope:
https://www.googleapis.com/auth/gmail.readonly
- Create another project or use the same project
- Enable Google Drive API:
- Navigate to "APIs & Services" > "Library"
- Search for "Google Drive API"
- Click "Enable"
- Create OAuth2 Credentials:
- Go to "APIs & Services" > "Credentials"
- Click "Create Credentials" > "OAuth client ID"
- Application type: Desktop app
- Name: "invoice pilot - Drive"
- Click "Create"
- Save the Client ID and Client Secret
- Configure OAuth consent screen:
- Go to "APIs & Services" > "OAuth consent screen"
- Add scope:
https://www.googleapis.com/auth/drive.file
# Clone the repository
git clone https://github.com/adolfousier/invoicepilot.git
cd invoice-pilot
# Build and run the project
just run
# The binary will be at target/release/invoice-pilotIf you prefer not to use just, you can build manually:
cargo build --release
./target/release/invoice-pilot-
Copy the example environment file to the docker directory:
cp .env.example docker/.env
Important: The
.envfile must be placed inside thedocker/directory for the database and application to work correctly. -
Edit
docker/.envand fill in your credentials:# Gmail account credentials (Account A) GOOGLE_GMAIL_CLIENT_ID=your-gmail-client-id.apps.googleusercontent.com GOOGLE_GMAIL_CLIENT_SECRET=your-gmail-client-secret # Drive account credentials (Account B) GOOGLE_DRIVE_CLIENT_ID=your-drive-client-id.apps.googleusercontent.com GOOGLE_DRIVE_CLIENT_SECRET=your-drive-client-secret # Drive folder path (will be created if it doesn't exist) GOOGLE_DRIVE_FOLDER_LOCATION=billing/all-expenses/2025 # Day of month to fetch invoices (1-31) FETCH_INVOICES_DAY=5 # Keywords to search for (comma-separated) TARGET_KEYWORDS_TO_FETCH_AND_DOWNLOAD="invoice, invoices, fatura, faturas, statement, bank, extrato, movimientos, financial, fiscal, tributary"
🚀 Default Mode: The interactive TUI is now the default and recommended way to use Invoice Pilot. Simply run cargo run with no arguments.
The interactive TUI (Terminal User Interface) provides a user-friendly, guided experience for managing your invoice processing:
cargo run
# or explicitly:
cargo run -- tui- 4-Panel Dashboard: Manual Processing, Authentication, Scheduled Mode, and Activity Log
- Interactive calendar widget in Scheduled Mode panel showing current month with highlighted scheduled days
- Visual menu navigation with keyboard controls (Tab to switch panels)
- Real-time progress display during processing with live updates
- Interactive date input with validation (YYYY-MM-DD format)
- OAuth authentication flow with URL display in dedicated popup
- Results summary with detailed breakdowns by bank/institution
- Animated authentication status indicators with progress bars for Gmail and Drive
- Context-sensitive help (press ? for help, Esc for setup guide)
- Error handling with clear error messages and recovery options
| Key | Action |
|---|---|
Tab / Shift+Tab |
Switch between panels |
Enter |
Open configuration popup for current panel |
Esc |
Close popup or quit application |
Q |
Quit application |
? |
Show help or setup guide |
Manual Processing Panel:
Enter: Start processing or configure datesR: Reset dates and resultsC: Cancel processing (when running)
Authentication Panel:
G: Authenticate Gmail accountD: Authenticate Google Drive accountR: Reset all authentication tokens
Scheduled Mode Panel:
- Calendar View: Shows current month with scheduled day highlighted in yellow
Enter: Configure scheduled processing dayS: Trigger manual scheduled run
Activity Log Panel:
- Read-only activity feed with timestamps
- Launch TUI: Run
just dev(orcargo runif you don't havejustinstalled) - Setup Guide: If no
.envfile exists, press?for the setup guide - Configure Environment: Follow the setup guide to create your
.envfile - Authenticate Services:
- Navigate to Authentication panel (Tab key)
- Press
Gto authenticate Gmail - Press
Dto authenticate Google Drive - Copy the displayed OAuth URL and complete authorization in browser
- Configure Processing:
- Switch to Manual Processing panel
- Press
Enterto set date range - Use
Tabto switch between start/end dates - Type dates in YYYY-MM-DD format
- Run Processing: Press
Enterin Manual Processing panel to start
- Authentication: Set up Gmail and Drive access (one-time setup)
- Date Configuration: Specify the date range for invoice search
- Processing: Monitor real-time progress as emails are searched and files uploaded
- Results Review: Check the Activity Log and Manual Processing panels for results
- Scheduled Setup: Configure automatic monthly processing in Scheduled Mode panel
- Configuration Errors: Setup guide appears automatically
- Authentication Failures: Clear error messages with retry options
- Processing Errors: Detailed error logs in Activity panel
- Network Issues: Automatic retry with user notification
- Invalid Input: Field validation with helpful error messages
The TUI provides a complete, professional interface for invoice processing with guided setup, real-time feedback, and comprehensive error handling.
For scripting or automation, the original CLI mode is still available:
On first run, you'll need to authorize both accounts:
cargo run -- manualThis will:
- Open a browser for Gmail authorization (Account A)
- Open a browser for Drive authorization (Account B)
- Cache tokens locally at
~/.config/invoice-pilot/ - Fetch invoices from the previous month and upload to Drive
cargo run -- manualcargo run -- manual --date-range 2024-09-01:2024-10-12Run on a schedule using systemd timer or cron:
cargo run -- scheduledThis will only execute if today matches FETCH_INVOICES_DAY from .env.
cargo run -- auth gmailcargo run -- auth drivecargo run -- auth reset- Searches Gmail for emails containing your configured keywords (invoice, fatura, statement, bank, etc.)
- Downloads ALL attachments from matching emails
- Creates smart filenames with sender names (e.g.,
langfuse-gmbh-invoice-12345.pdf)
- Identifies banks, brokerages, exchanges, and payment processors from email content
- Organizes files by institution in separate folders with proper capitalization
- Supports 100+ European banks, Wise, Revolut, Coinbase, Stripe, PayPal, and more
- Uses keywords like "bank", "banco", "statement", "financial", "fiscal", "tributary"
- Creates monthly folders automatically (e.g.,
2025/,2024/) - Creates institution-specific folders (e.g.,
Stripe/,Wise/,Coinbase/) - Uploads files with proper organization
- Prevents duplicates by checking existing files
- Wise (formerly TransferWise)
- Revolut
- Nubank
- Bunq
- Monzo
- Starling Bank
- Chime
- PayPal
- Stripe
- Adyen
- Mollie
- Santander
- BBVA
- CaixaBank
- ING
- Deutsche Bank
- HSBC
- Barclays
- And many more European banks
- Interactive Brokers
- Charles Schwab
- E*TRADE
- TD Ameritrade
- Fidelity
- Robinhood
- Webull
- Coinbase
- Binance
- Kraken
- Coinbase Pro
- Binance US
If FETCH_INVOICES_DAY is set in your .env file, Invoice Pilot can run automatically on the specified day of each month. The scheduled command will automatically spin up a Docker container to execute the job, ensuring isolation and reliability.
In automated mode, cached OAuth tokens are used, so no user interaction or browser opening is required. The job runs in a container with mounted volumes for configuration and tokens.
To use automated execution:
- Build the Docker image:
cd docker && docker-compose build - Run the scheduled command:
cargo run -- scheduled(or./target/release/invoice-pilot scheduled)
If you prefer external scheduling, you can still set up systemd timers or cron jobs as described below.
-
Create the service file
/etc/systemd/system/invoice-pilot.service:[Unit] Description=Invoice Pilot [Service] Type=oneshot User=your-username WorkingDirectory=/path/to/invoice-pilot ExecStart=/path/to/invoice-pilot/target/release/invoice-pilot scheduled Environment="PATH=/usr/local/bin:/usr/bin:/bin"
-
Create the timer file
/etc/systemd/system/invoice-pilot.timer:[Unit] Description=Invoice Pilot Monthly Check [Timer] OnCalendar=*-*-{FETCH_INVOICES_DAY} Persistent=true [Install] WantedBy=timers.target
Replace
{FETCH_INVOICES_DAY}with your configured day (e.g.,05for the 5th of each month). -
Enable and start the timer:
sudo systemctl daemon-reload sudo systemctl enable invoice-pilot.timer sudo systemctl start invoice-pilot.timer # Check status sudo systemctl status invoice-pilot.timer
Add to your crontab (crontab -e):
# Run on the configured day of each month at 9 AM
0 9 {FETCH_INVOICES_DAY} * * cd /path/to/invoice-pilot && /path/to/invoice-pilot/target/release/invoice-pilot scheduled >> /var/log/invoice-pilot.log 2>&1Replace {FETCH_INVOICES_DAY} with your configured day (e.g., 5 for the 5th of each month).
The OAuth callback uses port 8080. If it's in use:
- Close any running instances of the tool
- Check for other services using port 8080
- Kill the process:
lsof -ti:8080 | xargs kill -9
If you get authorization errors:
- Check that APIs are enabled in Google Cloud Console
- Verify OAuth2 scopes are configured correctly
- Re-authenticate:
cargo run -- auth reset - Make sure redirect URI is set to
http://localhost:8080in Google Cloud Console
Tokens auto-refresh, but if you encounter issues:
cargo run -- auth reset
cargo run -- manual- Check the date range
- Verify your Gmail account has emails matching the search criteria
- Try searching manually in Gmail with the query shown in logs
- Ensure your keywords include terms like "statement", "bank", or specific bank names
- Check if bank statements are being sent to a different email address
# Run all tests
cargo test
# Run with output
cargo test -- --nocapturesrc/
├── auth/ # OAuth2 authentication
│ ├── oauth.rs # Base OAuth2 logic
│ ├── gmail_auth.rs # Gmail-specific auth
│ └── drive_auth.rs # Drive-specific auth
├── gmail/ # Gmail API client
│ ├── client.rs # HTTP client
│ ├── search.rs # Email search with bank detection
│ └── attachment.rs # Attachment download with sender/bank extraction
├── drive/ # Google Drive API client
│ ├── client.rs # HTTP client
│ ├── folder.rs # Folder management
│ └── upload.rs # File upload
├── scheduler/ # Scheduling logic
│ └── runner.rs # Date calculations
├── config/ # Configuration
│ └── env.rs # .env parsing
├── cli/ # CLI interface
│ └── args.rs # Argument parsing
└── main.rs # Application entry point
- Never commit
.envfile or tokens to version control - Tokens are stored in
~/.config/invoice-pilot/with user-only permissions - OAuth2 uses PKCE for enhanced security
- All API calls use HTTPS
We welcome contributions from everyone! This is an open-source project, and we value any help you can provide.
- Fork the repository on GitHub
- Create a feature branch:
git checkout -b feature/amazing-feature - Make your changes with tests if applicable
- Commit your changes:
git commit -m 'feat: add amazing feature' - Push to the branch:
git push origin feature/amazing-feature - Open a Pull Request with a clear description of your changes
- Code Style: Follow Rust best practices and existing code style
- Tests: Add tests for new functionality when possible
- Documentation: Update documentation for new features
- Breaking Changes: Clearly mark breaking changes in PR descriptions
- Use the GitHub issue tracker to report bugs
- Include steps to reproduce, expected behavior, and actual behavior
- For feature requests, describe the problem and proposed solution
- New Bank/Institution Support: Add detection for new financial institutions
- Improved Error Handling: Enhance error messages and recovery
- Performance Optimizations: Speed up Gmail search or file uploads
- Documentation: Improve README or add usage examples
- Testing: Add more comprehensive test coverage
- Clone the repository:
git clone https://github.com/adolfousier/invoicepilot.git - Set up development environment:
cargo build - Run existing tests:
cargo test - Make your changes
- Test thoroughly:
cargo build && cargo test - Submit your pull request
Thank you for contributing to Invoice Pilot! 🚀
This project is licensed under the MIT License - see the LICENSE file for details.
This software is completely free to use, modify, and distribute for any purpose.
For issues, questions, or contributions, please open an issue on GitHub.
