:email: SMTP protocol support for the Vapor web framework.

30
7
Swift

Smtp

Build Status
Swift 5.2
Vapor 4
Swift Package Manager
Platforms OS X | Linux

📧 SMTP protocol support for the Vapor web framework.

This framework has dependencies only to Vapor and SwiftNIO packages.
SwiftNIO support was inspired by Apple examples: Swift NIO examples.

Features:

  • [x] Vapor provider/service
  • [x] async/await support
  • [x] SwiftNIO Support
  • [x] Text/HTML
  • [x] Attachments
  • [x] SSL/TLS (when connection starts)
  • [x] STARTTLS support
  • [x] Multiple recipients & CC
  • [x] Reply to
  • [x] BCC fields
  • [ ] Multiple emails sent at the same time (one SMTP connection)

Getting started

You need to add library to Package.swift file:

  • add package to dependencies:
.package(url: "https://github.com/Mikroservices/Smtp.git", from: "3.0.0")
  • and add product to your target:
.target(name: "App", dependencies: [
    .product(name: "Vapor", package: "vapor"),
    .product(name: "Smtp", package: "Smtp")
])

Set the SMTP server configuration (e.g. in main.swift file)

import Smtp

var env = try Environment.detect()
try LoggingSystem.bootstrap(from: &env)

let app = Application(env)
defer { app.shutdown() }

app.smtp.configuration.host = "smtp.server"
app.smtp.configuration.signInMethod = .credentials(username: "johndoe", password: "passw0rd")
app.smtp.configuration.secure = .ssl

try configure(app)
try app.run()

Using SMTP client (EventLoopFuture)

let email = try! Email(from: EmailAddress(address: "[email protected]", name: "John Doe"),
                  to: [EmailAddress(address: "[email protected]", name: "Ben Doe")],
                  subject: "The subject (text)",
                  body: "This is email body.")

request.smtp.send(email).map { result in
    switch result {
    case .success:
        print("Email has been sent")
    case .failure(let error):
        print("Email has not been sent: \(error)")
    }  
}

Also you can send emails directly via application class.

app.smtp.send(email).map { result in
    ...
}

Using SMPT client (async/await)

You have to set macOS 12 as a target in Package.swift file (and tool version 5.5).

    platforms: [
        .macOS(.v12)
    ],

Then you can use async/await alternatives of SMTP methods.

let email = try! Email(from: EmailAddress(address: "[email protected]", name: "John Doe"),
                  to: [EmailAddress(address: "[email protected]", name: "Ben Doe")],
                  subject: "The subject (text)",
                  body: "This is email body.")

try await request.smtp.send(email)

Also you can send emails directly via application class.

try await app.smtp.send(email)

Troubleshoots

You can use logHandler to handle and print all messages send/retrieved from email server.

request.smtp.send(email) { message in
    print(message)
}.map { result in
    ...
}

Developing

After cloning the repository you can open it in Xcode.

$ git clone https://github.com/Mikroservices/Smtp.git
$ cd Smtp
$ open Package.swift

You can build and run tests directly in Xcode.

Testing

Unit (integration) tests requires correct email credentials. Credentials are not check-in to the repository.
If you want to run unit tests you have to use your mailtrap account and/or other email provider credentials.

All you need to do is replacing the configuration section in Tests/SmtpTests/SmtpTests.swift file.

License

This project is licensed under the terms of the MIT license.