Skip to main content
Version: 1.0.1

Email Worker

The Email Worker is a production-ready worker that sends emails via SMTP. It supports multiple SMTP configurations, HTML and plain text emails, attachments, CC/BCC, and all standard email features.

Features​

  • Multiple SMTP configurations (Default, Marketing, Transactional, etc.)
  • HTML and plain text email body
  • File attachments (regular and inline for HTML)
  • CC and BCC recipients
  • Custom email headers
  • Email priority levels (High, Normal, Low)
  • Read and delivery receipts
  • Reply-To address
  • Automatic retry for transient errors
  • Permanent failure detection (no retry for invalid recipients)

Use Cases​

ScenarioExample
Transactional EmailsOrder confirmations, password resets
NotificationsAlert emails, status updates
Marketing CampaignsScheduled newsletter sends
ReportsDaily/weekly report delivery with attachments
System AlertsError notifications, monitoring alerts
Welcome EmailsNew user onboarding sequences

Security Model​

Like the SQL Worker, SMTP credentials are stored securely in the worker configuration, not in job data.

Worker (appsettings.json)

EmailConfig
└─ SmtpConfigs
└─ Default
├─ Host: smtp.gmail.com
├─ Username: ********
└─ Password: ********

(secrets stay here)

Only the configuration name (alias) is referenced in job data:

{
"configName": "Default",
"to": ["[email protected]"],
"subject": "Welcome!",
"body": "<h1>Hello!</h1>"
}

This design ensures that sensitive credentials never leave the worker environment.

Worker Configuration​

Configure SMTP servers in the worker's appsettings.json:

{
"EmailConfig": {
"DefaultConfigName": "Default",
"SmtpConfigs": {
"Default": {
"Host": "smtp.gmail.com",
"Port": 587,
"Username": "[email protected]",
"Password": "your-app-password",
"UseSsl": true,
"DefaultFromEmail": "[email protected]",
"DefaultFromName": "Your Company",
"TimeoutSeconds": 30,
"IgnoreCertificateErrors": false
},
"Marketing": {
"Host": "smtp.sendgrid.net",
"Port": 587,
"Username": "apikey",
"Password": "your-sendgrid-api-key",
"UseSsl": true,
"DefaultFromEmail": "[email protected]",
"DefaultFromName": "Your Company Marketing",
"TimeoutSeconds": 30
},
"Transactional": {
"Host": "smtp.mailgun.org",
"Port": 587,
"Username": "[email protected]",
"Password": "your-mailgun-password",
"UseSsl": true,
"DefaultFromEmail": "[email protected]",
"DefaultFromName": "Your Company"
}
}
}
}

SMTP Configuration Properties​

PropertyTypeRequiredDefaultDescription
Hoststring✓-SMTP server hostname
Portnumber-587SMTP port (25, 465, or 587)
Usernamestring--SMTP authentication username
Passwordstring--SMTP authentication password
UseSslboolean-trueEnable SSL/TLS encryption
DefaultFromEmailstring✓-Default sender email address
DefaultFromNamestring--Default sender display name
TimeoutSecondsnumber-30Connection timeout
IgnoreCertificateErrorsboolean-falseSkip SSL certificate validation

Job Data Schema​

When creating an email job, provide the email details through Job Data JSON:

{
"configName": "Default",
"to": ["[email protected]"],
"cc": ["[email protected]"],
"bcc": ["[email protected]"],
"subject": "Monthly Report - January 2024",
"body": "<h1>Monthly Report</h1><p>Please find attached...</p>",
"isHtml": true,
"fromEmail": "[email protected]",
"fromName": "Reports System",
"replyTo": "[email protected]",
"priority": "High",
"attachments": [
{
"fileName": "report.pdf",
"contentBase64": "JVBERi0xLjQK...",
"contentType": "application/pdf"
}
],
"requestReadReceipt": false,
"requestDeliveryReceipt": true
}

Configuration Reference​

Main Properties​

PropertyTypeRequiredDefaultDescription
configNamestring-Default configSMTP configuration alias
toarray✓-Recipient email addresses
ccarray--CC recipients
bccarray--BCC recipients (hidden)
subjectstring✓-Email subject line
bodystring✓-Email body content
isHtmlboolean-falseWhether body is HTML
fromEmailstring-From configOverride sender email
fromNamestring-From configOverride sender name
replyTostring--Reply-To address
priorityenum-NormalPriority: Low, Normal, High
attachmentsarray--File attachments
customHeadersobject--Custom email headers
requestReadReceiptboolean-falseRequest read receipt
requestDeliveryReceiptboolean-falseRequest delivery receipt

