Email Channel
The Email channel enables ZeroClaw to communicate via email using IMAP for receiving messages and SMTP for sending replies, with support for IMAP IDLE for instant push notifications.Overview
- Channel Name:
email - Transport: IMAP (receive) + SMTP (send)
- Authentication: Username/password
- Public Port Required: No
- Supports: Text, HTML, attachments, allowlist filtering
Configuration
Required Settings
Complete Configuration
Provider-Specific Examples
Gmail
- Go to Google Account settings
- Security → 2-Step Verification
- App passwords → Generate new password
- Use generated password in config
Outlook/Office 365
Yahoo Mail
NetEase (163.com / 126.com)
Features
IMAP IDLE (Push Mode)
The channel uses IMAP IDLE (RFC 2177) for instant push notifications: How it works:- Connect to IMAP server with TLS
- Authenticate with username/password
- Select mailbox (default: INBOX)
- Check for existing unseen messages
- Enter IDLE mode
- Server pushes notifications when new mail arrives
- Fetch and process new messages
- Re-enter IDLE
- Default: 1740 seconds (29 minutes)
- RFC 2177 recommends clients restart IDLE every 29 minutes
- Automatic reconnection on timeout
- Exponential backoff on connection errors
- Instant delivery (no delay)
- Lower server load
- Lower bandwidth usage
- Standard protocol support
Allowlist Filtering
Empty List (Deny All)
Wildcard (Allow All)
Specific Email Addresses
Domain Matching
Mixed Rules
Message Processing
Text Extraction
Priority:- Plain text body (MIME
text/plain) - HTML body (MIME
text/html) - HTML tags stripped - Text attachments
- Fallback:
"(no readable content)"
Subject Handling
Subject is prefixed to content:IMAP ID Extension (RFC 2971)
Sends client identification after login:- Some providers (NetEase) require it
- Helps with debugging
- Provider can optimize for known clients
name- Client application nameversion- Client versionvendor- Vendor/organization name
Attachment Support
Current Implementation:- Text attachments inlined:
[Attachment: file.txt]\ncontent - Other MIME types skipped
Reply Threading
Replies are sent to the sender’s address:Implementation Details
Source Location
src/channels/email_channel.rs (1106 lines)
Key Components
EmailChannel Struct
EmailConfig
Connection Flow
IMAP (Receive)
- TCP Connect:
TcpStream::connect(host:port) - TLS Handshake: rustls with system root certificates
- IMAP Greeting: Wait for server hello
- LOGIN:
LOGIN username password - IMAP ID: Send RFC 2971 metadata (if enabled)
- SELECT: Open mailbox (INBOX)
- SEARCH: Find unseen messages:
UID SEARCH UNSEEN - FETCH: Download message bodies:
UID FETCH ... RFC822 - STORE: Mark as seen:
UID STORE ... +FLAGS (\Seen) - IDLE: Enter idle mode:
IDLE - Wait: Block until server notification or timeout
- DONE: Exit idle:
DONE - Repeat from step 7
SMTP (Send)
- TCP Connect: (TLS port 465 or STARTTLS port 587)
- TLS: Establish encrypted connection
- EHLO: Identify client
- AUTH: Authenticate with credentials
- MAIL FROM: Set sender
- RCPT TO: Set recipient
- DATA: Send message body
- QUIT: Close connection
Message Deduplication
Prevents processing same email twice: Mechanism:- Tracks seen message IDs in memory:
HashSet<String> - Message ID from
Message-IDheader or generated UUID - Persists across IDLE reconnections
- Not persisted to disk (resets on restart)
- Marks all unseen messages in inbox as seen
- Processes them once
- Future restarts see no unseen messages
Error Recovery
Connection Loss:- Log error with backoff counter
- Wait 1 second
- Exponential backoff: 2s, 4s, 8s, …, max 60s
- Reconnect from scratch
- Resume listening
- Exit IDLE cleanly with
DONE - Check for new messages
- Re-enter IDLE
Error Handling
Common Errors
Authentication Failed:- Verify username/password
- Check if app passwords required
- Enable IMAP access in provider settings
- Check firewall rules
- Verify IMAP port (993 for TLS)
- Test with telnet:
openssl s_client -connect imap.example.com:993
- Update system root certificates
- Check system time (affects cert validation)
Runtime Commands
Not applicable - email operates asynchronously.Best Practices
- Use App Passwords: For Gmail, Yahoo, etc.
- Allowlist Domains: Use
@company.comfor organizations - Dedicated Account: Create separate email for bot
- Monitor Logs: Watch for connection errors
- IMAP ID: Enable for NetEase and other providers requiring it
- TLS Always: Never disable
smtp_tls
Troubleshooting
No Messages Received
Check Allowlist:Email IDLE listening on INBOX (instant push enabled)Blocked email from ...Email poll failed:
Messages Not Sending
Check SMTP Credentials: Same as IMAP username/password (usually) Check Port:- Port 465: SMTP over TLS (smtps)
- Port 587: SMTP with STARTTLS
IDLE Keeps Disconnecting
Provider Limit: Some providers close IDLE after shorter timeout. Solution: Reduce timeout:Performance
Message Latency
IMAP IDLE:- Delivery: <5 seconds (instant push)
- Processing: Depends on agent/provider
- Poll interval: Configurable (default: 60s)
- Latency: 0-60 seconds
Optimization Tips
- IDLE Over Polling: Always preferred
- Reduce Timeout: Lower for flaky networks
- Dedicated Mailbox: Use separate folder if needed
- Allowlist: Reduces processing overhead
Security
Credential Protection
- Stored in config file (protect with permissions:
chmod 600) - Never logged
- Transmitted over TLS only
TLS Configuration
- IMAP: Port 993 (implicit TLS)
- SMTP: Port 465 (implicit TLS) or 587 (STARTTLS)
- Uses system root certificates (rustls + webpki-roots)
- Certificate validation always enabled
Allowlist Enforcement
- Checked before any processing
- Case-insensitive for email addresses
- Logged when blocked: