libsmtp provides a practical SMTP client/server subset built on socket.
This library currently works on Magnolia's native runtime. In the JavaScript runtime it will fail with structured socket :error results until stream socket support is added there.
Supported commands in this implementation:
- Client:
EHLO,HELO,STARTTLS,MAIL FROM,RCPT TO,DATA,QUIT - Server:
EHLO,HELO,NOOP,RSET,STARTTLS,MAIL FROM,RCPT TO,DATA,QUIT
smtp := import('smtp')
Returns:
{ type: :ok, greeting: {...}, client: {...} }
Client methods:
command(line)ehlo(name?)helo(name?)startTLS(options?)mail(from)rcpt(to)data(body)send({from, to, raw? , headers?, body?})quit()close()
Starts an SMTP server and returns a close function.
Handler fields:
hostnameserver banner nameonMessage(message)called afterDATA
Message shape:
{
from: 'sender@example.com'
to: ['rcpt@example.com']
body: 'raw message body including headers'
tls?: false
}
onMessage should return an object like:
{ ok?: true, code: 250, message: 'queued' }
Enable STARTTLS with listener options:
{
startTLS?: true
certFile: './cert.pem'
keyFile: './key.pem'
}
smtp := import('smtp')
{ wait: wait } := import('std')
closeServer := smtp.listen('127.0.0.1:2525', {
onMessage: fn(message) {
println(message.body)
{ ok?: true, message: 'queued' }
}
})
wait(0.05)
clientResult := smtp.connect('127.0.0.1:2525')
client := clientResult.client
client.ehlo('localhost')
client.send({
from: 'sender@example.com'
to: ['rcpt@example.com']
raw: 'Subject: Demo\r\n\r\nhello smtp'
})
client.quit()
closeServer()