|
|
||
|---|---|---|
| .. | ||
| README.md | ||
| __init__.py | ||
| oauth_email.py | ||
| oauth_http_client.py | ||
| smtp.py | ||
| smtp_connection.py | ||
README.md
Email Module
This module provides email functionality for Dify, including SMTP with OAuth 2.0 support for Microsoft Exchange/Outlook.
Features
- Basic SMTP authentication
- OAuth 2.0 authentication for Microsoft Exchange/Outlook
- Multiple email providers: SMTP, SendGrid, Resend
- TLS/SSL support
- Microsoft Exchange compliance (Basic Auth retirement September 2025)
Configuration
Basic SMTP Configuration
MAIL_TYPE=smtp
MAIL_DEFAULT_SEND_FROM=your-email@company.com
SMTP_SERVER=smtp.company.com
SMTP_PORT=587
SMTP_USERNAME=your-email@company.com
SMTP_PASSWORD=your-password
SMTP_USE_TLS=true
SMTP_OPPORTUNISTIC_TLS=true
SMTP_AUTH_TYPE=basic
Microsoft Exchange OAuth 2.0 Configuration
For Microsoft Exchange/Outlook compatibility:
MAIL_TYPE=smtp
MAIL_DEFAULT_SEND_FROM=your-email@company.com
SMTP_SERVER=smtp.office365.com
SMTP_PORT=587
SMTP_USERNAME=your-email@company.com
SMTP_USE_TLS=true
SMTP_OPPORTUNISTIC_TLS=true
SMTP_AUTH_TYPE=oauth2
# Microsoft OAuth 2.0 Settings
MICROSOFT_OAUTH2_CLIENT_ID=your-azure-app-client-id
MICROSOFT_OAUTH2_CLIENT_SECRET=your-azure-app-client-secret
MICROSOFT_OAUTH2_TENANT_ID=your-tenant-id
Microsoft Azure AD App Setup
1. Create Azure AD Application
- Go to Azure Portal → Azure Active Directory → App registrations
- Click "New registration"
- Enter application name (e.g., "Dify Email Service")
- Select "Accounts in this organizational directory only"
- Click "Register"
2. Configure API Permissions
- Go to "API permissions"
- Click "Add a permission" → Microsoft Graph
- Select "Application permissions"
- Add these permissions:
Mail.Send- Send mail as any userSMTP.Send- Send email via SMTP AUTH
- Click "Grant admin consent"
3. Create Client Secret
- Go to "Certificates & secrets"
- Click "New client secret"
- Enter description and expiration
- Copy the secret value (you won't see it again)
4. Get Configuration Values
- Client ID: Application (client) ID from Overview page
- Client Secret: The secret value you just created
- Tenant ID: Directory (tenant) ID from Overview page
Usage Examples
Basic Usage
The email service is automatically configured based on environment variables. Simply use the mail extension:
from extensions.ext_mail import mail
# Send email
mail_data = {
"to": "recipient@example.com",
"subject": "Test Email",
"html": "<h1>Hello World</h1>"
}
try:
mail._client.send(mail_data)
print("Email sent successfully")
except Exception as e:
print(f"Failed to send email: {e}")
OAuth Token Management
For service accounts using client credentials flow:
from libs.mail.oauth_email import MicrosoftEmailOAuth
# Initialize OAuth client
oauth_client = MicrosoftEmailOAuth(
client_id="your-client-id",
client_secret="your-client-secret",
redirect_uri="", # Not needed for client credentials
tenant_id="your-tenant-id"
)
# Get access token
try:
token_response = oauth_client.get_access_token_client_credentials()
access_token = token_response["access_token"]
print(f"Access token obtained: {access_token[:10]}...")
except Exception as e:
print(f"Failed to get OAuth token: {e}")
Custom SMTP Client
For direct SMTP usage with OAuth:
from libs.mail import SMTPClient
# Create SMTP client with OAuth
client = SMTPClient(
server="smtp.office365.com",
port=587,
username="your-email@company.com",
password="", # Not used with OAuth
from_addr="your-email@company.com",
use_tls=True,
opportunistic_tls=True,
oauth_access_token="your-access-token",
auth_type="oauth2"
)
# Send email
mail_data = {
"to": "recipient@example.com",
"subject": "OAuth Test",
"html": "<p>Sent via OAuth 2.0</p>"
}
client.send(mail_data)
Migration from Basic Auth
Microsoft Exchange Migration
Microsoft is retiring Basic Authentication for Exchange Online in September 2025. Follow these steps to migrate:
-
Set up Azure AD Application (see setup instructions above)
-
Update configuration to use OAuth 2.0:
SMTP_AUTH_TYPE=oauth2 MICROSOFT_OAUTH2_CLIENT_ID=your-client-id MICROSOFT_OAUTH2_CLIENT_SECRET=your-client-secret MICROSOFT_OAUTH2_TENANT_ID=your-tenant-id -
Test the configuration before the migration deadline
-
Remove old password-based settings once OAuth is working
Backward Compatibility
The system maintains backward compatibility:
- Existing Basic Auth configurations continue to work
- OAuth settings are optional and only used when
SMTP_AUTH_TYPE=oauth2 - Gradual migration is supported
Troubleshooting
Common OAuth Issues
-
Token acquisition fails:
- Verify Client ID and Secret are correct
- Check that admin consent was granted for API permissions
- Ensure Tenant ID is correct
-
SMTP authentication fails:
- Verify the access token is valid and not expired
- Check that SMTP.Send permission is granted
- Ensure the user has Send As permissions
-
Configuration issues:
- Verify all required environment variables are set
- Check SMTP server and port settings
- Ensure TLS settings match your server requirements
Testing Token Acquisition
from libs.mail.oauth_email import MicrosoftEmailOAuth
def test_oauth_token():
oauth_client = MicrosoftEmailOAuth(
client_id="your-client-id",
client_secret="your-client-secret",
redirect_uri="",
tenant_id="your-tenant-id"
)
try:
response = oauth_client.get_access_token_client_credentials()
print("✓ OAuth token acquired successfully")
print(f"Token type: {response.get('token_type')}")
print(f"Expires in: {response.get('expires_in')} seconds")
return True
except Exception as e:
print(f"✗ OAuth token acquisition failed: {e}")
return False
if __name__ == "__main__":
test_oauth_token()
Security Considerations
Token Management
- Access tokens are automatically obtained when needed
- Tokens are not stored permanently
- Client credentials flow is used for service accounts
- Secrets should be stored securely in environment variables
Network Security
- Always use TLS for SMTP connections (
SMTP_USE_TLS=true) - Use opportunistic TLS when supported (
SMTP_OPPORTUNISTIC_TLS=true) - Verify SMTP server certificates in production
Access Control
- Grant minimum required permissions in Azure AD
- Use dedicated service accounts for email sending
- Regularly rotate client secrets
- Monitor access logs for suspicious activity
Dependencies
The email module uses these internal components:
libs.mail.smtp: Core SMTP client with OAuth supportlibs.mail.oauth_email: Microsoft OAuth 2.0 implementationlibs.mail.oauth_http_client: HTTP client abstractionlibs.mail.smtp_connection: SMTP connection managementextensions.ext_mail: Flask extension for email integration
Testing
The module includes comprehensive tests with proper mocking:
tests/unit_tests/libs/mail/test_oauth_email.py: OAuth functionality teststests/unit_tests/libs/mail/test_smtp_enhanced.py: SMTP client tests
Run tests with:
uv run pytest tests/unit_tests/libs/mail/test_oauth_email.py -v
uv run pytest tests/unit_tests/libs/mail/test_smtp_enhanced.py -v