# Email System
RUSTELO
This guide covers RUSTELO's comprehensive email system, including setup, configuration, usage, and best practices for integrating email functionality into your application. ## Overview The RUSTELO email system provides a complete solution for sending emails from your web application with support for multiple providers, template-based emails, form submissions, and both server-side and client-side integration. ### Architecture - **Email Service**: Core service that handles email sending - **Providers**: Pluggable email providers (SMTP, SendGrid, Console) - **Templates**: Handlebars-based email templates - **Forms**: Ready-to-use contact and support form components - **API**: REST endpoints for email operations ## Features ✨ **Multiple Providers** - SMTP (Gmail, Outlook, custom servers) - SendGrid API - Console output (development) 📧 **Template System** - Handlebars templates - HTML and text versions - Custom helpers - Variable substitution 🔧 **Form Integration** - Contact forms - Support forms with priorities - Custom form handling 🛡️ **Security** - Input validation - Rate limiting - CSRF protection - Secure configuration 🎨 **Rich Components** - React/Leptos form components - Real-time validation - Error handling - Success feedback ## Quick Start ### 1. Enable Email Feature Make sure the email feature is enabled in your `Cargo.toml`: ```toml [features] default = ["email"] email = ["lettre", "handlebars", "urlencoding"] ``` ### 2. Basic Configuration Add email configuration to your `config.toml`: ```toml [email] enabled = true provider = "console" # Start with console for development from_email = "noreply@yourapp.com" from_name = "Your App" template_dir = "templates/email" ``` ### 3. Create Template Directory ```bash mkdir -p templates/email/html mkdir -p templates/email/text ``` ### 4. Start Using ```rust // Send a simple email let result = email_service.send_simple_email( "user@example.com", "Welcome!", "Thank you for signing up!" ).await?; // Send a contact form let result = email_service.send_contact_form( "John Doe", "john@example.com", "Question about pricing", "I'd like to know more about your pricing plans.", "admin@yourapp.com" ).await?; ``` ## Configuration ### Email Configuration Options ```toml [email] # Basic settings enabled = true provider = "smtp" # "smtp", "sendgrid", "console" from_email = "noreply@yourapp.com" from_name = "Your App Name" template_dir = "templates/email" # SMTP settings (when provider = "smtp") smtp_host = "smtp.gmail.com" smtp_port = 587 smtp_username = "your-email@gmail.com" smtp_password = "@encrypted_smtp_password" smtp_use_tls = false smtp_use_starttls = true # SendGrid settings (when provider = "sendgrid") sendgrid_api_key = "@encrypted_sendgrid_api_key" sendgrid_endpoint = "https://api.sendgrid.com/v3/mail/send" ``` ### Environment-Specific Configuration ```toml # Development [environments.development] email.provider = "console" email.enabled = true # Production [environments.production] email.provider = "sendgrid" email.sendgrid_api_key = "@encrypted_sendgrid_api_key" email.enabled = true ``` ## Email Providers ### Console Provider Perfect for development and testing. Prints emails to the console. ```toml [email] provider = "console" ``` **Features:** - No external dependencies - Immediate feedback - Safe for development ### SMTP Provider Use any SMTP server including Gmail, Outlook, or custom servers. ```toml [email] provider = "smtp" smtp_host = "smtp.gmail.com" smtp_port = 587 smtp_username = "your-email@gmail.com" smtp_password = "@encrypted_smtp_password" smtp_use_starttls = true ``` **Common SMTP Configurations:** **Gmail:** ```toml smtp_host = "smtp.gmail.com" smtp_port = 587 smtp_use_starttls = true # Requires App Password (not regular password) ``` **Outlook:** ```toml smtp_host = "smtp-mail.outlook.com" smtp_port = 587 smtp_use_starttls = true ``` **Custom SMTP:** ```toml smtp_host = "mail.yourserver.com" smtp_port = 587 smtp_use_starttls = true ``` ### SendGrid Provider Use SendGrid's API for reliable email delivery. ```toml [email] provider = "sendgrid" sendgrid_api_key = "@encrypted_sendgrid_api_key" ``` **Features:** - High deliverability - Built-in analytics - Bounce handling - Reliable service ## Templates ### Template Structure ``` templates/email/ ├── html/ │ ├── contact.hbs │ ├── support.hbs │ ├── welcome.hbs │ └── notification.hbs └── text/ ├── contact.hbs ├── support.hbs ├── welcome.hbs └── notification.hbs ``` ### Template Naming - `contact.hbs` - Contact form emails - `support.hbs` - Support form emails - `welcome.hbs` - Welcome/registration emails - `notification.hbs` - General notifications ### Handlebars Helpers Built-in helpers for common email tasks: - `{{format_date}}` - Format dates - `{{format_currency}}` - Format money - `{{upper}}` - Uppercase text - `{{lower}}` - Lowercase text - `{{capitalize}}` - Capitalize words ### Example Template **templates/email/html/contact.hbs:** ```html Contact Form Submission

