SMTP email sending implementation
Introduction#
Nodemailer send path: HTML plus stripped text, per-recipient delay, progress IPC, and the current no-attachments limit.
Project structure#
The email sending functionality is implemented across the Electron main process, preload bridge, React components, and handler modules. The key components include:
- Electron main process: IPC handlers for SMTP and Gmail, file dialogs, and progress tracking
- Preload bridge: Secure IPC exposure for renderer-side operations
- Handler modules: SMTP and Gmail email sending logic
- React components: UI for SMTP configuration, recipient import, email composition, and progress display
- Utilities: Pyodide integration for Python-based number parsing
graph TB subgraph "Electron Application" UI["React Components<br/>BulkMailer.jsx, SMTPForm.jsx"] Preload["Preload Bridge<br/>preload.js"] Main["Main Process<br/>main.js"] SMTPHandler["SMTP Handler<br/>smtp-handler.js"] GmailHandler["Gmail Handler<br/>gmail-handler.js"] end UI --> Preload Preload --> Main Main --> SMTPHandler Main --> GmailHandler Main --> |"File Dialogs"| UI
Core components#
This section outlines the primary components involved in SMTP email sending and bulk messaging:
- SMTP Handler: Implements SMTP transport creation, connection verification, email composition with HTML and plain text fallback, progress reporting, rate limiting, and error handling
- Gmail Handler: Manages OAuth2 authentication, token storage, and email sending via Gmail API
- Main Process: Exposes IPC handlers for SMTP and Gmail operations, manages file dialogs for email list import, and coordinates progress events
- Preload Bridge: Provides secure IPC methods to the renderer process for authentication, sending, file operations, and progress listeners
- React Components: Provide UI for SMTP configuration, recipient import, email composition, delay configuration, and real-time progress display
- Pyodide Utilities: Enable Python-based number parsing for contact management
Key implementation highlights:
- HTML email support with automatic plain text fallback generation
- Configurable delays between messages for rate limiting and deliverability
- Real-time progress updates via IPC events
- Error handling for individual message failures with partial delivery reporting
- Email validation for recipient formatting
- Attachment handling limitations and suggested workarounds
Architecture overview#
Send path layers:
sequenceDiagram
participant UI as "React UI<br/>SMTPForm.jsx"
participant Preload as "Preload Bridge<br/>preload.js"
participant Main as "Main Process<br/>main.js"
participant SMTP as "SMTP Handler<br/>smtp-handler.js"
participant Transport as "Nodemailer Transport"
participant Provider as "SMTP Provider"
UI->>Preload : sendSMTPEmail(smtpData)
Preload->>Main : ipcRenderer.invoke('smtp-send', smtpData)
Main->>SMTP : handleSMTPSend(event, smtpData)
SMTP->>SMTP : Validate SMTP config
SMTP->>Transport : createTransport(config)
Transport->>Provider : connect & verify
loop For each recipient
SMTP->>UI : email-progress (sending)
SMTP->>Transport : sendMail(options)
Transport->>Provider : deliver email
Provider-->>Transport : delivery result
Transport-->>SMTP : delivery status
SMTP->>UI : email-progress (sent/failed)
end
SMTP-->>Main : {success, results}
Main-->>Preload : result
Preload-->>UI : resultDetailed component analysis#
SMTP handler implementation#
The SMTP handler module encapsulates the complete email sending workflow:
flowchart TD
Start([Function Entry]) --> ValidateConfig["Validate SMTP Configuration"]
ValidateConfig --> ConfigValid{"Configuration Valid?"}
ConfigValid --> |No| ReturnError["Return Error Response"]
ConfigValid --> |Yes| CreateTransporter["Create Nodemailer Transport"]
CreateTransporter --> VerifyConnection["Verify Transport Connection"]
VerifyConnection --> VerifySuccess{"Connection Verified?"}
VerifySuccess --> |No| ReturnError
VerifySuccess --> |Yes| InitResults["Initialize Results Array"]
InitResults --> LoopRecipients["Loop Through Recipients"]
LoopRecipients --> ProgressSending["Send Progress: sending"]
ProgressSending --> ComposeEmail["Compose Email Options<br/>HTML + Plain Text Fallback"]
ComposeEmail --> SendMail["transporter.sendMail()"]
SendMail --> SendSuccess{"Send Success?"}
SendSuccess --> |Yes| RecordSuccess["Record Success"]
SendSuccess --> |No| RecordFailure["Record Failure + Error"]
RecordSuccess --> ProgressSent["Send Progress: sent"]
RecordFailure --> ProgressFailed["Send Progress: failed"]
ProgressSent --> DelayCheck{"More Recipients?"}
ProgressFailed --> DelayCheck
DelayCheck --> |Yes| Delay["Apply Configurable Delay"]
DelayCheck --> |No| Complete["Complete All Recipients"]
Delay --> LoopRecipients
Complete --> ReturnResults["Return Success + Results"]
ReturnError --> End([Function Exit])
ReturnResults --> EndKey implementation characteristics:
- SMTP configuration validation with host, port, user, and password checks
- Transport creation with SSL/TLS support and self-signed certificate handling
- Connection verification before sending
- Email composition with HTML content and automatic plain text fallback generation
- Real-time progress reporting for each recipient
- Configurable delay between messages for rate limiting
- Detailed error handling with individual failure recording
Email composition and content generation#
The email composition system supports rich HTML content with automatic plain text fallback:
- HTML content support: The message body is passed directly as HTML content
- Plain text fallback generation: Plain text version is created by stripping HTML tags from the message content
- Content-Type specification: Uses text/html MIME type for HTML emails
- Character encoding: UTF-8 character encoding for international content support
Implementation considerations:
- HTML emails should use proper HTML structure with DOCTYPE declarations for best rendering
- Plain text fallback exists for clients that ignore HTML
- Content length validation should be considered for large HTML documents
Attachment handling limitations and workarounds#
Current implementation limitations:
- No native attachment support in the SMTP handler
- Email composition is limited to subject, HTML body, and plain text fallback
Recommended workarounds:
- Use inline images with proper base64 encoding within HTML content
- For external files, consider converting to embedded content or linking to hosted resources
- For large attachments, consider alternative delivery methods such as cloud storage links
- Implement pre-processing to convert file content to appropriate HTML representation
Bulk sending implementation with rate limiting#
The bulk sending implementation includes several mechanisms for controlled delivery:
sequenceDiagram
participant UI as "UI Layer"
participant Handler as "SMTP Handler"
participant Transport as "Nodemailer"
participant Provider as "SMTP Provider"
UI->>Handler : sendSMTPEmail({recipients, delay})
loop For each recipient
Handler->>Handler : Progress : sending
Handler->>Transport : sendMail()
Transport->>Provider : deliver
Provider-->>Transport : result
alt Success
Handler->>Handler : Record success
Handler->>Handler : Progress : sent
else Failure
Handler->>Handler : Record failure + error
Handler->>Handler : Progress : failed
end
Handler->>Handler : Apply delay (if not last recipient)
end
Handler-->>UI : Results summaryRate limiting and throttling mechanisms:
- Configurable delay between messages (default 1000ms)
- Conditional delay application (no delay after the last message)
- Progress tracking for each recipient with real-time updates
- Individual error handling with partial delivery reporting
Progress tracking and real-time status updates#
The system tracks progress through IPC events:
stateDiagram-v2 [*] --> Idle Idle --> Sending : "Progress Event" Sending --> Sent : "Success" Sending --> Failed : "Error" Sent --> Delay : "Next Message" Failed --> Delay : "Next Message" Delay --> Sending : "More Recipients?" Delay --> Completed : "No More Recipients" Completed --> [*]
Progress event structure:
- Current position in batch
- Total recipient count
- Recipient email address
- Status: sending, sent, or failed
- Error details when applicable
Error handling and partial delivery scenarios#
The implementation handles errors at multiple levels:
Individual message failure handling:
- Each recipient is processed independently
- Failures are recorded with specific error messages
- Partial delivery scenarios are supported with mixed success/failure results
- Progress updates reflect individual recipient outcomes
System-level error handling:
- SMTP configuration validation errors
- Transport connection verification failures
- Network connectivity issues
- Authentication failures
Email validation and recipient formatting#
Recipient validation occurs in the UI layer:
Validation rules:
- Non-empty recipient list
- Valid email format using regex pattern
- Subject and message content validation
- Trimmed whitespace handling
Recipient formatting:
- Line-by-line input with newline separation
- Automatic trimming of whitespace
- Filtering of empty entries
- Support for comma-separated values in CSV files
UI components for SMTP configuration#
The SMTP form is the UI for email composition:
Key UI elements:
- SMTP server configuration fields (host, port, username, password)
- Secure connection toggle
- Recipient import functionality
- Email composition area with character counting
- Delay configuration slider
- Real-time activity log with color-coded status indicators
Progress visualization:
- Color-coded status indicators (green for sent, red for failed)
- Timestamped entries
- Scrollable activity log
- Real-time updates during sending
Dependency analysis#
The email sending implementation relies on several key dependencies and external integrations:
graph TB subgraph "Application Dependencies" Nodemailer["Nodemailer"] ElectronStore["Electron Store"] GoogleApis["Google APIs"] QRCode["QRCode Library"] end subgraph "Core Modules" SMTPHandler["smtp-handler.js"] GmailHandler["gmail-handler.js"] MainProcess["main.js"] Preload["preload.js"] end SMTPHandler --> Nodemailer SMTPHandler --> ElectronStore GmailHandler --> GoogleApis MainProcess --> SMTPHandler MainProcess --> GmailHandler Preload --> MainProcess
External service integrations:
- SMTP providers for email delivery
- Google APIs for Gmail authentication and sending
- QR code generation for WhatsApp authentication
- File system access for contact import
Performance considerations#
Several factors impact the performance and reliability of bulk email sending:
Processing efficiency:
- HTML to plain text conversion is performed synchronously for each message
- Connection verification occurs once per session
- Delay mechanism prevents overwhelming provider servers
Memory management:
- Results arrays grow linearly with recipient count
- Progress events are emitted for each recipient
- Large recipient lists may impact UI responsiveness
Network optimization:
- Single transport connection reused for all messages
- Configurable delays reduce network pressure
- Connection verification prevents unnecessary retries
Scalability recommendations:
- Consider batching recipients for very large lists
- Monitor provider rate limits and adjust delays accordingly
- Implement backoff strategies for persistent failures
- Use connection pooling for high-volume scenarios
Troubleshooting guide#
Common SMTP issues#
Connection and authentication problems:
- Verify SMTP host, port, and security settings match provider requirements
- Check firewall and network connectivity
- Ensure proper SSL/TLS configuration for secure connections
- Validate username/password credentials
Delivery failures:
- Review individual recipient error messages in the activity log
- Check provider-specific error codes and rate limit notifications
- Verify recipient email addresses are properly formatted
- Monitor progress events for failed recipients
Provider-Specific restrictions#
Gmail SMTP considerations:
- Use app-specific passwords instead of regular account passwords
- Enable “Less secure app access” or configure OAuth2 authentication
- Monitor daily sending quotas and adjust batch sizes accordingly
Outlook/Hotmail SMTP:
- Verify SMTP settings: host, port, and security requirements
- Check for IP reputation issues if sending from shared hosting
- Implement proper DKIM/SPF/DNS configurations for improved deliverability
Deliverability and spam prevention#
Habits that help:
- Implement proper sender reputation management
- Use consistent sender identity across messages
- Include unsubscribe links and proper headers
- Monitor bounce rates and engagement metrics
- Respect provider rate limits and implement appropriate delays
UI and configuration issues#
Recipient import problems:
- Ensure CSV files have proper column headers or use first column as email
- Verify file encoding is UTF-8
- Check that email addresses contain “@” symbol and proper format
Progress tracking issues:
- Verify IPC event listeners are properly attached
- Check that progress events are being emitted from the main process
- Ensure UI components are subscribed to progress updates
Conclusion#
No attachment pipeline yet. If you need files, say so in the body or extend nodemailer usage deliberately.
Appendices#
Configuration reference#
SMTP server settings:
- Host: SMTP server hostname or IP address
- Port: Standard ports (587 for TLS, 465 for SSL)
- Username: Email address or username for authentication
- Password: App password or authentication token
- Secure: Enable SSL/TLS encryption
Email template examples#
HTML email structure recommendations:
- Use semantic HTML tags for proper rendering
- Include proper DOCTYPE declaration
- Implement responsive design for mobile devices
- Use inline styles for better compatibility
- Provide plain text alternatives for accessibility
Content formatting guidelines:
- Keep subject lines concise and compelling
- Use clear, scannable content structure
- Include proper spacing and formatting
- Test across different email clients and devices
Security considerations#
Credential storage:
- Passwords are not saved to prevent security risks
- Use encrypted storage for sensitive configuration data
- Implement proper access controls and permissions
Network security:
- Enable SSL/TLS for all SMTP connections
- Validate server certificates appropriately
- Monitor for man-in-the-middle attacks
- Use secure authentication methods