Skip to content

Sends email over SMTP and reads a mailbox over IMAP or POP3. Mail.properties returns a Compose object to send with, Mail.imap and Mail.pop return a Mailbox to read with. Things to know: the SMTP server is configured with the short keys host, port, auth and starttls or with JavaMail property names (["mail.smtp.host"]); both work. Mail.imap and Mail.pop connect immediately and raise an error when the login fails. Mailboxes are read-only: you can read and search but not delete, move or mark messages. No timeouts are set unless you add the JavaMail timeout properties. Keep passwords in secrets: secret("name"). Close mailboxes with mailbox.close() or Mail.close().

Example

Send a mail and wait for the reply

-- Send a notification, then wait for the answer in the inbox
local smtp = Mail.properties({
["mail.smtp.host"] = "smtp.example.com",
["mail.smtp.port"] = 587,
["mail.smtp.auth"] = "true",
["mail.smtp.starttls.enable"] = "true",
user = "bot@example.com",
password = secret("mail_password"),
})
smtp.send("alice@example.com", "Please confirm", "<p>Reply to confirm the order.</p>")
local mailbox = Mail.imap({ host = "imap.example.com", user = "bot@example.com", password = secret("mail_password") })
local replies = mailbox.poll({ from = "alice@example.com", subject = "Re: Please confirm" }, 120)
Assert.equals(1, #replies)
mailbox.close()

Functions

  • properties Compose Prepares sending mail over SMTP and returns a Compose object; no connection is made until you call send or sendFile on it.
  • imap Mailbox Connects to an IMAP server, logs in, opens a folder (INBOX unless folder is given) and returns the Mailbox.
  • pop Mailbox Connects to a POP3 server, logs in and returns the Mailbox for its inbox.
  • close self Closes every mailbox opened with Mail.imap or Mail.pop in this script.
Mail.properties(list: SmtpSettings)→Compose

Prepares sending mail over SMTP and returns a Compose object; no connection is made until you call send or sendFile on it. The table is handed to JavaMail as its properties, so JavaMail names work as well. Configure the server with host, port, auth = true to log in with user and password, starttls = true (port 587) or ssl = true (port 465) to encrypt. These are aliases for ["mail.smtp.host"], ["mail.smtp.port"], ["mail.smtp.auth"], ["mail.smtp.starttls.enable"] and ["mail.smtp.ssl.enable"]; the JavaMail key wins when both are given, and any other mail.smtp.* property can be added, such as ["mail.smtp.connectiontimeout"] and ["mail.smtp.timeout"] in milliseconds (default: wait forever). The keys user and password (or username) are used as login and the user is also the sender address of every mail. Without a host JavaMail tries localhost:25. An older list form {"mail.smtp.host, smtp.example.com"} also works. Raises an error when the argument is not a table.

Parameters

list SmtpSettings
JavaMail properties plus user and password

Returns

Compose Sends email through the SMTP server configured with Mail.properties.

Example

local smtp = Mail.properties({
["mail.smtp.host"] = "smtp.example.com",
["mail.smtp.port"] = 587,
["mail.smtp.auth"] = "true",
["mail.smtp.starttls.enable"] = "true",
["mail.smtp.connectiontimeout"] = 10000,
["mail.smtp.timeout"] = 20000,
user = "bot@example.com",
password = secret("smtp_password"),
})
smtp.send("alice@example.com", "Nightly report", "<p>The report is ready.</p>")
Mail.imap(list: MailboxSettings)→Mailbox

Connects to an IMAP server, logs in, opens a folder (INBOX unless folder is given) and returns the Mailbox. SSL is used by default (port 993). Raises an error when host, user or password is missing, when the login or connection fails ("Failed to connect to mailbox: ...") or when the folder does not exist. Add JavaMail properties such as ["mail.imap.connectiontimeout"] = 10000 to the table to set timeouts, which are unlimited by default. Close the mailbox when you are done.

Parameters

list MailboxSettings
Server, login and options; host, user and password are required

Returns

Mailbox A logged-in IMAP or POP3 mailbox with one open folder.

Example

local mailbox = Mail.imap({
host = "imap.example.com",
user = "bot@example.com",
password = secret("mail_password"),
["mail.imap.connectiontimeout"] = 10000,
})
local unread = mailbox.search({ seen = false, subject = "Invoice", limit = 10 })
for _, message in ipairs(unread) do
print(message.subject, message.from[1], message.has_attachments)
end
mailbox.close()
Mail.pop(list: MailboxSettings)→Mailbox

Connects to a POP3 server, logs in and returns the Mailbox for its inbox. Same settings and errors as Mail.imap, but without SSL by default (port 110; set ssl = true or port 995 for SSL). POP3 has a single folder (INBOX) and no message flags, so seen is always false and the seen/unseen search criteria are not useful. Prefer IMAP when the server offers it.

Parameters

list MailboxSettings
Server, login and options; host, user and password are required

Returns

Mailbox A logged-in IMAP or POP3 mailbox with one open folder.

Example

local mailbox = Mail.pop({ host = "pop.example.com", user = "bot@example.com", password = secret("mail_password"), ssl = true })
print(#mailbox.messages() .. " messages")
mailbox.close()
Mail.close()→self

Closes every mailbox opened with Mail.imap or Mail.pop in this script. Use mailbox.close() to close one.

Returns

self chainable The library itself, so calls can be chained.