Compose email with recipients, HTML bodies and attachments, check it, and send it through an SMTP server.
import "std:email"std:email builds an email message and sends it through an SMTP server. Composing needs no network, so you can build, check and print a message to see exactly what would go out. Only send talks to a server.
Build a message#
email.new(options) returns a result, because it checks every address. Add recipients, set a body, and read the pieces back:
import "std:email"
auto mail = email.new({from: "[email protected]", to: "[email protected]", subject: "Lunch?"}).unwrap()
mail.setBody("Hi Bob,\nare you free at noon?")
log mail.from() mail.to() mail.subject()
log mail.preview()preview() is a quick look for logs and tests.
More recipients#
addTo, addCc and addBcc add one address each, and setTo and friends replace the lot. Bcc addresses get the message but never appear in the headers:
import "std:email"
auto mail = email.new({from: "[email protected]", to: ["[email protected]", "[email protected]"]}).unwrap()
mail.addCc("[email protected]").unwrap()
mail.addBcc("[email protected]").unwrap()
log mail.recipients()
log mail.bcc()
log mail.hasRecipient("[email protected]")
log mail.stringify().contains("[email protected]")Bad addresses#
Adding a bad address fails and leaves the message as it was:
import "std:email"
auto mail = email.new({from: "[email protected]"}).unwrap()
auto bad = mail.addTo("not an address")
log bad.isErr() bad.unwrapErr().kind
log mail.to()
log email.new({from: "nope"}).isErr()Check before sending#
validate() says whether the message can be sent: it needs a sender, a recipient and a subject, and it explains what is missing:
import "std:email"
auto mail = email.new({to: "[email protected]"}).unwrap()
log mail.validate().unwrapErr().message
mail.setFrom("[email protected]").unwrap()
log mail.validate().unwrapErr().message
mail.setSubject("Hi")
mail.setBody("hello")
log mail.validate().isOk()HTML and attachments#
setBody(text, {html: true}) sends the body as HTML. attach(name, data) adds a file from memory and attachFile(path) one from disk:
import "std:email"
auto mail = email.new({from: "[email protected]", to: "[email protected]", subject: "Report"}).unwrap()
mail.setBody("<h1>Weekly report</h1><p>See attached.</p>", {html: true})
mail.attach("numbers.csv", "week,sales\n1,10\n2,14\n").unwrap()
log mail.isHTML()
log mail.attachments()
string wire = mail.stringify()
log wire.contains("Content-Type: text/html")
log wire.contains("numbers.csv")stringify() returns the complete message as send would transmit it, which is useful for tests that check what an app would email.
Which recipients appear in the message's headers?
Sending#
mail.send(host, options) delivers the message. The defaults suit a normal provider: port 587 with TLS negotiated when the server offers it. Credentials go in the options:
import "std:email"
import "std:env"
auto mail = email.new({from: "[email protected]", to: "[email protected]", subject: "Hi"}).unwrap()
mail.setBody("Sent from OSL")
auto outcome = mail.send("smtp.example.com", {
username: env.get("SMTP_USER"),
password: env.get("SMTP_PASSWORD")
})
switch outcome (
case ok(_)
log "sent"
case err(e)
log "not sent:" e.kind e.message
)Failures come back as an error: NetworkError and TimeoutError for connection trouble, PermissionError for a refused login, UnsupportedError when the server has no TLS and you gave a password (the password would travel in the clear), RuntimeError when the server refuses the sender, recipient or message, and StateError when the message isn't valid. Read the password from env, not from source.
A receipt
Build a message from [email protected] to a customer with the subject Your receipt and a body of Total: 12.50. Print its subject, and whether it is valid.
Your receipt true
API reference#
91 members, generated from the std:email source of OSL 9.3.0.
Functions
email.addBcc(any recipient) booleanDeprecated. Deprecated: use email.new() and message.addBcc(address) instead.
addBcc adds a Bcc address to the shared message.
email.addCc(any recipient) booleanDeprecated. Deprecated: use email.new() and message.addCc(address) instead.
addCc adds a Cc address to the shared message.
email.addTo(any recipient) booleanDeprecated. Deprecated: use email.new() and message.addTo(address) instead.
addTo adds a To address to the shared message.
email.addToMany(array recipients) booleanDeprecated. Deprecated: use email.new({to: addresses}) instead.
addToMany adds To addresses to the shared message.
email.attachContent(object files) booleanDeprecated. Deprecated: use email.new() and message.attach(name, data) instead.
attachContent attaches name → content pairs to the shared message.
email.attachFile(any filePath) booleanDeprecated. Deprecated: use email.new() and message.attachFile(path) instead.
attachFile attaches a file to the shared message.
email.buildMessage(string from, any ...unused) stringDeprecated. Deprecated: use message.stringify() instead.
buildMessage returns the shared message's text as sent by from.
email.clear()Deprecated. Deprecated: use message.clear() instead.
clear empties the shared message except its sender.
email.create() *email.EmailDeprecated. Deprecated: use email.new(options?) instead.
create returns a new, empty message.
email.fromMap(object data) *email.EmailDeprecated. Deprecated: use email.new(options) instead, which fails with ValueError for an invalid address.
fromMap builds a message from {from, to, cc, bcc, subject, body, html}, silently skipping invalid addresses.
email.getBcc() arrayDeprecated. Deprecated: use email.new() and message.bcc() instead.
getBcc returns the shared message's Bcc addresses.
email.getBody() stringDeprecated. Deprecated: use email.new() and message.body() instead.
getBody returns the shared message's body.
email.getCc() arrayDeprecated. Deprecated: use email.new() and message.cc() instead.
getCc returns the shared message's Cc addresses.
email.getHeaders() string[string]Deprecated. Deprecated: use message.headers() instead.
getHeaders returns the shared message's From, To, Subject and Date.
email.getRecipientCount() intDeprecated. Deprecated: use message.recipients().len instead.
getRecipientCount returns the shared message's number of recipients.
email.getRecipients() arrayDeprecated. Deprecated: use message.recipients() instead.
getRecipients returns the shared message's recipients.
email.getSubject() stringDeprecated. Deprecated: use email.new() and message.subject() instead.
getSubject returns the shared message's subject.
email.getTo() arrayDeprecated. Deprecated: use email.new() and message.to() instead.
getTo returns the shared message's To addresses.
email.hasRecipient(string recipient) booleanDeprecated. Deprecated: use message.hasRecipient(address) instead.
hasRecipient reports whether the shared message has the recipient.
email.isHTML() booleanDeprecated. Deprecated: use email.new() and message.isHTML() instead.
isHTML reports whether the shared message's body is HTML.
email.new(object? options) result<*email.Email, error>new returns a message. Options: from, to, cc and bcc (an address or an array of addresses), subject, body and html (true when body is HTML). Fails with ValueError when an address is invalid; addresses must be plain ASCII such as "[email protected]".
email.preview() stringDeprecated. Deprecated: use message.preview() instead.
preview summarises the shared message.
email.queue() objectDeprecated. Deprecated: use message.toMap() instead.
queue returns {email, queuedAt, sent: false} for the shared message.
email.sendGmail(any username, any password) objectDeprecated. Deprecated: use message.send("smtp.gmail.com", {username, password}) instead.
sendGmail sends the shared message through Gmail.
email.sendLocalhost() objectDeprecated. Deprecated: use message.send("localhost", {port: 25}) instead.
sendLocalhost sends the shared message through localhost:25.
email.sendOffice365(any username, any password) objectDeprecated. Deprecated: use message.send("smtp.office365.com", {username, password}) instead.
sendOffice365 sends the shared message through Office 365.
email.sendOutlook(any username, any password) objectDeprecated. Deprecated: use message.send("smtp-mail.outlook.com", {username, password}) instead.
sendOutlook sends the shared message through Outlook.
email.sendWithSmtp(any host, any port, any username, any ...rest) objectDeprecated. Deprecated: use email.new() and message.send(host, options) instead.
sendWithSmtp(host, port, username, password, auth) sends the shared message.
email.setBcc(any recipients) booleanDeprecated. Deprecated: use email.new() and message.setBcc(addresses) instead.
setBcc replaces the shared message's Bcc addresses, skipping invalid ones.
email.setBody(any body)Deprecated. Deprecated: use email.new({body}) instead.
setBody sets the shared message's body.
email.setCc(any recipients) booleanDeprecated. Deprecated: use email.new() and message.setCc(addresses) instead.
setCc replaces the shared message's Cc addresses, skipping invalid ones.
email.setFrom(any addr) booleanDeprecated. Deprecated: use email.new({from}) and message.setFrom(address) instead.
setFrom sets the shared message's sender, or returns false for an invalid address.
email.setHTML(any html) booleanDeprecated. Deprecated: use email.new({body, html: true}) instead.
setHTML sets an HTML body on the shared message and returns true.
email.setSubject(any subject)Deprecated. Deprecated: use email.new({subject}) instead.
setSubject sets the shared message's subject.
email.setText(any text)Deprecated. Deprecated: use email.new({body}) instead.
setText sets a plain-text body on the shared message.
email.setTo(any recipients) booleanDeprecated. Deprecated: use email.new() and message.setTo(addresses) instead.
setTo replaces the shared message's To addresses.
email.toMap() objectDeprecated. Deprecated: use message.toMap() instead.
toMap returns the shared message as an object.
email.validate() booleanDeprecated. Deprecated: use message.validate() instead.
validate reports whether the shared message has a sender, a To address and a subject.
email.wrapText(any width) booleanDeprecated. Deprecated: use message.setBody(text, {wrap: width}) instead.
wrapText wraps the shared message's body.
*email.Email
email.addBcc(string address) result<unit, error>addBcc adds a Bcc address, like addTo.
email.addCc(string address) result<unit, error>addCc adds a Cc address, like addTo.
email.addTo(string address) result<unit, error>addTo adds a To address. An address already on the message (in any list, ignoring case) is skipped. Fails with ValueError when address is invalid.
email.addToMany(array recipients) booleanDeprecated. Deprecated: use message.addTo(address) for each address instead.
addToMany adds To addresses, stopping with false at the first invalid or duplicate one.
email.attach(string name, any data) result<unit, error>attach adds an attachment called name holding data, a string or byte[]. Fails with ValueError when name is empty or the message already has an attachment with that name. Throws TypeError for other data types.
email.attachContent(object files) booleanDeprecated. Deprecated: use message.attach(name, data) instead.
attachContent attaches each name → content pair of files, returning false at the first empty or duplicate name.
email.attachFile(string path, object? options) result<unit, error>attachFile attaches the file at path, named after the file. Options: name (the attachment's name instead). Fails with NotFoundError or PermissionError when the file can't be read, IOError when path is a directory, and ValueError when an attachment with that name exists.
email.attachments() string[]attachments returns the attachment names, sorted.
email.bcc() string[]bcc returns the Bcc addresses. They receive the message but are never written into it.
email.body() stringbody returns the body text.
email.buildMessage(string from, any ...unused) stringDeprecated. Deprecated: use message.stringify() instead.
buildMessage returns the message text as sent by from.
email.cc() string[]cc returns the Cc addresses.
email.clear()clear removes the recipients, subject, body and attachments, keeping the sender.
email.create() *email.EmailDeprecated. Deprecated: use email.new(options?) instead.
create returns a new, empty message.
email.from() string?from returns the sender's address, or null when none is set.
email.fromMap(object data) *email.EmailDeprecated. Deprecated: use email.new(options) instead.
fromMap builds a new message from {from, to, cc, bcc, subject, body, html}, silently skipping invalid addresses.
email.getBcc() arrayDeprecated. Deprecated: use message.bcc() instead.
getBcc returns the Bcc addresses.
email.getCc() arrayDeprecated. Deprecated: use message.cc() instead.
getCc returns the Cc addresses.
email.getHeaders() string[string]Deprecated. Deprecated: use message.headers() instead.
getHeaders returns From, To, Subject and Date.
email.getRecipientCount() intDeprecated. Deprecated: use message.recipients().len instead.
getRecipientCount returns the number of recipients.
email.getRecipients() arrayDeprecated. Deprecated: use message.recipients() instead.
getRecipients returns every recipient.
email.getSubject() stringDeprecated. Deprecated: use message.subject() instead.
getSubject returns the subject.
email.getTo() arrayDeprecated. Deprecated: use message.to() instead.
getTo returns the To addresses.
email.hasRecipient(string address) booleanhasRecipient reports whether address is a To, Cc or Bcc recipient, ignoring case.
email.headers() string[string]headers returns the headers the message is sent with: From, To, Cc (when there are Cc addresses), Subject, Date (now) and MIME-Version. Bcc addresses are never included.
email.isHTML() booleanisHTML reports whether the body is sent as HTML rather than plain text.
email.preview() stringpreview returns a short readable summary: the From, To and Subject lines, a blank line and the body.
email.queue() objectDeprecated. Deprecated: use message.toMap() instead.
queue returns {email, queuedAt (unix seconds), sent: false}. Nothing is queued.
email.recipients() string[]recipients returns every To, Cc and Bcc address, in that order.
email.reset()reset clears everything, the sender included.
email.send(string host, object? options) result<unit, error>send delivers the message through the SMTP server at host. Options: port (default 587, or 465 with implicit TLS), username, password, tls ("auto", "starttls", "implicit" or "none") and timeout (milliseconds, default 30000). Fails with StateError, PermissionError, UnsupportedError, NetworkError, TimeoutError or RuntimeError.
email.sendGmail(any username, any password) objectDeprecated. Deprecated: use message.send("smtp.gmail.com", {username, password}) instead.
sendGmail sends through smtp.gmail.com:587.
email.sendLocalhost() objectDeprecated. Deprecated: use message.send("localhost", {port: 25}) instead.
sendLocalhost sends through localhost:25 without signing in.
email.sendOffice365(any username, any password) objectDeprecated. Deprecated: use message.send("smtp.office365.com", {username, password}) instead.
sendOffice365 sends through smtp.office365.com:587.
email.sendOutlook(any username, any password) objectDeprecated. Deprecated: use message.send("smtp-mail.outlook.com", {username, password}) instead.
sendOutlook sends through smtp-mail.outlook.com:587.
email.sendWithSmtp(any host, any port, any username, any ...rest) objectDeprecated. Deprecated: use message.send(host, {port, username, password}) instead, which fails with a typed error.
sendWithSmtp(host, port, username, password, auth) sends the message and returns {success: true, message} or {success: false, error}.
email.setBcc(array addresses) result<unit, error>setBcc replaces the Bcc addresses, like setTo.
email.setBody(string body, object? options)setBody replaces the body. Options: html (true for an HTML body, false for plain text; when omitted the format stays as it was, plain text for a new message) and wrap (wrap each line at this many characters, breaking between words). Throws ValueError when wrap is less than 1.
email.setCc(array addresses) result<unit, error>setCc replaces the Cc addresses, like setTo.
email.setFrom(string address) result<unit, error>setFrom sets the sender's address. Fails with ValueError, leaving the sender unchanged, when address isn't a valid email address.
email.setHTML(any html) booleanDeprecated. Deprecated: use message.setBody(html, {html: true}) instead.
setHTML sets an HTML body and returns true.
email.setSubject(string subject)setSubject sets the subject. Line breaks become spaces, so a subject can't add headers.
email.setText(any text)Deprecated. Deprecated: use message.setBody(text, {html: false}) instead.
setText sets a plain-text body.
email.setTo(array addresses) result<unit, error>setTo replaces the To addresses with addresses, an array of strings; addresses already on the message are skipped. Fails with ValueError, changing nothing, when any address is invalid.
email.stringify() stringstringify returns the message exactly as send would transmit it: MIME headers, a quoted-printable body and base64 attachments. Bcc addresses are not included.
email.subject() stringsubject returns the subject.
email.to() string[]to returns the To addresses.
email.toMap() {bcc: string[], body: string, cc: string[], from: string, html: boolean, subject: string, to: string[]}toMap returns the message as an object with the keys from, to, cc, bcc, subject, body and html. Attachments are not included. email.new accepts the same keys.
email.validate() result<unit, error>validate checks that the message can be sent: it has a sender, at least one To address and a subject. Fails with StateError naming what is missing.
email.wrapText(any width) booleanDeprecated. Deprecated: use message.setBody(text, {wrap: width}) instead.
wrapText wraps the body at width characters (78 when width is 0) and returns true.