← All ivy-nodes
IVYXSTUDIO · IVY NODE
E
Email Send
ivy.node.email-send · v0.1.0
ivyx✓
Sends a plain-text or HTML email through an SMTP server in one step and returns the recipients it went to. TLS and login are optional, so a local relay works as well as a mail provider; reference the password as a stored secret.
#email#smtp#send#notify#mail
Inputs
| Field | Type | Description |
|---|---|---|
| smtp_hostrequired | string | The SMTP server, such as smtp.example.com or localhost for a local relay. |
| smtp_port | integer | The port: 587 for STARTTLS, 1025 for mailpit. |
| from_addrrequired | string | The sender address. |
| torequired | Not declared | One address, several separated by commas, or a list. |
| subjectrequired | string | The subject line. |
| bodyrequired | string | The plain-text body. |
| html | string | An HTML version of the body, sent alongside it. |
| use_tls | boolean | Upgrade with STARTTLS. On by default on port 587; port 465 is always TLS. |
| username | string | Login name, when the server needs one. |
| password | string | Login password; reference a stored secret instead of writing it. |
Outputs
| Field | Type | Description |
|---|---|---|
| sentrequired | boolean | True once the server accepted the message. |
| recipientsrequired | array | The addresses it was accepted for. |
| subjectrequired | string | The subject sent. |
Source
python
inp = __ivy_ctx__["nodes"][__ivy_node_id__]["input"]
import smtplib
from email.message import EmailMessage
host = inp["smtp_host"]
port = int(inp.get("smtp_port", 587))
sender = inp["from_addr"]
to = inp["to"]
recipients = [a.strip() for a in (to if isinstance(to, list) else str(to).split(",")) if a and a.strip()]
if not recipients:
raise ValueError("There is no recipient.")
message = EmailMessage()
message["From"] = sender
message["To"] = ", ".join(recipients)
message["Subject"] = inp["subject"]
message.set_content(inp["body"])
if inp.get("html"):
message.add_alternative(inp["html"], subtype="html")
# 465 is TLS from the first byte; 587 upgrades with STARTTLS; anything else
# (25, a local relay on 1025) is plain unless use_tls says otherwise.
connect = smtplib.SMTP_SSL if port == 465 else smtplib.SMTP
with connect(host, port, timeout=30) as server:
if port != 465 and inp.get("use_tls", port == 587):
server.starttls()
if inp.get("username") and inp.get("password"):
server.login(inp["username"], inp["password"])
refused = server.send_message(message) or {}
out = __ivy_ctx__["nodes"][__ivy_node_id__]["output"]
out["sent"] = True
out["recipients"] = [r for r in recipients if r not in refused]
out["subject"] = inp["subject"]Tests
Requires: python:3.9
- relay
A local relay accepts a message for two recipients.
- no-recipient
An empty recipient list is refused before connecting.
- closed-port
Nothing listening fails the step.