Mail
Send emails from your workflows for notifications, alerts, and reports.
Basic Usage
smtp:
host: "smtp.gmail.com"
port: "587"
username: "${env.SMTP_USER}"
password: "${env.SMTP_PASS}"
steps:
- action: mail.send
with:
to: recipient@example.com
from: sender@example.com
subject: "Workflow Completed"
message: "The data processing workflow has completed successfully."SMTP Configuration
Configure SMTP at the DAG level for all mail steps. For global configuration, see Email Notifications.
Password Authentication
Use password authentication only when the SMTP provider still accepts it.
# Gmail
smtp:
host: "smtp.gmail.com"
port: "587"
username: "your-email@gmail.com"
password: "app-specific-password" # Not regular password
# AWS SES
smtp:
host: "email-smtp.us-east-1.amazonaws.com"
port: "587"
username: "${env.AWS_SES_SMTP_USER}"
password: "${env.AWS_SES_SMTP_PASSWORD}"OAuth 2.0
OAuth uses the same DAG-level smtp block and therefore works for every mail.send step and mail notification in the DAG. Omit host, port, and password; Dagu selects the provider's STARTTLS endpoint and authenticates with XOAUTH2.
env:
- SMTP_TENANT_ID: ${SMTP_TENANT_ID}
- SMTP_CLIENT_ID: ${SMTP_CLIENT_ID}
- SMTP_CLIENT_SECRET: ${SMTP_CLIENT_SECRET}
smtp:
username: alerts@contoso.com
oauth:
provider: microsoft
tenant_id: "${env.SMTP_TENANT_ID}"
client_id: "${env.SMTP_CLIENT_ID}"
client_secret: "${env.SMTP_CLIENT_SECRET}"Supported provider values are microsoft, google_service_account, and google_refresh. See Email Notifications for the required fields, Google examples, provider authorization steps, and SMTP inheritance behavior.
Variable Expansion
Scoped references in smtp fields expand DAG-scoped values. OS environment variables are not expanded directly. If your SMTP credentials come from the OS environment, import them in the env: block:
env:
- SMTP_USER: ${SMTP_USER} # Import from OS environment
- SMTP_PASS: ${SMTP_PASS}
smtp:
host: "smtp.gmail.com"
port: "587"
username: "${env.SMTP_USER}"
password: "${env.SMTP_PASS}"Examples
Multiple Recipients
steps:
- action: mail.send
with:
to:
- team@example.com
- manager@example.com
- stakeholders@example.com
from: noreply@example.com
subject: "Daily Report Ready"
message: "The daily report has been generated."
- action: mail.send
with:
to: admin@example.com # Single recipient still works
from: system@example.com
subject: "System Update"
message: "System maintenance completed."With Variables
params:
- ENVIRONMENT: production
- VERSION: v1.2.3
steps:
- action: mail.send
with:
to: devops@company.com
from: deploy@company.com
subject: "Deployed to ${params.ENVIRONMENT}"
message: |
Deployment completed:
- Environment: ${params.ENVIRONMENT}
- Version: ${params.VERSION}
- Attempt started: ${context.attempt.started_at}Success/Failure Notifications
handler_on:
success:
action: mail.send
with:
to: team@company.com
from: dagu@company.com
subject: "Pipeline Success - ${context.dag.name}"
message: |
Pipeline completed successfully.
Run ID: ${context.run.id}
Logs: ${context.paths.log_file}
failure:
action: mail.send
with:
to: oncall@company.com
from: alerts@company.com
subject: "Pipeline Failed - ${context.dag.name}"
message: |
Pipeline failed.
Run ID: ${context.run.id}
Check logs: ${context.paths.log_file}
steps:
- run: echo "Run your main tasks here"Error Alerts
error_mail:
from: alerts@company.com
to: oncall@company.com
prefix: "[CRITICAL]"
attach_logs: true
steps:
- run: echo "Run some critical task"
mail_on_error: trueWith Attachments
steps:
- id: generate_report
run: echo "Generating report..." > report.txt
- id: send_report
action: mail.send
with:
to: management@company.com
from: reports@company.com
subject: "Weekly Report"
message: "Please find the weekly report attached."
attachments:
- report.txt
depends: generate_reportWith Retry
steps:
- action: mail.send
with:
to: oncall@company.com
from: alerts@company.com
subject: "Critical Alert"
message: "Immediate action required."
retry_policy:
limit: 3
interval_sec: 60
