NOTICE: All information contained herein is, and remains
the property of TechnoCore Automate.
Updated : 2026-03-17
ObjWorkflowSendMail is the SENDMAIL workflow node
executor. It sends emails directly via SMTP using
WebMail.send_report(), with optional template rendering
via ObjTemplate and AI-generated summaries via ObjAI.
Registered as WorkflowNodeType.SENDMAIL via
@ObjNodeRegistry.register.
SENDMAIL — direct SMTP email delivery.
Icon: 📤
| Mode | Description |
|---|---|
| SINGLE | Send one email using template, inline body, or context |
| BULK | Iterate a rendered output table and send per row |
{
"mode": "SINGLE",
"to": "user@example.com",
"template_code": "WF_RUN_COMPLETE",
"remote_connection": "smtp"
}
Sends one email. Subject and body come from one of:
def_email_templateObjTemplate.render_email(), with workflowsubject and body in node_data,local_patch_param_render_subject /_render_body from a preceding FEATURERENDER node| Parameter | Default | Description |
|---|---|---|
to |
from context | Recipient email address |
template_code |
— | Email template from def_email_template |
subject |
_render_subject | Email subject (if no template_code) |
body |
_render_body | Email body (if no template_code) |
remote_connection |
smtp | SMTP credentials key |
attachments |
— | Comma-separated file paths |
Context fallback keys (set by FEATURERENDER SINGLE):
_render_to — recipient_render_subject — subject line_render_body — message bodyIterates a rendered output table and sends one email per
row. Looks up the recipient email from the source table.
| Parameter | Default | Description |
|---|---|---|
to |
— | Source table column containing email address |
rendered_table |
_render_output_table | Table with rendered messages |
remote_connection |
smtp | SMTP credentials key |
channel_filter |
— | Only send rows matching this channel |
attachments |
— | Comma-separated file paths |
Context fallback keys (set by FEATURERENDER BULK):
_render_output_table — rendered messages table_render_source_table — source data table_render_pk_column — primary key columnWhen template_code is set, the node loads the template
from def_email_template via ObjTemplate.render_email().
The workflow context is enriched with computed stats
before rendering:
| Context Key | Source |
|---|---|
$workflow$ |
Workflow name from result dict |
$timestamp$ |
Current date/time |
$host$ |
Server hostname |
$package$ |
Active package |
$transition_count$ |
Number of DAG transitions |
$total_elapsed_s$ |
Total pipeline time in seconds |
$ai_summary$ |
AI-generated or rule-based summary |
$sections_html$ |
Auto-generated detail sections |
The enrichment engine builds HTML sections based on what
data exists in the workflow context. Only populated
sections are included:
| Section | Condition |
|---|---|
| Pipeline Summary | Always (shows node timings) |
| Feature Store | _featurestore_compute in context |
| Global Aggregates | globals table exists |
| Rendered Output | _render_output_table in context |
| By Channel | output table has Channel column |
| By Template | output table has TemplateCode column |
| Sample Output | output table has rows |
| Additional Results | extra scalar result keys |
This makes the template system generic — any workflow
can use the same WF_RUN_COMPLETE template regardless
of which node types it contains.
The node generates an executive summary for the email:
config.yaml → ai.summary model (preferred)ai.default model# config.yaml
ai:
default: mcp:ollama:mistral
summary: mcp:ollama:qwen3:8b
The AI receives a structured text block of all run
metrics and generates a concise bullet-point analysis.
The to parameter is resolved in order:
@ — treated as a literal address@ — use thatThe remote_connection parameter controls credentials:
| Value | Behaviour |
|---|---|
smtp or empty |
Read from config.yaml smtp section |
WEBMASTER |
Read from email.WEBMASTER in config or def_remoteconnections |
# config.yaml
smtp:
server: smtp-relay.brevo.com
port: 587
username: xxx@smtp-brevo.com
password: secret
sender: noreply@example.com
| Key | Description |
|---|---|
_sendmail_total |
Total rows attempted |
_sendmail_sent |
Successfully sent count |
_sendmail_status |
SENT / DONE / FAIL / NO EMAIL |
START → FEATURESTORE → FEATURERENDER → SENDMAIL → DONE
(compute) (render) (deliver)
{
"mode": "SINGLE",
"to": "team@example.com",
"template_code": "WF_RUN_COMPLETE",
"remote_connection": "smtp"
}
START → CALC → SENDMAIL → DONE
{
"mode": "SINGLE",
"to": "admin@example.com",
"template_code": "WF_RUN_COMPLETE",
"remote_connection": "smtp"
}
{
"mode": "BULK",
"to": "Email",
"remote_connection": "smtp",
"channel_filter": "Email"
}
| SENDMAIL | ||
|---|---|---|
| Delivery | MongoDB queue → ServeConversation | Direct SMTP |
| Templates | def_Channel / def_notify | def_email_template / inline |
| AI Summary | No | Yes (via ObjAI) |
| Use case | Channel pipeline (async) | Direct outcome delivery |
ObjTemplate.py — email template managementObjWebMail.py — SMTP email deliveryObjWorkflowFeatureRender.py — FEATURERENDER nodeObjWorkflowEmail.py — EMAIL node (channel queue)ObjAI.py — AI model integrationUpdated : 2026-03-17