New Contact Form Submission

Name: {{name}}

Email: {{email}}

Subject: {{subject}}

Message:

{{message}}

``` **templates/email/text/contact.hbs:** ```text New Contact Form Submission Name: {{name}} Email: {{email}} Subject: {{subject}} Message: {{message}} Sent at {{format_date timestamp}} ``` ## API Endpoints ### GET /api/email/status Check email system status. **Response:** ```json { "enabled": true, "provider": "smtp", "configured": true, "templates": ["contact", "support", "welcome", "notification"] } ``` ### POST /api/email/contact Send a contact form email. **Request:** ```json { "name": "John Doe", "email": "john@example.com", "subject": "Question about pricing", "message": "I'd like to know more about your pricing plans.", "recipient": "admin@yourapp.com" } ``` **Response:** ```json { "message": "Email sent successfully", "message_id": "abc123def456", "status": "sent" } ``` ### POST /api/email/support Send a support form email with priority. **Request:** ```json { "name": "Jane Smith", "email": "jane@example.com", "subject": "Technical Issue", "message": "Having trouble with login functionality.", "priority": "high", "category": "technical", "recipient": "support@yourapp.com" } ``` ### POST /api/email/send Send a template-based email. **Request:** ```json { "to": "user@example.com", "subject": "Welcome to Our Platform", "template": "welcome", "template_data": { "user_name": "John Doe", "activation_link": "https://yourapp.com/activate/token123" } } ``` ### POST /api/email/notification Send a notification email. **Request:** ```json { "to": "user@example.com", "title": "Important Update", "message": "Your account has been updated successfully.", "content": "Additional details about the update..." } ``` ## Client Components ### ContactForm Component ```rust #[component] pub fn ContactForm() -> impl IntoView { let (form_data, set_form_data) = create_signal(ContactFormData::default()); let (is_submitting, set_is_submitting) = create_signal(false); let (message, set_message) = create_signal(String::new()); let submit_form = create_action(move |data: &ContactFormData| { let data = data.clone(); async move { set_is_submitting(true); let result = send_contact_form(data).await; set_is_submitting(false); match result { Ok(_) => set_message("Thank you for your message! We'll get back to you soon.".to_string()), Err(e) => set_message(format!("Error sending message: {}", e)), } } }); view! {

"Contact Us"

{move || message.get()}
} } ``` ### SupportForm Component ```rust #[component] pub fn SupportForm() -> impl IntoView { let (form_data, set_form_data) = create_signal(SupportFormData::default()); let (is_submitting, set_is_submitting) = create_signal(false); let (message, set_message) = create_signal(String::new()); let submit_form = create_action(move |data: &SupportFormData| { let data = data.clone(); async move { set_is_submitting(true); let result = send_support_form(data).await; set_is_submitting(false); match result { Ok(_) => set_message("Support ticket submitted successfully!".to_string()), Err(e) => set_message(format!("Error submitting ticket: {}", e)), } } }); view! {

"Support Request"

