std/smtp

    Dark Mode
Search:
  Source   Edit

This module implements the SMTP client protocol as specified by RFC 5321, this can be used to send mail to any SMTP Server.

This module also implements the protocol used to format messages, as specified by RFC 2822.

Example gmail use:

var msg = createMessage("Hello from Nim's SMTP",
                        "Hello!.\n Is this awesome or what?",
                        @["foo@gmail.com"])
let smtpConn = newSmtp(useSsl = true, debug=true)
smtpConn.connect("smtp.gmail.com", Port 465)
smtpConn.auth("username", "password")
smtpConn.sendmail("username@gmail.com", @["foo@gmail.com"], $msg)

Example for startTls use:

var msg = createMessage("Hello from Nim's SMTP",
                        "Hello!.\n Is this awesome or what?",
                        @["foo@gmail.com"])
let smtpConn = newSmtp(debug=true)
smtpConn.connect("smtp.mailtrap.io", Port 2525)
smtpConn.startTls()
smtpConn.auth("username", "password")
smtpConn.sendmail("username@gmail.com", @["foo@gmail.com"], $msg)

For SSL support this module relies on OpenSSL. If you want to enable SSL, compile with -d:ssl.

Types

AsyncSmtp = SmtpBase[AsyncSocket]
  Source   Edit
Message = object
  msgTo: seq[string]
  msgCc: seq[string]
  msgSubject: string
  msgOtherHeaders: StringTableRef
  msgBody: string
  Source   Edit
ReplyError = object of IOError
  Source   Edit
Smtp = SmtpBase[Socket]
  Source   Edit

Procs

proc `$`(msg: Message): string {....raises: [], tags: [].}
stringify for Message.   Source   Edit
proc auth(smtp: AsyncSmtp; username, password: string): owned(Future[void]) {.
    ...raises: [Exception], tags: [RootEffect].}
Sends an AUTH command to the server to login as the username using password. May fail with ReplyError.   Source   Edit
proc auth(smtp: Smtp; username, password: string) {.
    ...raises: [SslError, OSError, TimeoutError, ReplyError],
    tags: [WriteIOEffect, ReadIOEffect, TimeEffect].}
  Source   Edit
proc checkReply(smtp: AsyncSmtp; reply: string): owned(Future[void]) {.
    ...raises: [Exception], tags: [RootEffect].}

Calls debugRecv and checks that the received data starts with reply. If the received data does not start with reply, then a QUIT command will be sent to the SMTP server and a ReplyError exception will be raised.

This is a lower level proc and not something that you typically would need to call when using this module. One exception to this is if you are implementing any SMTP extensions.

  Source   Edit
proc checkReply(smtp: Smtp; reply: string) {.
    ...raises: [TimeoutError, OSError, SslError, ReplyError],
    tags: [ReadIOEffect, TimeEffect, WriteIOEffect].}
  Source   Edit
proc close(smtp: AsyncSmtp): owned(Future[void]) {....raises: [Exception],
    tags: [RootEffect].}
Disconnects from the SMTP server and closes the socket.   Source   Edit
proc close(smtp: Smtp) {....raises: [SslError, OSError, Exception, LibraryError],
                         tags: [WriteIOEffect, RootEffect].}
  Source   Edit
proc connect(smtp: AsyncSmtp; address: string; port: Port): owned(
    Future[void]) {....raises: [Exception], tags: [RootEffect].}
Establishes a connection with a SMTP server. May fail with ReplyError or with a socket error.   Source   Edit
proc connect(smtp: Smtp; address: string; port: Port) {.
    ...raises: [OSError, SslError, TimeoutError, ReplyError],
    tags: [ReadIOEffect, TimeEffect, WriteIOEffect].}
  Source   Edit
proc createMessage(mSubject, mBody: string; mTo, mCc: seq[string] = @[]): Message {.
    ...raises: [], tags: [].}

Alternate version of the above.

You need to make sure that mSubject, mTo and mCc don't contain any newline characters. Failing to do so will raise AssertionDefect.

  Source   Edit
proc createMessage(mSubject, mBody: string; mTo, mCc: seq[string];
                   otherHeaders: openArray[tuple[name, value: string]]): Message {.
    ...raises: [], tags: [].}

