SIMPLE_SMTP

API Reference

Class Overview

SIMPLE_SMTP provides native SMTP email sending for Eiffel applications. It supports TLS, authentication, HTML emails, and attachments without requiring external tools or shell commands.

Configuration Features

make (a_host: STRING; a_port: INTEGER)

create smtp.make ("smtp.example.com", 587)

Initialize SMTP client for the specified host and port. Automatically sets TLS mode based on port (465 = TLS, 587 = STARTTLS).

Contracts

require: host_not_void: a_host /= Void
require: host_not_empty: not a_host.is_empty
require: valid_port: a_port > 0 and a_port < 65536
ensure: host_set: host = a_host
ensure: port_set: port = a_port

set_credentials (a_username, a_password: STRING)

smtp.set_credentials ("user@example.com", "password")

Set authentication credentials for AUTH LOGIN.

Contracts

require: username_not_void: a_username /= Void
require: password_not_void: a_password /= Void
ensure: username_set: username = a_username
ensure: password_set: password = a_password

set_timeout (a_seconds: INTEGER)

smtp.set_timeout (60)

Set connection timeout in seconds. Default is 30 seconds.

Contracts

require: positive: a_seconds > 0
ensure: timeout_set: timeout_seconds = a_seconds

enable_tls

smtp.enable_tls

Enable TLS/SSL connection from start (port 465 style). Mutually exclusive with STARTTLS.

Contracts

ensure: tls_enabled: use_tls
ensure: starttls_disabled: not use_starttls

enable_starttls

smtp.enable_starttls

Enable STARTTLS upgrade (port 587 style). Mutually exclusive with TLS.

Contracts

ensure: starttls_enabled: use_starttls
ensure: tls_disabled: not use_tls

Recipient Features

set_from (a_email: STRING; a_name: detachable STRING)

smtp.set_from ("sender@example.com", "Sender Name")

Set sender email address and optional display name.

Contracts

require: email_not_void: a_email /= Void
require: email_not_empty: not a_email.is_empty
ensure: from_set: internal_from_email.same_string (a_email)
ensure: has_from: has_sender

add_to (a_email: STRING; a_name: detachable STRING)

smtp.add_to ("recipient@example.com", "Recipient")

Add a To recipient with optional display name.

Contracts

require: email_not_void: a_email /= Void
require: email_not_empty: not a_email.is_empty
ensure: recipient_added: to_count = old to_count + 1

add_cc (a_email: STRING; a_name: detachable STRING)

smtp.add_cc ("cc@example.com", "CC Person")

Add a Cc (carbon copy) recipient.

Contracts

require: email_not_void: a_email /= Void
require: email_not_empty: not a_email.is_empty
ensure: recipient_added: cc_count = old cc_count + 1

add_bcc (a_email: STRING; a_name: detachable STRING)

smtp.add_bcc ("hidden@example.com", Void)

Add a Bcc (blind carbon copy) recipient. Not included in message headers.

Contracts

require: email_not_void: a_email /= Void
require: email_not_empty: not a_email.is_empty
ensure: recipient_added: bcc_count = old bcc_count + 1

clear_recipients

smtp.clear_recipients

Clear all To, Cc, and Bcc recipients.

Contracts

ensure: no_to: to_count = 0
ensure: no_cc: cc_count = 0
ensure: no_bcc: bcc_count = 0

Content Features

set_subject (a_subject: STRING)

smtp.set_subject ("Hello from Eiffel!")

Set the email subject line.

Contracts

require: subject_not_void: a_subject /= Void
ensure: subject_set: internal_subject = a_subject
ensure: has_subject: has_subject_set

set_body (a_body: STRING)

smtp.set_body ("This is the email body.")

Set plain text body. Clears any HTML body.

Contracts

require: body_not_void: a_body /= Void
ensure: body_set: body_text = a_body
ensure: has_body: has_body_set

set_html_body (a_html: STRING)

smtp.set_html_body ("<html><body><h1>Hello</h1></body></html>")

Set HTML body for rich formatting.

Contracts

require: html_not_void: a_html /= Void
ensure: html_set: body_html = a_html
ensure: has_body: has_body_set

set_body_with_html (a_text, a_html: STRING)

smtp.set_body_with_html ("Plain text", "<html>HTML</html>")

Set both plain text and HTML body (multipart/alternative). Email clients choose which to display.

Contracts

require: text_not_void: a_text /= Void
require: html_not_void: a_html /= Void
ensure: text_set: body_text = a_text
ensure: html_set: body_html = a_html

add_attachment (a_filename: STRING; a_content: STRING; a_mime_type: STRING)

smtp.add_attachment ("report.pdf", pdf_content, "application/pdf")

Add a file attachment. Content is Base64 encoded automatically.

Contracts

require: filename_not_void: a_filename /= Void
require: content_not_void: a_content /= Void
require: mime_not_void: a_mime_type /= Void
ensure: attachment_added: attachment_count = old attachment_count + 1

clear_attachments

smtp.clear_attachments

Remove all attachments.

Contracts

ensure: no_attachments: attachment_count = 0

Sending Features

send: BOOLEAN

if smtp.send then print ("Sent!") end

Send the email. Returns True on success. Check last_error on failure.

Contracts

require: has_from: has_sender
require: has_recipients: has_recipients
require: has_subject: has_subject_set
require: has_body: has_body_set
ensure: error_on_failure: not Result implies has_error

send_async (a_callback: detachable PROCEDURE [BOOLEAN])

smtp.send_async (agent handle_result)

Send email with callback for result. Currently implemented synchronously.

Contracts

require: has_from: has_sender
require: has_recipients: has_recipients
require: has_subject: has_subject_set
require: has_body: has_body_set

Status Features

has_error: BOOLEAN

if smtp.has_error then print (smtp.last_error) end

Check if the last operation produced an error.

last_error: STRING

error_msg := smtp.last_error

Error message from last failed operation. Empty if no error.

last_response: STRING

response := smtp.last_response

Last SMTP server response string.

Query Features

Feature Type Description
has_sender BOOLEAN Has sender been set?
has_recipients BOOLEAN Are there any To recipients?
has_subject_set BOOLEAN Has subject been set?
has_body_set BOOLEAN Has body (text or HTML) been set?
to_count INTEGER Number of To recipients
cc_count INTEGER Number of Cc recipients
bcc_count INTEGER Number of Bcc recipients
attachment_count INTEGER Number of attachments

Class Invariants

invariant: host_exists: host /= Void
invariant: host_not_empty: not host.is_empty
invariant: valid_port: port > 0 and port < 65536
invariant: to_lists_match: to_emails.count = to_names.count
invariant: cc_lists_match: cc_emails.count = cc_names.count
invariant: bcc_lists_match: bcc_emails.count = bcc_names.count
invariant: attachments_consistent: attachment_names.count = attachment_contents.count
invariant: timeout_positive: timeout_seconds > 0
invariant: tls_modes_exclusive: not (use_tls and use_starttls)