Mail Executor
The mail executor enables you to send emails from your workflows, perfect for notifications, alerts, and report distribution.
Overview
The mail executor allows you to:
- Send email notifications on workflow events
- Attach files and logs to emails
- Use templates with variable substitution
- Configure SMTP settings globally or per-step
- Send to multiple recipients
- Support HTML and plain text formats
Basic Usage
Simple Email
yaml
smtp:
host: "smtp.gmail.com"
port: "587"
username: "[email protected]"
password: "your-app-password"
steps:
- name: send-notification
executor:
type: mail
config:
to: [email protected]
from: [email protected]
subject: "Workflow Completed"
message: "The data processing workflow has completed successfully."
With Multiple Recipients
yaml
steps:
- name: notify-team
executor:
type: mail
config:
to: "[email protected], [email protected], [email protected]"
from: [email protected]
subject: "Daily Report Ready"
message: "The daily report has been generated and is ready for review."
SMTP Configuration
Global SMTP Settings
Configure SMTP settings at the DAG level:
yaml
smtp:
host: "smtp.office365.com"
port: "587"
username: "${SMTP_USER}"
password: "${SMTP_PASS}"
steps:
- name: send-alert
executor:
type: mail
config:
to: [email protected]
from: [email protected]
subject: "Alert: Process Failed"
message: "The data import process has failed. Please investigate."
Common SMTP Configurations
Gmail
yaml
smtp:
host: "smtp.gmail.com"
port: "587"
username: "[email protected]"
password: "your-app-specific-password" # Use app password, not regular password
Office 365 / Outlook
yaml
smtp:
host: "smtp.office365.com"
port: "587"
username: "[email protected]"
password: "${SMTP_PASSWORD}"
SendGrid
yaml
smtp:
host: "smtp.sendgrid.net"
port: "587"
username: "apikey" # Literal string "apikey"
password: "${SENDGRID_API_KEY}"
AWS SES
yaml
smtp:
host: "email-smtp.us-east-1.amazonaws.com"
port: "587"
username: "${AWS_SES_SMTP_USER}"
password: "${AWS_SES_SMTP_PASSWORD}"
Email Templates
Using Variables in Emails
yaml
params:
- ENVIRONMENT: production
- DATE: "`date +%Y-%m-%d`"
steps:
- name: deployment-notification
executor:
type: mail
config:
to: [email protected]
from: [email protected]
subject: "Deployment to ${ENVIRONMENT} - ${DATE}"
message: |
Deployment Details:
Environment: ${ENVIRONMENT}
Date: ${DATE}
Version: ${VERSION}
Deployed by: Dagu Automation
All services have been successfully deployed and are running.
Dynamic Recipients
yaml
params:
- RECIPIENT_NAME: "John Doe"
- RECIPIENT_EMAIL: "[email protected]"
steps:
- name: personalized-email
executor:
type: mail
config:
to: ${RECIPIENT_EMAIL}
from: [email protected]
subject: "Hello ${RECIPIENT_NAME}"
message: |
Dear ${RECIPIENT_NAME},
This is a personalized notification just for you.
Best regards,
The Automation Team
Real-World Examples
Workflow Status Notifications
yaml
name: data-pipeline
smtp:
host: "smtp.gmail.com"
port: "587"
username: "${SMTP_USER}"
password: "${SMTP_PASS}"
handlerOn:
success:
executor:
type: mail
config:
to: [email protected]
from: [email protected]
subject: "✅ Data Pipeline Success - ${DAG_NAME}"
message: |
The data pipeline has completed successfully.
Workflow: ${DAG_NAME}
Run ID: ${DAG_RUN_ID}
Completion Time: `date`
View logs at: ${DAG_RUN_LOG_FILE}
failure:
executor:
type: mail
config:
to: "[email protected], [email protected]"
from: [email protected]
subject: "❌ Data Pipeline Failed - ${DAG_NAME}"
message: |
The data pipeline has failed and requires attention.
Workflow: ${DAG_NAME}
Run ID: ${DAG_RUN_ID}
Failure Time: `date`
Please check the logs at: ${DAG_RUN_LOG_FILE}
steps:
- name: process-data
command: python process_data.py
Report Distribution
yaml
name: weekly-report
schedule: "0 9 * * MON" # Every Monday at 9 AM
smtp:
host: "smtp.office365.com"
port: "587"
username: "${SMTP_USER}"
password: "${SMTP_PASS}"
steps:
- name: generate-report
command: |
cd /opt/reports
python generate_weekly_report.py
ls -la weekly_report_*.pdf
output: REPORT_FILE
- name: send-to-management
executor:
type: mail
config:
to: "[email protected], [email protected], [email protected]"
from: [email protected]
subject: "Weekly Business Report - `date +%Y-%m-%d`"
message: |
Dear Leadership Team,
Please find attached the weekly business report for the week ending `date +%Y-%m-%d`.
Report Highlights:
- Revenue metrics
- Customer acquisition
- System performance
- Team productivity
The full report is attached as a PDF.
Best regards,
Business Intelligence Team
attachments:
- ${REPORT_FILE}
depends: generate-report
Error Alert with Context
yaml
name: critical-process
errorMail:
from: [email protected]
to: [email protected]
prefix: "[CRITICAL]"
attachLogs: true
steps:
- name: validate-input
command: |
if [ ! -f /data/input.csv ]; then
echo "ERROR: Input file missing"
exit 1
fi
if [ $(wc -l < /data/input.csv) -lt 100 ]; then
echo "ERROR: Input file has insufficient data"
exit 1
fi
- name: process-critical-data
command: python critical_process.py
mailOnError: true
depends: validate-input
- name: verify-output
command: |
if [ ! -f /data/output.csv ]; then
echo "ERROR: Output file not generated"
exit 1
fi
mailOnError: true
depends: process-critical-data
Customer Notifications
yaml
name: order-confirmation
params:
- ORDER_ID: "12345"
- CUSTOMER_EMAIL: "[email protected]"
- CUSTOMER_NAME: "Jane Smith"
steps:
- name: get-order-details
command: |
curl -s https://api.company.com/orders/${ORDER_ID} | \
jq -r '.total_amount'
output: ORDER_TOTAL
- name: send-confirmation
executor:
type: mail
config:
to: ${CUSTOMER_EMAIL}
from: [email protected]
subject: "Order Confirmation #${ORDER_ID}"
message: |
Dear ${CUSTOMER_NAME},
Thank you for your order!
Order Details:
- Order Number: ${ORDER_ID}
- Total Amount: $${ORDER_TOTAL}
- Order Date: `date +"%B %d, %Y"`
Your order is being processed and you will receive a shipping
notification once it has been dispatched.
If you have any questions, please don't hesitate to contact
our customer service team.
Best regards,
The Sales Team
depends: get-order-details
Advanced Features
Conditional Email Sending
yaml
steps:
- name: check-threshold
command: |
USAGE=$(df -h /data | awk 'NR==2 {print $5}' | sed 's/%//')
echo $USAGE
output: DISK_USAGE
- name: send-alert-if-high
executor:
type: mail
config:
to: [email protected]
from: [email protected]
subject: "⚠️ High Disk Usage Alert"
message: |
Warning: Disk usage on /data has reached ${DISK_USAGE}%
Server: ${HOSTNAME}
Threshold: 80%
Current Usage: ${DISK_USAGE}%
Please take action to free up disk space.
preconditions:
- condition: "test ${DISK_USAGE} -gt 80"
depends: check-threshold
Email with Multiple Attachments
yaml
steps:
- name: prepare-files
command: |
# Generate multiple reports
python generate_sales_report.py > /tmp/sales.csv
python generate_inventory_report.py > /tmp/inventory.csv
python generate_metrics_report.py > /tmp/metrics.csv
# Create summary
echo "Report generated on $(date)" > /tmp/summary.txt
- name: send-reports
executor:
type: mail
config:
to: [email protected]
from: [email protected]
subject: "Monthly Reports Package"
message: |
Please find attached the monthly reports:
1. Sales Report (sales.csv)
2. Inventory Report (inventory.csv)
3. Metrics Report (metrics.csv)
4. Summary (summary.txt)
attachments:
- /tmp/sales.csv
- /tmp/inventory.csv
- /tmp/metrics.csv
- /tmp/summary.txt
depends: prepare-files
Dynamic Email Content
yaml
steps:
- name: gather-metrics
command: |
cat <<EOF
{
"total_orders": 1523,
"revenue": 125430.50,
"new_customers": 89,
"avg_order_value": 82.30
}
EOF
output: METRICS
- name: send-daily-summary
command: |
# Parse metrics
ORDERS=$(echo "${METRICS}" | jq -r '.total_orders')
REVENUE=$(echo "${METRICS}" | jq -r '.revenue')
CUSTOMERS=$(echo "${METRICS}" | jq -r '.new_customers')
AOV=$(echo "${METRICS}" | jq -r '.avg_order_value')
# Generate email body
cat <<EOF > /tmp/email_body.txt
Daily Business Summary - $(date +"%B %d, %Y")
📊 Today's Performance:
Orders: ${ORDERS}
Revenue: \$${REVENUE}
New Customers: ${CUSTOMERS}
Average Order Value: \$${AOV}
${ORDERS:+✅} Orders are ${ORDERS:-❌ No orders received}
${REVENUE:+✅} Revenue target achieved
View full dashboard at: https://dashboard.company.com
EOF
cat /tmp/email_body.txt
output: EMAIL_BODY
depends: gather-metrics
- name: send-summary
executor:
type: mail
config:
to: [email protected]
from: [email protected]
subject: "📈 Daily Summary - Strong Performance"
message: ${EMAIL_BODY}
depends: send-daily-summary
Error Handling
Handling Mail Failures
yaml
steps:
- name: primary-notification
executor:
type: mail
config:
to: [email protected]
from: [email protected]
subject: "Important Update"
message: "This is a critical notification."
continueOn:
failure: true
output: MAIL_RESULT
- name: fallback-notification
command: |
# Use alternative notification method
curl -X POST https://hooks.slack.com/services/YOUR/WEBHOOK \
-H 'Content-type: application/json' \
-d '{"text":"Failed to send email - Important Update"}'
preconditions:
- condition: "${MAIL_RESULT}"
expected: ""
depends: primary-notification
Retry Email Sending
yaml
steps:
- name: send-with-retry
executor:
type: mail
config:
to: [email protected]
from: [email protected]
subject: "Critical System Alert"
message: "System requires immediate attention."
retryPolicy:
limit: 3
intervalSec: 60 # Wait 1 minute between retries
Integration Examples
With Monitoring Systems
yaml
steps:
- name: check-service-health
command: |
STATUS=$(curl -s -o /dev/null -w "%{http_code}" http://api.company.com/health)
echo $STATUS
output: HTTP_STATUS
- name: alert-if-down
executor:
type: mail
config:
to: "[email protected], [email protected]"
from: [email protected]
subject: "🚨 URGENT: API Service Down"
message: |
The API service is not responding.
Status Code: ${HTTP_STATUS}
Checked at: `date`
Endpoint: http://api.company.com/health
Please investigate immediately.
preconditions:
- condition: "test ${HTTP_STATUS} -ne 200"
depends: check-service-health
With CI/CD Pipelines
yaml
name: build-notification
steps:
- name: run-tests
command: |
cd /project
npm test
echo $? > /tmp/test_result.txt
- name: notify-build-status
executor:
type: mail
config:
to: [email protected]
from: [email protected]
subject: "Build ${BUILD_NUMBER} - ${BUILD_STATUS}"
message: |
Build Details:
Build Number: ${BUILD_NUMBER}
Branch: ${GIT_BRANCH}
Commit: ${GIT_COMMIT}
Author: ${GIT_AUTHOR}
Test Results: ${TEST_RESULT}
View full build log at: ${BUILD_URL}
See Also
- Learn about JQ Executor for JSON processing
- Check out Notifications for more alerting options