diff --git a/Other/logo.png b/Other/logo.png new file mode 100755 index 0000000..2803432 Binary files /dev/null and b/Other/logo.png differ diff --git a/Package.resolved b/Package.resolved index 6100c11..9db3624 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": "038e30ec9004fb1915d14d964a3facc1ec5c80f4", + "version": "3.0.0" } }, { @@ -15,8 +15,8 @@ "repositoryURL": "https://github.com/vapor/core.git", "state": { "branch": null, - "revision": "9238f270cdd40349fd1e047dab21f4dea1999ec6", - "version": "3.0.0-rc.2.3" + "revision": "2ad95efabedc228ddbadee1974f6bbaac6c89abd", + "version": "3.0.3" } }, { @@ -24,8 +24,8 @@ "repositoryURL": "https://github.com/vapor/crypto.git", "state": { "branch": null, - "revision": "4c7acb4fbf1720682275f0ef543474c951d84a09", - "version": "3.0.0-rc.3" + "revision": "e77aa181580b466fb26865918b62973d9fbfaed6", + "version": "3.0.0" } }, { @@ -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": "e594e658cc001e04b8d4ad13881d8714c510f94f", + "version": "1.0.0-rc.2.2.2" } }, { @@ -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,13 +55,22 @@ "version": "3.0.0-rc.2" } }, + { + "package": "SendGrid", + "repositoryURL": "https://github.com/vapor-community/sendgrid-provider.git", + "state": { + "branch": null, + "revision": "400914c4c54b34240cf7c99ce0464b1771f969c2", + "version": "3.0.1" + } + }, { "package": "Service", "repositoryURL": "https://github.com/vapor/service.git", "state": { "branch": null, - "revision": "02205a16a3f4714a08836529f5a868c2ce256719", - "version": "1.0.0-rc.2.2" + "revision": "281a70b69783891900be31a9e70051b6fe19e146", + "version": "1.0.0" } }, { @@ -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": "497b987a79291c3743fe4ba6f17eadcdf20c1728", + "version": "1.0.0" } }, { @@ -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": "c045b8d02e6a135f055e879a9fa789026a0b4e9d", + "version": "3.0.0-rc.2.2.4" } }, { @@ -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" } }, { @@ -141,7 +150,7 @@ "repositoryURL": "https://github.com/LiveUI/VaporTestTools.git", "state": { "branch": "master", - "revision": "723ab62c1f8fccb0f246e02ebc854edd4eab0a60", + "revision": "dc93505814efdbd9e97ce2844bb534e8adf1436e", "version": null } } diff --git a/Package.swift b/Package.swift index 79cf2ac..571dc73 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.1"), .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/README.md b/README.md index a8bb7b1..3e32c19 100644 --- a/README.md +++ b/README.md @@ -1 +1,78 @@ -# MailCore \ No newline at end of file +![Vapor 3 test tools](https://github.com/LiveUI/VaporTestTools/raw/master/Other/logo.png) + +## + +[![Slack](https://img.shields.io/badge/join-slack-745EAF.svg?style=flat)](http://bit.ly/2B0dEyt) +[![Jenkins](https://ci.liveui.io/job/LiveUI/job/MailCore/job/master/badge/icon)](https://ci.liveui.io/job/LiveUI/job/MailCore/) +[![Platforms](https://img.shields.io/badge/platforms-macOS%2010.13%20|%20Ubuntu%2016.04%20LTS-ff0000.svg?style=flat)](https://github.com/LiveUI/Boost) +[![Swift Package Manager](https://img.shields.io/badge/SPM-compatible-4BC51D.svg?style=flat)](https://swift.org/package-manager/) +[![Swift 4](https://img.shields.io/badge/swift-4.0-orange.svg?style=flat)](http://swift.org) +[![Vapor 3](https://img.shields.io/badge/vapor-3.0-blue.svg?style=flat)](https://vapor.codes) + + +Mailing wrapper for multiple mailing services like MailGun, SendGrig or SMTP + +## Features + +- [x] MailGun +- [ ] SendGrid +- [ ] SMTP + +## Install + +Just add following line package to your `Package.swift` file. + +```swift +.package(url: "https://github.com/LiveUI/MailCore.git", .branch("master")) +``` + +## Use + +Usage is really simple. First register the service in your apps `configure` method: + +```swift +let config = Mailer.Config.mailgun(key: "{mailGunApi}", domain: "{mailGunDomain}") +Mailer(config: config, registerOn: &services) +``` + +`Mailer.Config` is an `enum` and you can choose from any integrated services to be used + +And send an email: + +```swift +let mail = Mailer.Message(from: "admin@liveui.io", to: "bobby.ewing@southfork.com", subject: "Oil spill", text: "Oooops I did it again", html: "

Oooops 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 8a69834..3394d26 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 } @@ -70,7 +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 = message.asSendGridContent() + let sendGridClient = try req.make(SendGridClient.self) + 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/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 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