diff --git a/Package.swift b/Package.swift index 6e00f3a..d8fb0be 100644 --- a/Package.swift +++ b/Package.swift @@ -11,12 +11,14 @@ let package = Package( ], dependencies: [ .package(url: "https://github.com/vapor/vapor.git", from: "4.0.0"), - .package(url: "https://github.com/vapor-community/sendgrid-kit.git", from: "1.0.0"), + .package(url: "https://github.com/vapor-community/sendgrid-kit.git", .branch("vapor-email")), + .package(url: "https://github.com/vapor/email.git", .branch("master")) ], targets: [ .target(name: "SendGrid", dependencies: [ .product(name: "Vapor", package: "vapor"), .product(name: "SendGridKit", package: "sendgrid-kit"), + .product(name: "Email", package: "email"), ]), .testTarget(name: "SendGridTests", dependencies: ["SendGrid"]) ] diff --git a/Sources/SendGrid/Application+SendGrid.swift b/Sources/SendGrid/Application+SendGrid.swift deleted file mode 100644 index ec61dc6..0000000 --- a/Sources/SendGrid/Application+SendGrid.swift +++ /dev/null @@ -1,42 +0,0 @@ -import Vapor -import SendGridKit - -extension Application { - public struct Sendgrid { - private final class Storage { - let apiKey: String - - init(apiKey: String) { - self.apiKey = apiKey - } - } - - private struct Key: StorageKey { - typealias Value = Storage - } - - private var storage: Storage { - if self.application.storage[Key.self] == nil { - self.initialize() - } - return self.application.storage[Key.self]! - } - - public func initialize() { - guard let apiKey = Environment.process.SENDGRID_API_KEY else { - fatalError("No sendgrid API key provided") - } - - self.application.storage[Key.self] = .init(apiKey: apiKey) - } - - fileprivate let application: Application - - public var client: SendGridClient { - .init(httpClient: self.application.http.client.shared, apiKey: self.storage.apiKey) - } - } - - public var sendgrid: Sendgrid { .init(application: self) } -} - diff --git a/Sources/SendGrid/Emails+SendGrid.swift b/Sources/SendGrid/Emails+SendGrid.swift new file mode 100644 index 0000000..06a6d1c --- /dev/null +++ b/Sources/SendGrid/Emails+SendGrid.swift @@ -0,0 +1,54 @@ +import Vapor +import SendGridKit +import Email + +extension Application.Emails.Provider { + static func sendgrid(apiKey: String) -> Self { + .init { app in + app.emails.use { + SendGridClient(httpClient: $0.http.client.shared, eventLoop: $0.eventLoopGroup.next(), apiKey: apiKey) + } + } + } +} + + +//extension Application { +// public struct Sendgrid { +// private final class Storage { +// let apiKey: String +// +// init(apiKey: String) { +// self.apiKey = apiKey +// } +// } +// +// private struct Key: StorageKey { +// typealias Value = Storage +// } +// +// private var storage: Storage { +// if self.application.storage[Key.self] == nil { +// self.initialize() +// } +// return self.application.storage[Key.self]! +// } +// +// public func initialize() { +// guard let apiKey = Environment.process.SENDGRID_API_KEY else { +// fatalError("No sendgrid API key provided") +// } +// +// self.application.storage[Key.self] = .init(apiKey: apiKey) +// } +// +// fileprivate let application: Application +// +// public var client: SendGridClient { +// .init(httpClient: self.application.http.client.shared, apiKey: self.storage.apiKey) +// } +// } +// +// public var sendgrid: Sendgrid { .init(application: self) } +//} + diff --git a/Sources/SendGrid/Sendgrid+Email.swift b/Sources/SendGrid/Sendgrid+Email.swift new file mode 100644 index 0000000..661990f --- /dev/null +++ b/Sources/SendGrid/Sendgrid+Email.swift @@ -0,0 +1,64 @@ +import Vapor +import Email +import SendGridKit + +extension SendGridClient: EmailClient { + public func send(_ emails: [VaporEmail]) -> EventLoopFuture { + self.send(emails: emails.map { convert($0) }) + } + + public func send(_ email: VaporEmail) -> EventLoopFuture { + return self.send(email: convert(email)) + } + + private func convert(_ email: VaporEmail) -> SendGridEmail { + let personalization = Personalization( + to: email.to.sendgrid(), + cc: email.cc?.sendgrid(), + bcc: email.bcc?.sendgrid(), + subject: email.subject + ) + + var content = [[ + "type": "text/plain", + "value": email.text + ]] + + if let html = email.html { + content.append([ + "type": "text/html", + "value": html + ]) + } + + var sendgridEmail = SendGridEmail( + personalizations: [personalization], + from: .init(email: email.from.email, name: email.from.name), + subject: email.subject, + content: content, + attachments: nil + ) + + if let replyTo = email.replyTo { + sendgridEmail.replyTo = .init(email: replyTo.email, name: replyTo.name) + } + + return sendgridEmail + } + + public func delegating(to eventLoop: EventLoop) -> EmailClient { + return self.hopped(to: eventLoop) + } +} + +extension Array where Element == Email.EmailAddress { + func sendgrid() -> [SendGridKit.EmailAddress]? { + guard !self.isEmpty else { + return nil + } + + return self.map { + SendGridKit.EmailAddress(email: $0.email, name: $0.name) + } + } +}