Attachment Properties​

PropertyTypeRequiredDescription
fileNamestring✓File name with extension
contentBase64string✓Base64-encoded file content
contentTypestring-MIME type (auto-detected if omitted)
isInlineboolean-Inline attachment for HTML
contentIdstring-Content ID for inline (use as cid:value)

Deployment​

docker run -d --name milvaion-email-worker --network milvaion_milvaion-network milvasoft/milvaion-email-worker:latest

Docker Compose​

services:
email-worker:
image: milvasoft/milvaion-email-worker:latest
environment:
- Worker__WorkerId=email-worker-01
- Worker__RabbitMQ__Host=rabbitmq
- Worker__Redis__ConnectionString=redis:6379
- EmailConfig__DefaultConfigName=Default
- EmailConfig__SmtpConfigs__Default__Host=smtp.gmail.com
- EmailConfig__SmtpConfigs__Default__Port=587
- EmailConfig__SmtpConfigs__Default__Username=${SMTP_USERNAME}
- EmailConfig__SmtpConfigs__Default__Password=${SMTP_PASSWORD}
- EmailConfig__SmtpConfigs__Default__UseSsl=true
- EmailConfig__SmtpConfigs__Default__DefaultFromEmail=noreply@yourcompany.com
- EmailConfig__SmtpConfigs__Default__DefaultFromName=Your Company
depends_on:
- rabbitmq
- redis
restart: unless-stopped

Environment Variables​

All SMTP configurations can be overridden via environment variables:

# Default SMTP Configuration
EmailConfig__SmtpConfigs__Default__Host=smtp.gmail.com
EmailConfig__SmtpConfigs__Default__Port=587
EmailConfig__SmtpConfigs__Default__Username=[email protected]
EmailConfig__SmtpConfigs__Default__Password=your-app-password
EmailConfig__SmtpConfigs__Default__UseSsl=true
EmailConfig__SmtpConfigs__Default__DefaultFromEmail=[email protected]
EmailConfig__SmtpConfigs__Default__DefaultFromName=Your Company

# Marketing SMTP Configuration
EmailConfig__SmtpConfigs__Marketing__Host=smtp.sendgrid.net
EmailConfig__SmtpConfigs__Marketing__Port=587
EmailConfig__SmtpConfigs__Marketing__Username=apikey
EmailConfig__SmtpConfigs__Marketing__Password=your-sendgrid-api-key

# Timeout and SSL Settings
EmailConfig__SmtpConfigs__Default__TimeoutSeconds=30
EmailConfig__SmtpConfigs__Default__IgnoreCertificateErrors=false

Kubernetes​

apiVersion: apps/v1
kind: Deployment
metadata:
name: email-worker
spec:
replicas: 2
selector:
matchLabels:
app: email-worker
template:
metadata:
labels:
app: email-worker
spec:
containers:
- name: email-worker
image: milvasoft/milvaion-email-worker:latest
env:
- name: Worker__WorkerId
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: Worker__RabbitMQ__Host
value: rabbitmq-service
- name: Worker__Redis__ConnectionString
value: redis-service:6379
- name: EmailConfig__SmtpConfigs__Default__Password
valueFrom:
secretKeyRef:
name: email-secrets
key: smtp-password
envFrom:
- configMapRef:
name: email-worker-config
---
apiVersion: v1
kind: Secret
metadata:
name: email-secrets
type: Opaque
stringData:
smtp-password: your-smtp-password
---
apiVersion: v1
kind: ConfigMap
metadata:
name: email-worker-config
data:
EmailConfig__SmtpConfigs__Default__Host: smtp.gmail.com
EmailConfig__SmtpConfigs__Default__Port: "587"
EmailConfig__SmtpConfigs__Default__Username: your-[email protected]
EmailConfig__SmtpConfigs__Default__UseSsl: "true"
EmailConfig__SmtpConfigs__Default__DefaultFromEmail: [email protected]
EmailConfig__SmtpConfigs__Default__DefaultFromName: Your Company

Scaling Considerations​

FactorRecommendation
Replicas2-4 workers for high-volume email sending
Rate LimitingRespect SMTP provider limits (Gmail: 500/day, SendGrid: varies)
Retry StrategyBuilt-in retry handles transient failures automatically
Memory~256MB per worker (more if handling large attachments)

For custom workers, see Your First Worker and Implementing Jobs.