Files
bakery-ia/services/notification/EMAIL_SENDING_FIX.md
2026-01-26 10:25:47 +01:00

5.3 KiB

Email Sending Fix Summary

Problem Identified

The email service was failing with the error:

SMTP.send_message() got an unexpected keyword argument 'from_addr'

This occurred when trying to send emails through the notification service.

Root Cause

The issue was in the email_service.py file where aiosmtplib's send_message() method was being called with from_addr and to_addrs parameters:

# OLD CODE (incorrect)
await server.send_message(message, from_addr=from_email, to_addrs=[to_email])

However, the aiosmtplib library's send_message() method doesn't accept these parameters. The from_addr and to_addrs should be specified in the MIME message headers, not as parameters to send_message().

Solution Implemented

Fixed Email Sending Method

File: services/notification/app/services/email_service.py

# NEW CODE (correct)
# Note: aiosmtplib send_message doesn't use from_addr/to_addrs parameters
# The From/To headers are already set in the MIME message
await server.send_message(message)

How It Works

The email service already properly sets the From and To headers in the MIME message:

# From email_service.py - message construction
message = MIMEMultipart('alternative')
message['Subject'] = subject
message['To'] = to_email
message['From'] = formataddr((sender_name, sender_email))

The aiosmtplib.send_message() method reads these headers from the MIME message automatically, so we don't need to pass them as separate parameters.

Additional Improvements

1. Trusted Relay Support

Added SMTP_REQUIRE_AUTH configuration option to support Mailu and other trusted relay servers:

# In config.py
SMTP_REQUIRE_AUTH: bool = os.getenv("SMTP_REQUIRE_AUTH", "false").lower() == "true"

2. Updated Authentication Logic

# In email_service.py
if self.smtp_require_auth and self.smtp_user and self.smtp_password:
    await server.login(self.smtp_user, self.smtp_password)
elif not self.smtp_require_auth:
    logger.debug("Skipping SMTP authentication - trusted relay mode")

3. Enhanced Logging

Added informative logging to indicate when using trusted relay mode:

[info] Email service configured for trusted relay mode (no authentication)
[debug] Skipping SMTP authentication - trusted relay mode

Configuration Examples

For Mailu (Internal Communications)

export SMTP_HOST=mailu.bakery-ia.local
export SMTP_PORT=587
export SMTP_REQUIRE_AUTH=false  # No authentication needed
export DEFAULT_FROM_EMAIL=noreply@bakeryforecast.es

For External SMTP (SendGrid, Gmail, etc.)

export SMTP_HOST=smtp.sendgrid.net
export SMTP_PORT=587
export SMTP_USERNAME=apikey
export SMTP_PASSWORD=your_api_key
export SMTP_REQUIRE_AUTH=true  # Explicit authentication
export DEFAULT_FROM_EMAIL=noreply@yourdomain.com

Testing

Created comprehensive tests to verify:

  • Email message construction is correct
  • MIME headers are properly set
  • aiosmtplib compatibility
  • Both trusted relay and authenticated modes work
  • Configuration is valid for both scenarios

Files Modified

  1. services/notification/app/services/email_service.py - Fixed send_message call
  2. services/notification/app/core/config.py - Added SMTP_REQUIRE_AUTH
  3. services/notification/README.md - Updated documentation
  4. services/notification/test_email_sending.py - Added sending tests
  5. services/notification/test_email_config.py - Added config tests

Expected Behavior After Fix

Successful Email Sending

[info] Email service configured for trusted relay mode (no authentication)
[debug] Skipping SMTP authentication - trusted relay mode
[info] Email sent successfully to=contact@bakewise.ai subject='[Ventas] Test Subject'

Error Handling

If there are still issues, they will be properly logged with clear error messages:

[error] SMTP send failed error="connection refused"
[error] Failed to send email to=contact@bakewise.ai error="connection refused"

Troubleshooting

If Emails Still Don't Send

  1. Check SMTP Server Connectivity:

    telnet mailu.bakery-ia.local 587
    
  2. Verify Mailu Configuration:

    • Ensure RELAYNETS includes your Kubernetes subnet
    • Check Mailu logs: kubectl logs mailu-pod
  3. Test with Simple SMTP Client:

    import smtplib
    from email.mime.text import MIMEText
    
    msg = MIMEText('Test')
    msg['Subject'] = 'Test'
    msg['From'] = 'noreply@bakeryforecast.es'
    msg['To'] = 'test@bakeryforecast.es'
    
    with smtplib.SMTP('mailu.bakery-ia.local', 587) as server:
        server.send_message(msg)
    
  4. Check Notification Service Logs:

    kubectl logs notification-service-pod | grep "Email"
    

Summary

The email sending issue has been resolved by:

  1. Fixing the aiosmtplib usage - Removed incorrect from_addr and to_addrs parameters
  2. Adding trusted relay support - For Mailu and internal email servers
  3. Enhancing error handling - Better logging and debugging information
  4. Maintaining compatibility - Works with both internal and external SMTP servers

The notification service should now successfully send emails through Mailu without authentication for internal communications, and with proper authentication for external SMTP services.