Creates a new MIME compliant message.

You need to make sure that mSubject, mTo and mCc don't contain any newline characters. Failing to do so will raise AssertionDefect.

  Source   Edit
proc debugRecv(smtp: AsyncSmtp): Future[string] {.
    ...raises: [Exception, ValueError], tags: [RootEffect].}

Receives a line of data from the socket connected to the SMTP server.

If the smtp object was created with debug enabled, debugRecv will invoke echo("S:" & result.string) after the data is received.

This is a lower level proc and not something that you typically would need to call when using this module. One exception to this is if you are implementing any SMTP extensions.

See checkReply(reply).

  Source   Edit
proc debugRecv(smtp: Smtp): string {....raises: [TimeoutError, OSError, SslError],
                                     tags: [ReadIOEffect, TimeEffect].}
  Source   Edit
proc debugSend(smtp: AsyncSmtp; cmd: string): owned(Future[void]) {.
    ...raises: [Exception], tags: [RootEffect].}

Sends cmd on the socket connected to the SMTP server.

If the smtp object was created with debug enabled, debugSend will invoke echo("C:" & cmd) before sending.

This is a lower level proc and not something that you typically would need to call when using this module. One exception to this is if you are implementing any SMTP extensions.

  Source   Edit
proc debugSend(smtp: Smtp; cmd: string) {....raises: [SslError, OSError],
    tags: [WriteIOEffect].}
  Source   Edit
proc ehlo(smtp: AsyncSmtp): Future[bool] {....raises: [Exception, ValueError],
    tags: [RootEffect].}
Sends EHLO request.   Source   Edit
proc ehlo(smtp: Smtp): bool {....raises: [SslError, OSError, TimeoutError],
                              tags: [WriteIOEffect, ReadIOEffect, TimeEffect].}
  Source   Edit
proc helo(smtp: AsyncSmtp): owned(Future[void]) {....raises: [Exception],
    tags: [RootEffect].}
  Source   Edit
proc helo(smtp: Smtp) {....raises: [SslError, OSError, TimeoutError, ReplyError],
                        tags: [WriteIOEffect, ReadIOEffect, TimeEffect].}
  Source   Edit
proc newAsyncSmtp(useSsl = false; debug = false; sslContext: SslContext = nil): AsyncSmtp {.
    ...raises: [OSError, Exception, SslError, LibraryError, IOError],
    tags: [RootEffect, ReadDirEffect, ReadEnvEffect].}
Creates a new AsyncSmtp instance.   Source   Edit
proc newSmtp(useSsl = false; debug = false; sslContext: SslContext = nil): Smtp {.
    ...raises: [OSError, SslError, Exception, LibraryError, IOError],
    tags: [RootEffect, ReadDirEffect, ReadEnvEffect].}
Creates a new Smtp instance.   Source   Edit
proc sendMail(smtp: AsyncSmtp; fromAddr: string; toAddrs: seq[string];
              msg: string): owned(Future[void]) {....raises: [Exception],
    tags: [RootEffect].}

Sends msg from fromAddr to the addresses specified in toAddrs. Messages may be formed using createMessage by converting the Message into a string.

You need to make sure that fromAddr and toAddrs don't contain any newline characters. Failing to do so will raise AssertionDefect.

  Source   Edit
proc sendMail(smtp: Smtp; fromAddr: string; toAddrs: seq[string]; msg: string) {.
    ...raises: [SslError, OSError, TimeoutError, ReplyError],
    tags: [WriteIOEffect, ReadIOEffect, TimeEffect].}
  Source   Edit
proc startTls(smtp: AsyncSmtp; sslContext: SslContext = nil): owned(
    Future[void]) {....raises: [Exception],
                    tags: [RootEffect, ReadDirEffect, ReadEnvEffect].}
Put the SMTP connection in TLS (Transport Layer Security) mode. May fail with ReplyError   Source   Edit
proc startTls(smtp: Smtp; sslContext: SslContext = nil) {....raises: [SslError,
    OSError, TimeoutError, ReplyError, Exception, LibraryError, IOError], tags: [
    WriteIOEffect, ReadIOEffect, TimeEffect, RootEffect, ReadDirEffect,
    ReadEnvEffect].}
  Source   Edit