feat: aso add label for ai processed
This commit is contained in:
parent
56c9f764fc
commit
6de059dca7
3 changed files with 243 additions and 2 deletions
165
CLAUDE.md
Normal file
165
CLAUDE.md
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Project Overview
|
||||
|
||||
ParaClub AI Mailer is an automated email response system written in Go that:
|
||||
- Fetches emails via IMAP from a configured mailbox
|
||||
- Gathers context from configured URLs (HTML content extraction)
|
||||
- Uses OpenRouter AI API to generate context-aware email replies
|
||||
- Saves AI-generated responses as email drafts
|
||||
- Processes emails sequentially with configurable polling intervals
|
||||
|
||||
The system is designed as a long-running service with graceful shutdown handling.
|
||||
|
||||
## Build and Run Commands
|
||||
|
||||
```bash
|
||||
# Install dependencies
|
||||
go mod download
|
||||
|
||||
# Build the application
|
||||
go build -o paraclub-ai-mailer ./cmd/paraclub-ai-mailer
|
||||
|
||||
# Run with default config (config.yaml in current directory)
|
||||
./paraclub-ai-mailer
|
||||
|
||||
# Run with custom config path
|
||||
./paraclub-ai-mailer -config /path/to/config.yaml
|
||||
|
||||
# Run tests (if any exist)
|
||||
go test ./...
|
||||
|
||||
# Format code
|
||||
go fmt ./...
|
||||
|
||||
# Vet code for issues
|
||||
go vet ./...
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
The application requires a `config.yaml` file. Use `config.yaml.example` as a template.
|
||||
|
||||
Key configuration sections:
|
||||
- **imap**: Server details, credentials, mailbox folders
|
||||
- **ai**: OpenRouter API key, model selection, temperature, max tokens
|
||||
- **context**: List of URLs to fetch as context for AI
|
||||
- **polling**: Email check interval (e.g., "5m")
|
||||
- **logging**: Log level and file path
|
||||
|
||||
Credentials support three formats:
|
||||
- Direct value: `password: "mypassword"`
|
||||
- Environment variable: `password: "${IMAP_PASSWORD}"`
|
||||
- File reference: `password: "file:///path/to/password.txt"`
|
||||
|
||||
## Code Architecture
|
||||
|
||||
### Module Structure
|
||||
|
||||
```
|
||||
cmd/paraclub-ai-mailer/main.go # Entry point, orchestration
|
||||
config/config.go # Configuration loading and validation
|
||||
internal/
|
||||
├── logger/logger.go # Centralized logging wrapper (logrus)
|
||||
├── imap/imap.go # IMAP client, email operations
|
||||
├── fetcher/fetcher.go # HTML content fetching and text extraction
|
||||
└── ai/ai.go # OpenRouter AI integration
|
||||
```
|
||||
|
||||
### Key Design Patterns
|
||||
|
||||
**Email Processing Flow** (main.go:92-172):
|
||||
1. Fetch unprocessed emails (UNSEEN flag)
|
||||
2. Fetch context from all configured URLs
|
||||
3. For each email:
|
||||
- Detect language via AI
|
||||
- Generate AI reply with context
|
||||
- Save as draft with original email quoted
|
||||
- Mark as processed (move to processed_box, mark as read)
|
||||
|
||||
**IMAP Client** (internal/imap/imap.go):
|
||||
- Connection handling with automatic reconnection (ensureConnection, reconnect)
|
||||
- Folder path normalization with delimiter detection
|
||||
- Gmail-specific logic in ensureFolder (uses "/" delimiter, handles system folders)
|
||||
- Email content extraction handles multipart messages and quoted-printable encoding
|
||||
- Draft formatting includes HTML response + quoted original message
|
||||
- Panic recovery in SaveDraft and MarkAsProcessed
|
||||
|
||||
**AI Integration** (internal/ai/ai.go):
|
||||
- Two-stage process: language detection, then reply generation
|
||||
- Language-aware responses (system prompt includes detected language)
|
||||
- Output must be raw HTML (not markdown-wrapped)
|
||||
- Retry logic with max 3 attempts
|
||||
|
||||
**Context Fetching** (internal/fetcher/fetcher.go):
|
||||
- HTML to plain text extraction (strips tags, extracts text nodes)
|
||||
- 30-second timeout per URL
|
||||
- Batch fetching fails if any URL fails
|
||||
|
||||
### Important Implementation Details
|
||||
|
||||
**MIME Email Parsing** (internal/imap/imap.go:287-510):
|
||||
- `extractMessageContent` handles multipart and single-part messages
|
||||
- Content-Transfer-Encoding support: quoted-printable
|
||||
- `cleanMessageContent` has a `performHeaderStripping` flag (true for fallback, false for parsed content)
|
||||
- Extensive debug logging for troubleshooting email parsing issues
|
||||
|
||||
**Folder Management** (internal/imap/imap.go:512-663):
|
||||
- `ensureFolder` detects Gmail vs generic IMAP servers
|
||||
- Gmail: Uses "/" delimiter, skips CREATE for system folders like "[Gmail]/Drafts"
|
||||
- Generic IMAP: Lists mailboxes to detect delimiter, creates folders if missing
|
||||
- Has timeout protection (30s for LIST, 35s overall)
|
||||
- Includes panic recovery
|
||||
|
||||
**Logging Strategy**:
|
||||
- All modules use `internal/logger` wrapper around logrus
|
||||
- Structured logging with fields (logrus.Fields)
|
||||
- Debug level logs include detailed information (e.g., email content lengths, folder paths)
|
||||
- Recent commits show enhanced logging for troubleshooting email extraction
|
||||
|
||||
## Development Guidelines
|
||||
|
||||
### Error Handling
|
||||
- Use defer/recover for panic protection in critical IMAP operations (SaveDraft, MarkAsProcessed, ensureFolder)
|
||||
- Retry mechanisms in AI client (max 3 attempts)
|
||||
- IMAP connection auto-reconnection on failure
|
||||
- Continue processing remaining emails if one fails
|
||||
|
||||
### Adding New Features
|
||||
- **New AI models**: Update config.yaml model parameter (passed to OpenRouter API)
|
||||
- **New context sources**: Add URLs to config.yaml context.urls array
|
||||
- **New IMAP operations**: Add methods to IMAPClient struct, ensure connection handling
|
||||
- **Email format changes**: Modify draft template in SaveDraft (line 242-266)
|
||||
|
||||
### Testing Considerations
|
||||
- Email parsing logic is complex (multipart, encoding) - test with various email formats
|
||||
- Gmail behavior differs from generic IMAP servers
|
||||
- Test with different folder delimiters ("/" vs ".")
|
||||
- Language detection affects response language
|
||||
|
||||
## Dependencies
|
||||
|
||||
Core dependencies (go.mod):
|
||||
- `github.com/emersion/go-imap` - IMAP client library
|
||||
- `github.com/sirupsen/logrus` - Structured logging
|
||||
- `golang.org/x/net/html` - HTML parsing for context extraction
|
||||
- `gopkg.in/yaml.v3` - Configuration file parsing
|
||||
|
||||
## Common Issues
|
||||
|
||||
**IMAP Folder Issues**:
|
||||
- Check logs for delimiter detection (ensureFolder)
|
||||
- Gmail requires special handling for system folders
|
||||
- Folder names are case-sensitive
|
||||
|
||||
**Email Content Extraction**:
|
||||
- Multi-part emails may require different handling
|
||||
- Check Content-Transfer-Encoding header
|
||||
- Recent fixes improved header stripping and content cleaning
|
||||
|
||||
**AI Response Issues**:
|
||||
- Verify API key is correctly loaded from environment/file
|
||||
- Check model name is valid for OpenRouter
|
||||
- Response must be raw HTML (system prompt enforces this)
|
||||
Loading…
Add table
Add a link
Reference in a new issue