Problem
I would like to use the MailGun service to send emails from a pure Swift app.
Research So Far
As I understa
requests.post sends an HTTP POST request, encoding key/value pairs as application/x-www-form-urlencoded
. You need to do the same.
application/x-www-form-urlencoded
as per How to escape the HTTP params in SwiftSwift 3 answer:
func test() {
let session = URLSession.shared
var request = URLRequest(url: URL(string: "https://api.mailgun.net/v3/sandbox(Personal info).mailgun.org/messages")!)
request.httpMethod = "POST"
let data = "from: Excited User <(Personal info)>&to: [bar@example.com,(Personal info)]&subject:Hello&text:Testinggsome Mailgun awesomness!"
request.httpBody = data.data(using: .ascii)
request.setValue("key-(Personal info)", forHTTPHeaderField: "api")
let task = session.dataTask(with: request, completionHandler: {(data, response, error) in
if let error = error {
print(error)
}
if let response = response {
print("url = \(response.url!)")
print("response = \(response)")
let httpResponse = response as! HTTPURLResponse
print("response code = \(httpResponse.statusCode)")
}
})
task.resume()
}
I spent hours trying to get the selected answer working, but to no avail.
Although I was finally able to get this working properly with a large HTTP response. I put the full path into Keys.plist so that I can upload my code to github and broke out some of the arguments into variables so I can have them programmatically set later down the road.
// Email the FBO with desired information
// Parse our Keys.plist so we can use our path
var keys: NSDictionary?
if let path = NSBundle.mainBundle().pathForResource("Keys", ofType: "plist") {
keys = NSDictionary(contentsOfFile: path)
}
if let dict = keys {
// variablize our https path with API key, recipient and message text
let mailgunAPIPath = dict["mailgunAPIPath"] as? String
let emailRecipient = "bar@foo.com"
let emailMessage = "Testing%20email%20sender%20variables"
// Create a session and fill it with our request
let session = NSURLSession.sharedSession()
let request = NSMutableURLRequest(URL: NSURL(string: mailgunAPIPath! + "from=FBOGo%20Reservation%20%3Cscheduler@<my domain>.com%3E&to=reservations@<my domain>.com&to=\(emailRecipient)&subject=A%20New%20Reservation%21&text=\(emailMessage)")!)
// POST and report back with any errors and response codes
request.HTTPMethod = "POST"
let task = session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
if let error = error {
print(error)
}
if let response = response {
print("url = \(response.URL!)")
print("response = \(response)")
let httpResponse = response as! NSHTTPURLResponse
print("response code = \(httpResponse.statusCode)")
}
})
task.resume()
}
The Mailgun Path is in Keys.plist as a string called mailgunAPIPath with the value:
https://API:key-<my key>@api.mailgun.net/v3/<my domain>.com/messages?
Hope this offers a solution to anyone else having issues with MailGun and wanting to avoid a 3rd party solution!
In python, the auth
is being passed in the header.
You have to do a http post request, passing both the header and the body.
This is a working code:
func test() {
let session = NSURLSession.sharedSession()
let request = NSMutableURLRequest(URL: NSURL(string: "https://api.mailgun.net/v3/sandbox(Personal info).mailgun.org/messages")!)
request.HTTPMethod = "POST"
let data = "from: Excited User <(Personal info)>&to: [bar@example.com,(Personal info)]&subject:Hello&text:Testinggsome Mailgun awesomness!"
request.HTTPBody = data.dataUsingEncoding(NSASCIIStringEncoding)
request.setValue("key-(Personal info)", forHTTPHeaderField: "api")
let task = session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
if let error = error {
print(error)
}
if let response = response {
print("url = \(response.URL!)")
print("response = \(response)")
let httpResponse = response as! NSHTTPURLResponse
print("response code = \(httpResponse.statusCode)")
}
})
task.resume()
}