From cac2c2fcd67af20d4b2500defcab2ad65fdc0248 Mon Sep 17 00:00:00 2001 From: Ondrej Rafaj Date: Sun, 1 Apr 2018 00:53:35 +0100 Subject: [PATCH 1/2] adding send grid --- Package.resolved | 45 +++++++++++++++---------- Package.swift | 4 ++- Sources/MailCore/MailCore.swift | 14 +++++++- Tests/MailCoreTests/MailCoreTests.swift | 1 - 4 files changed, 43 insertions(+), 21 deletions(-) diff --git a/Package.resolved b/Package.resolved index 6100c11..e15987b 100644 --- a/Package.resolved +++ b/Package.resolved @@ -6,8 +6,8 @@ "repositoryURL": "https://github.com/vapor/console.git", "state": { "branch": null, - "revision": "e37e02c86ded07678ebf22517fdb8d070c5447f5", - "version": "3.0.0-rc.2.1" + "revision": "273cf2ed1f4daba88a452494c342020171d8c7b8", + "version": "3.0.0-rc.2.2" } }, { @@ -15,8 +15,8 @@ "repositoryURL": "https://github.com/vapor/core.git", "state": { "branch": null, - "revision": "9238f270cdd40349fd1e047dab21f4dea1999ec6", - "version": "3.0.0-rc.2.3" + "revision": "225aff2b69049f2a4d9a4aae71d27ba7fb083032", + "version": "3.0.1" } }, { @@ -33,8 +33,8 @@ "repositoryURL": "https://github.com/vapor/database-kit.git", "state": { "branch": null, - "revision": "ce82abe73051388dcadbf34873b29a75df58cabc", - "version": "1.0.0-rc.2.1.1" + "revision": "9e77b5b95e3f1f141abdf75d6123f591971162cd", + "version": "1.0.0-rc.2.2.1" } }, { @@ -42,8 +42,8 @@ "repositoryURL": "https://github.com/vapor/engine.git", "state": { "branch": null, - "revision": "cd6756a971caba5f14a861b446fe682a15d2ae28", - "version": "3.0.0-rc.2.1" + "revision": "4846ea9abeb04863f82f618ee8cb22650a82ae3c", + "version": "3.0.0-rc.2.1.1" } }, { @@ -55,6 +55,15 @@ "version": "3.0.0-rc.2" } }, + { + "package": "SendGrid", + "repositoryURL": "https://github.com/vapor-community/sendgrid-provider.git", + "state": { + "branch": null, + "revision": "9a05b9067db51641c005b8e989d940028de5d1b9", + "version": "3.0.0-rc1.1" + } + }, { "package": "Service", "repositoryURL": "https://github.com/vapor/service.git", @@ -78,8 +87,8 @@ "repositoryURL": "https://github.com/apple/swift-nio-ssl.git", "state": { "branch": null, - "revision": "85a55f91bf80afa96889426962f0e0369fae9187", - "version": "1.0.0" + "revision": "ea006b6368dbd9dbfd297deb6ddb3f070b72d043", + "version": "1.0.1" } }, { @@ -105,8 +114,8 @@ "repositoryURL": "https://github.com/vapor/template-kit.git", "state": { "branch": null, - "revision": "ef940383716d05ac6e1b0dcb0ba672c7c0f8a718", - "version": "1.0.0-rc.2.0.1" + "revision": "61ed3d3b0df4c181d6b88e06b418f425978ac2af", + "version": "1.0.0-rc.2.0.3" } }, { @@ -114,8 +123,8 @@ "repositoryURL": "https://github.com/vapor/validation.git", "state": { "branch": null, - "revision": "aa12fbde809392ef39ddf046252c94a9fd67c420", - "version": "2.0.0-rc.2.1" + "revision": "1ce87fc2d18a8f15a491805825063c8db493a51e", + "version": "2.0.0-rc.2.1.1" } }, { @@ -123,8 +132,8 @@ "repositoryURL": "https://github.com/vapor/vapor.git", "state": { "branch": null, - "revision": "72424e773c26eaece83819d1a067ae77b4f68cc6", - "version": "3.0.0-rc.2.2" + "revision": "5e59691ef575597aa640da76ccb9fc5ee638f2c1", + "version": "3.0.0-rc.2.2.1" } }, { @@ -132,8 +141,8 @@ "repositoryURL": "https://github.com/twof/VaporMailgunService.git", "state": { "branch": null, - "revision": "018685b24cc9e31a02ca549c491bc6978e473648", - "version": "0.4.0" + "revision": "e661e24415f3600755ba62e8e549c126a08aec6e", + "version": "0.4.1" } }, { diff --git a/Package.swift b/Package.swift index 79cf2ac..3504c3e 100644 --- a/Package.swift +++ b/Package.swift @@ -10,12 +10,14 @@ let package = Package( dependencies: [ .package(url: "https://github.com/vapor/vapor.git", from: "3.0.0-rc.2"), .package(url: "https://github.com/twof/VaporMailgunService.git", from: "0.4.0"), + .package(url: "https://github.com/vapor-community/sendgrid-provider.git", from: "3.0.0-rc"), .package(url: "https://github.com/LiveUI/VaporTestTools.git", .branch("master")) ], targets: [ .target(name: "MailCore", dependencies: [ "Vapor", - "Mailgun" + "Mailgun", + "SendGrid" ] ), .target(name: "MailCoreTestTools", dependencies: [ diff --git a/Sources/MailCore/MailCore.swift b/Sources/MailCore/MailCore.swift index 8a69834..09dc7de 100644 --- a/Sources/MailCore/MailCore.swift +++ b/Sources/MailCore/MailCore.swift @@ -8,6 +8,7 @@ import Foundation import Vapor import Mailgun +import SendGrid public protocol MailerService: Service { @@ -42,6 +43,7 @@ public class Mailer: MailerService { public enum Config { case none case mailgun(key: String, domain: String) + case sendGrid(key: String) } let config: Config @@ -49,12 +51,16 @@ public class Mailer: MailerService { // MARK: Initialization - @discardableResult public init(config: Config, registerOn services: inout Services) { + @discardableResult public init(config: Config, registerOn services: inout Services) throws { self.config = config switch config { case .mailgun(let key, let domain): services.register(Mailgun(apiKey: key, domain: domain), as: Mailgun.self) + case .sendGrid(key: let key): + let config = SendGridConfig(apiKey: key) + services.register(config) + try services.register(SendGridProvider()) default: break } @@ -71,6 +77,12 @@ public class Mailer: MailerService { return try mailgunClient.send(message.asMailgunContent(), on: req).map(to: Mailer.Result.self) { _ in return Mailer.Result.success } + case .sendGrid(_): + let email = SendGridEmail(from: ) + let sendGridClient = try req.make(SendGridClient.self) + try sendGridClient.send([email], on: req.eventLoop).map(on: Mailer.Result.self) { _ in + return Mailer.Result.success + } default: return req.eventLoop.newSucceededFuture(result: Mailer.Result.serviceNotConfigured) } diff --git a/Tests/MailCoreTests/MailCoreTests.swift b/Tests/MailCoreTests/MailCoreTests.swift index a53a6b6..62edbe9 100644 --- a/Tests/MailCoreTests/MailCoreTests.swift +++ b/Tests/MailCoreTests/MailCoreTests.swift @@ -1,4 +1,3 @@ -import App import Dispatch import XCTest From b83aa9e23297750d425e641e28727e8365be73eb Mon Sep 17 00:00:00 2001 From: Ondrej Rafaj Date: Wed, 11 Apr 2018 00:21:41 +0100 Subject: [PATCH 2/2] readme, scripts and sendgrid --- Other/logo.png | Bin 0 -> 61337 bytes Package.resolved | 34 ++++---- Package.swift | 2 +- README.md | 79 +++++++++++++++++- .../Extensions/Message+SendGrid.swift | 34 ++++++++ Sources/MailCore/MailCore.swift | 14 +++- scripts/update.sh | 5 +- scripts/upgrade.sh | 6 ++ 8 files changed, 148 insertions(+), 26 deletions(-) create mode 100755 Other/logo.png create mode 100644 Sources/MailCore/Extensions/Message+SendGrid.swift create mode 100755 scripts/upgrade.sh diff --git a/Other/logo.png b/Other/logo.png new file mode 100755 index 0000000000000000000000000000000000000000..28034321aafce684701aa352c020ebe249ad1b32 GIT binary patch literal 61337 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 I did it again

") +return try req.mail.send(mail).flatMap(to: Response.self) { mailResult in + print(mailResult) + // ... Return your response for example +} +``` + +## Support + +Join our [Slack](http://bit.ly/2B0dEyt), channel #help-boost to ... well, get help :) + +## Boost AppStore + +Core package for [Boost](http://www.boostappstore.com), a completely open source enterprise AppStore written in Swift! +- Website: http://www.boostappstore.com +- Github: https://github.com/LiveUI/Boost + +## Other core packages + +* [BoostCore](https://github.com/LiveUI/BoostCore/) - AppStore core module +* [ApiCore](https://github.com/LiveUI/ApiCore/) - Base user & team management including forgotten passwords, etc ... +* [DBCore](https://github.com/LiveUI/DbCore/) - Set of tools for work with PostgreSQL database +* [VaporTestTools](https://github.com/LiveUI/VaporTestTools) - Test tools and helpers for Vapor 3 + +## Code contributions + +We love PR’s, we can’t get enough of them ... so if you have an interesting improvement, bug-fix or a new feature please don’t hesitate to get in touch. If you are not sure about something before you start the development you can always contact our dev and product team through our Slack. + +## Author + +Ondrej Rafaj (@rafiki270 on [Github](https://github.com/rafiki270), [Twitter](https://twitter.com/rafiki270), [LiveUI Slack](http://bit.ly/2B0dEyt) and [Vapor Slack](https://vapor.team/)) + +## License + +MIT license, please see LICENSE file for more details. + diff --git a/Sources/MailCore/Extensions/Message+SendGrid.swift b/Sources/MailCore/Extensions/Message+SendGrid.swift new file mode 100644 index 0000000..3cb4a05 --- /dev/null +++ b/Sources/MailCore/Extensions/Message+SendGrid.swift @@ -0,0 +1,34 @@ +// +// Message+SendGrid.swift +// MailCore +// +// Created by Ondrej Rafaj on 11/04/2018. +// + +import Foundation +import Vapor +import SendGrid + + +extension Mailer.Message { + + func asSendGridContent() -> SendGridEmail { + var content = [ + [ + "type": "text/plain", + "value": text + ] + ] + if let html = html { + content.append( + [ + "type": "text/html", + "value": html + ] + ) + } + let message = SendGridEmail(from: EmailAddress(email: from), replyTo: EmailAddress(email: to), subject: subject, content: content) + return message + } + +} diff --git a/Sources/MailCore/MailCore.swift b/Sources/MailCore/MailCore.swift index 09dc7de..3394d26 100644 --- a/Sources/MailCore/MailCore.swift +++ b/Sources/MailCore/MailCore.swift @@ -76,13 +76,19 @@ public class Mailer: MailerService { let mailgunClient = try req.make(Mailgun.self) return try mailgunClient.send(message.asMailgunContent(), on: req).map(to: Mailer.Result.self) { _ in return Mailer.Result.success - } + }.catchMap({ error in + return Mailer.Result.failure(error: error) + } + ) case .sendGrid(_): - let email = SendGridEmail(from: ) + let email = message.asSendGridContent() let sendGridClient = try req.make(SendGridClient.self) - try sendGridClient.send([email], on: req.eventLoop).map(on: Mailer.Result.self) { _ in + return try sendGridClient.send([email], on: req.eventLoop).map(to: Mailer.Result.self) { _ in return Mailer.Result.success - } + }.catchMap({ error in + return Mailer.Result.failure(error: error) + } + ) default: return req.eventLoop.newSucceededFuture(result: Mailer.Result.serviceNotConfigured) } diff --git a/scripts/update.sh b/scripts/update.sh index bd70fb8..c254080 100755 --- a/scripts/update.sh +++ b/scripts/update.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash rm -rf .build -vapor clean --verbose -y -rm Package.resolved -vapor xcode --verbose -y +vapor clean -y --verbose +vapor xcode -n --verbose diff --git a/scripts/upgrade.sh b/scripts/upgrade.sh new file mode 100755 index 0000000..6a98522 --- /dev/null +++ b/scripts/upgrade.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +rm -rf .build +vapor clean -y --verbose +rm Package.resolved +vapor xcode -n --verbose