Mailgun

Discord Platforms Swift 5.2 Vapor 4

Mailgun 是一个 Vapor 4 服务,用于一个流行的 电子邮件发送 API

注意:Vapor3 版本可在 vapor3 分支和 3.0.0 标签中找到

安装

Mailgun 可以通过 Swift Package Manager 安装

.package(url: "https://github.com/vapor-community/mailgun.git", from: "5.0.0")

.target(name: "App", dependencies: [
    .product(name: "Vapor", package: "vapor"),
    .product(name: "Mailgun", package: "mailgun")
])

使用

在此 注册 并设置一个 Mailgun 帐户

请确保您获得 API 密钥并注册一个自定义域名

配置

configure.swift

import Mailgun

// Called before your application initializes.
func configure(_ app: Application) throws {
    /// case 1
    /// put into your environment variables the following keys:
    /// MAILGUN_API_KEY=...
    app.mailgun.configuration = .environment

    /// case 2
    /// manually
    app.mailgun.configuration = .init(apiKey: "<api key>")
}

注意:如果您的私有 API 密钥以 key- 开头,请务必包含它

声明您的所有域名

extension MailgunDomain {
    static var myApp1: MailgunDomain { .init("mg.myapp1.com", .us) }
    static var myApp2: MailgunDomain { .init("mg.myapp2.com", .eu) }
    static var myApp3: MailgunDomain { .init("mg.myapp3.com", .us) }
    static var myApp4: MailgunDomain { .init("mg.myapp4.com", .eu) }
}

configure.swift 中设置默认域名

app.mailgun.defaultDomain = .myApp1

使用

MailgunApplicationRequest 上均可用

// call it without arguments to use default domain
app.mailgun().send(...)
req.mailgun().send(...)

// or call it with domain
app.mailgun(.myApp1).send(...)
req.mailgun(.myApp1).send(...)

configure.swift

import Mailgun

// Called before your application initializes.
func configure(_ app: Application) throws {
    /// configure mailgun

    /// then you're ready to use it
    app.mailgun(.myApp1).send(...).whenSuccess { response in
        print("just sent: \(response)")
    }
}

💡 注意:以下所有示例都将使用 Request,但您可以像上面的示例一样使用 Application

routes.swift

无附件
import Mailgun

func routes(_ app: Application) throws {
    app.post("mail") { req -> EventLoopFuture<ClientResponse> in
        let message = MailgunMessage(
            from: "postmaster@example.com",
            to: "example@gmail.com",
            subject: "Newsletter",
            text: "This is a newsletter",
            html: "<h1>This is a newsletter</h1>"
        )
        return req.mailgun().send(message)
    }
}
带附件
import Mailgun

func routes(_ app: Application) throws {
    app.post("mail") { req -> EventLoopFuture<ClientResponse> in
        let fm = FileManager.default
        guard let attachmentData = fm.contents(atPath: "/tmp/test.pdf") else {
          throw Abort(.internalServerError)
        }
        let bytes: [UInt8] = Array(attachmentData)
        var bytesBuffer = ByteBufferAllocator().buffer(capacity: bytes.count)
        bytesBuffer.writeBytes(bytes)
        let attachment = File.init(data: bytesBuffer, filename: "test.pdf")
        let message = MailgunMessage(
            from: "postmaster@example.com",
            to: "example@gmail.com",
            subject: "Newsletter",
            text: "This is a newsletter",
            html: "<h1>This is a newsletter</h1>",
            attachments: [attachment]
        )
        return req.mailgun().send(message)
    }
}
带模板(附件可以用相同的方式使用)
import Mailgun

func routes(_ app: Application) throws {
    app.post("mail") { req -> EventLoopFuture<ClientResponse> in
        let message = MailgunTemplateMessage(
            from: "postmaster@example.com",
            to: "example@gmail.com",
            subject: "Newsletter",
            template: "my-template",
            templateData: ["foo": "bar"]
        )
        return req.mailgun().send(message)
    }
}
通过 Leaf 设置内容

使用 Vapor Leaf,您可以轻松设置您的 HTML 内容。

首先在 Resources/Views/Emails/my-email.leaf 中设置一个 leaf 文件

<html>
    <body>
        <p>Hi #(name)</p>
    </body>
</html>

有了这个,您可以在发送邮件时,使用 Swift 代码中的变量更改 #(name)

import Mailgun

func routes(_ app: Application) throws {
    app.post("mail") { req -> EventLoopFuture<ClientResponse> in
        let content = try req.view().render("Emails/my-email", [
            "name": "Bob"
        ])

        let message = Mailgun.Message(
            from: "postmaster@example.com",
            to: "example@gmail.com",
            subject: "Newsletter",
            text: "",
            html: content
        )

        return req.mailgun().send(message)
    }
}
设置路由
public func configure(_ app: Application) throws {
    // sets up a catch_all forward for the route listed
    let routeSetup = MailgunRouteSetup(forwardURL: "http://example.com/mailgun/all", description: "A route for all emails")
    app.mailgun().setup(forwarding: routeSetup).whenSuccess { response in
        print(response)
    }
}
处理路由
import Mailgun

func routes(_ app: Application) throws {
    let mailgunGroup = app.grouped("mailgun")
    mailgunGroup.post("all") { req -> String in
        do {
            let incomingMail = try req.content.decode(MailgunIncomingMessage.self)
            print("incomingMail: (incomingMail)")
            return "Hello"
        } catch {
            throw Abort(.internalServerError, reason: "Could not decode incoming message")
        }
    }
}
创建模板
import Mailgun

func routes(_ app: Application) throws {
    let mailgunGroup = app.grouped("mailgun")
    mailgunGroup.post("template") { req -> EventLoopFuture<ClientResponse> in
        let template = MailgunTemplate(name: "my-template", description: "api created :)", template: "<h1>Hello {{ name }}</h1>")
        return req.mailgun().createTemplate(template)
    }
}