// Similar form fields with priority selector
} } ``` ## Server Usage ### Basic Email Sending ```rust use server::email::{EmailService, EmailConfig}; #[tokio::main] async fn main() -> Result<(), Box> { let config = EmailConfig::from_file("config.toml")?; let email_service = EmailService::new(config).await?; // Send simple email email_service.send_simple_email( "user@example.com", "Welcome!", "Thank you for signing up!" ).await?; Ok(()) } ``` ### Template-Based Emails ```rust use std::collections::HashMap; #[server(SendWelcomeEmail, "/api/email/welcome")] pub async fn send_welcome_email( email: String, name: String, activation_token: String, ) -> Result { let email_service = get_email_service().await?; let mut template_data = HashMap::new(); template_data.insert("user_name".to_string(), name); template_data.insert("activation_link".to_string(), format!("https://yourapp.com/activate/{}", activation_token)); email_service.send_template_email( &email, "Welcome to Our Platform", "welcome", template_data ).await?; Ok("Welcome email sent successfully".to_string()) } ``` ### Form Handling ```rust #[server(HandleContactForm, "/api/email/contact")] pub async fn handle_contact_form( name: String, email: String, subject: String, message: String, ) -> Result { let email_service = get_email_service().await?; // Validate input if name.is_empty() || email.is_empty() || message.is_empty() { return Err(ServerFnError::ServerError("All fields are required".to_string())); } // Send email email_service.send_contact_form( &name, &email, &subject, &message, "admin@yourapp.com" ).await?; Ok("Contact form submitted successfully".to_string()) } ``` ## Environment Variables ### Common Variables ```bash # SMTP Configuration SMTP_HOST=smtp.gmail.com SMTP_PORT=587 SMTP_USERNAME=your-email@gmail.com SMTP_PASSWORD=your-app-password SMTP_USE_STARTTLS=true # SendGrid Configuration SENDGRID_API_KEY=your-sendgrid-api-key # Email Settings EMAIL_FROM=noreply@yourapp.com EMAIL_FROM_NAME="Your App" ``` ### Using in Configuration ```toml [email] smtp_username = "${SMTP_USERNAME}" smtp_password = "@encrypted_smtp_password" sendgrid_api_key = "@encrypted_sendgrid_api_key" from_email = "${EMAIL_FROM}" ``` ## Security Considerations ### 1. Credential Management Always encrypt sensitive credentials: ```bash # Encrypt SMTP password cargo run --bin config_crypto_tool encrypt "your-smtp-password" # Encrypt SendGrid API key cargo run --bin config_crypto_tool encrypt "your-sendgrid-api-key" ``` ### 2. Input Validation Always validate email inputs: ```rust use validator::{Validate, ValidationError}; #[derive(Validate)] struct ContactFormData { #[validate(length(min = 1, message = "Name is required"))] name: String, #[validate(email(message = "Invalid email address"))] email: String, #[validate(length(min = 1, max = 1000, message = "Message must be between 1 and 1000 characters"))] message: String, } ``` ### 3. Rate Limiting Implement rate limiting for email endpoints: ```rust use tower_governor::{governor::GovernorLayer, GovernorConfigBuilder}; // Limit to 5 emails per minute per IP let governor_config = GovernorConfigBuilder::default() .per_minute(5) .burst_size(2) .finish() .unwrap(); let governor_layer = GovernorLayer { config: Arc::new(governor_config), }; ``` ### 4. CSRF Protection Enable CSRF protection for email forms: ```rust use axum_csrf::{CsrfConfig, CsrfLayer}; let csrf_config = CsrfConfig::default(); let csrf_layer = CsrfLayer::new(csrf_config); ``` ## Troubleshooting ### Common Issues **Email not sending:** - Check provider configuration - Verify credentials - Check network connectivity - Review email service logs **Template not found:** - Verify template directory path - Check template file naming - Ensure HTML and text versions exist **Authentication failed:** - For Gmail: Use App Password, not regular password - For other providers: Check username/password - Verify server and port settings **Rate limiting:** - Check provider limits - Implement proper rate limiting - Consider using queues for bulk emails ### Debug Mode Enable debug logging to troubleshoot issues: ```toml [logging] level = "debug" [email] enabled = true debug = true ``` ## Best Practices 1. **Use encrypted configuration** for sensitive credentials 2. **Implement proper validation** for all email inputs 3. **Use rate limiting** to prevent abuse 4. **Provide both HTML and text** versions of templates 5. **Test with console provider** during development 6. **Monitor email delivery** in production 7. **Handle errors gracefully** with user-friendly messages 8. **Use meaningful subject lines** and sender names ## Next Steps - [API Reference](../../api/email.md) - [Security Best Practices](../../security/best-practices.md) - [Configuration Guide](../../configuration/files.md) - [Deployment Guide](../../deployment/production.md) The email system provides a robust foundation for all your application's communication needs while maintaining security and reliability.