← Back to PRs

#21981: feat: Add email channel plugin with channelRuntime support

by guxiaobo open 2026-02-20 16:04 View on GitHub →
gateway size: XL
## Summary This PR adds a fully functional email channel plugin for OpenClaw, enabling email communication via IMAP/SMTP. It also enhances the Plugin SDK to support channel plugins that need access to dispatch and routing utilities. ## Changes ### Email Channel Plugin - **IMAP/SMTP Implementation**: Send and receive emails using standard email protocols - **Sender Filtering**: Configure allowed senders to restrict email processing - **State Persistence**: Track processed emails to avoid duplicates - **Race Condition Protection**: Stable email processing with proper state management ### Plugin SDK Enhancement - Add optional `channelRuntime` field to `ChannelGatewayContext` - Provide channel plugins access to `PluginRuntime['channel']` utilities - Maintain backward compatibility with existing channels ## Files Added ### Email Channel Plugin (`extensions/email-channel/`) - `index.ts` - Plugin entry point - `src/channel.ts` - Channel plugin definition with gateway and outbound handlers - `src/runtime.ts` - IMAP/SMTP implementation with state management - `src/types/` - TypeScript definitions for imap, mailparser, nodemailer - `openclaw.plugin.json` - Plugin manifest - `package.json` - Dependencies (imap, mailparser, nodemailer) ## Files Modified ### Plugin SDK - `src/channels/plugins/types.adapters.ts` - Add `channelRuntime` to `ChannelGatewayContext` - `src/gateway/server-channels.ts` - Pass `channelRuntime` to channel manager - `src/gateway/server.impl.ts` - Initialize and provide `channelRuntime` ## Testing The email channel has been tested locally with: - ✅ IMAP connection and email polling - ✅ Email processing and sender filtering - ✅ AI-powered reply generation - ✅ SMTP email sending - ✅ State persistence across restarts - ✅ Race condition handling ## Configuration Example ```json { "channels": { "email": { "accounts": { "default": { "imap": { "host": "imap.example.com", "port": 993, "secure": true, "user": "your-email@example.com", "password": "your-password" }, "smtp": { "host": "smtp.example.com", "port": 587, "secure": true, "user": "your-email@example.com", "password": "your-password" }, "checkInterval": 30, "allowedSenders": ["trusted@example.com"] } } } } } ``` ## Notes - This PR only modifies files directly related to the email channel feature - The `channelRuntime` addition is backward compatible (optional field) - All dependencies are standard npm packages with MIT licenses <!-- greptile_comment --> <h3>Greptile Summary</h3> This PR adds a functional email channel plugin with IMAP/SMTP support and extends the Plugin SDK to provide `channelRuntime` access for advanced channel plugins. **Key Changes:** - New email channel plugin (`extensions/email-channel/`) with IMAP polling, SMTP sending, state persistence, and sender filtering - Plugin SDK enhanced with optional `channelRuntime` field in `ChannelGatewayContext` for dispatch/routing utilities - Backward compatible SDK changes (optional field) **Issues Found:** - **Critical**: Module-level state in `runtime.ts` prevents multiple email accounts from running simultaneously, despite the plugin supporting multiple accounts via `listAccountIds` - **Critical**: Error retry logic removes failed emails from processed list, which could cause infinite retry loops if handler consistently fails - **Important**: Hard requirement for `channelRuntime` (throws error if undefined) contradicts the "backward compatible" claim in the PR description - **Moderate**: Duplicate processing window between marking message as processed and handler completion - **Minor**: Error notification sends email even when the error was in sending email itself **Recommendations:** - Refactor `runtime.ts` to use per-account state instead of module-level variables - Implement retry limits with exponential backoff instead of unconditional retries - Clarify backward compatibility stance or implement graceful degradation <h3>Confidence Score: 2/5</h3> - This PR has critical architectural issues that need resolution before merging - Score reflects critical bugs in the implementation: (1) module-level state prevents the advertised multi-account support from working correctly - only one email account can be active at a time, (2) error retry logic could cause infinite loops, and (3) there's a contradiction between claiming backward compatibility while throwing errors when `channelRuntime` is undefined. The Plugin SDK changes themselves are clean and backward compatible, but the email channel implementation has design flaws that would cause issues in production. - Pay close attention to `extensions/email-channel/src/runtime.ts` (module-level state architecture) and `extensions/email-channel/src/channel.ts` (error handling and backward compatibility) <sub>Last reviewed commit: 7c0eea3</sub> <!-- greptile_other_comments_section --> <!-- /greptile_comment -->

Most Similar PRs