SMTP Sink Node
The smtpsink node sends an email via SMTP for each pipeline record, building recipients, subject, and body from record fields using template expressions.
Each record that passes through the sink triggers one email. Recipients, subject, and body are specified as templates that support {{$.field}} placeholders, allowing the email content to be fully dynamic based on record data. STARTTLS is enabled by default for encrypted transport.
Key Features
- Per-record email sending: each pipeline record triggers one outbound email
- Template expressions: use
{{$.field}}placeholders intoTemplate,ccTemplate,subjectTemplate, andbodyTemplateto build dynamic content from record fields - HTML and plain text support: set
bodyContentTypetotext/htmlfor rich HTML emails ortext/plainfor simple text - STARTTLS support: encrypted transport via STARTTLS is enabled by default
Configuration
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
host | String | Yes | — | SMTP server hostname |
port | Integer | No | 587 | SMTP server port |
credentialId | String | Yes | — | ID of username/password credentials in jobContext.otherProperties. |
fromAddress | String | Yes | — | Sender email address (e.g. alerts@example.com) |
toTemplate | String | Yes | — | Template expression for recipient(s). Supports {{$.field}} placeholders. |
ccTemplate | String | No | — | Template expression for CC recipients. Supports {{$.field}} placeholders. |
subjectTemplate | String | Yes | — | Template for the email subject. Supports {{$.field}} placeholders. |
bodyTemplate | String | Yes | — | Template for the email body. Supports {{$.field}} placeholders. |
bodyContentType | String | No | text/plain | MIME type of the body (text/plain or text/html) |
useTls | Boolean | No | true | Enable STARTTLS |
Template Expressions
Template fields support {{$.field}} placeholders that are evaluated against each pipeline record at runtime. For example, given a record:
{
"alert_email": "oncall@example.com",
"severity": "CRITICAL",
"host": "web-server-01",
"message": "Disk usage exceeded 90%"
}
The following configuration produces a fully dynamic email per record:
config:
fromAddress: "alerts@example.com"
toTemplate: "{{$.alert_email}}"
subjectTemplate: "Alert: {{$.severity}} on {{$.host}}"
bodyTemplate: "Host {{$.host}} reported: {{$.message}}"
bodyContentType: "text/plain"
This would send an email to oncall@example.com with the subject Alert: CRITICAL on web-server-01 and the body Host web-server-01 reported: Disk usage exceeded 90%.
DAG Example
jobContext:
otherProperties:
smtp-cred:
username: alerts@example.com
password: mypassword
metricTags: {}
dlqConfig:
dag:
- id: "source"
commandName: "stdin"
config:
encodingType: "JSON_OBJECT"
outputs:
- "sink"
- id: "sink"
commandName: "smtpsink"
config:
host: "smtp.example.com"
port: 587
credentialId: "smtp-cred"
fromAddress: "alerts@example.com"
toTemplate: "{{$.alert_email}}"
subjectTemplate: "Alert: {{$.severity}} on {{$.host}}"
bodyTemplate: "Host {{$.host}} reported: {{$.message}}"
bodyContentType: "text/plain"
useTls: true
Related Nodes
- imapsource: Poll an IMAP mailbox and emit each email as an record
- sqssink: Send pipeline records as messages to an SQS queue