Проблема

Я хочу использовать службу MailGun для отправки электронных писем из чистого приложения Swift.

Исследования на данный момент

Насколько я понимаю, существует два метода отправки электронного письма через MailGun. Один из них - отправить MailGun электронное письмо, и MailGun перенаправит его (см. Отправить через SMTP ). Насколько я понимаю, это не сработает, поскольку iOS не может автоматически отправлять почту программно и должна использовать методы, требующие вмешательства пользователя. Таким образом, я должен использовать API напрямую. Насколько я понимаю, для этого мне нужно открыть URL-адрес, поэтому я должен использовать некоторую форму NSURLSession согласно этот SO-ответ

Код

MailGun предоставляет документацию для Python, которая выглядит следующим образом:

def send_simple_message():
return requests.post(
    "https://api.mailgun.net/v3/sandbox(Personal info).mailgun.org/messages",
    auth=("api", "key-(Personal info)"),
    data={"from": "Excited User <(Personal info)>",
          "to": ["bar@example.com", "(Personal info)"],
          "subject": "Hello",
          "text": "Testing some Mailgun awesomness!"})

При этом (Личная информация) заменяется ключами / информацией / адресами электронной почты.

Вопрос

Как мне это сделать в Swift?

Благодарность!

3
rocket101 25 Окт 2015 в 04:18

4 ответа

Лучший ответ

В python auth передается в заголовке.

Вам нужно выполнить HTTP-запрос, передавая и заголовок, и тело.

Это рабочий код:

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()
    }
5
William Kinaan 25 Окт 2015 в 02:41

Swift 3 ответ:

    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()
    }
1
HLie 5 Апр 2017 в 03:24

Я часами пытался заставить выбранный ответ работать, но безуспешно.

Хотя я наконец смог заставить это работать должным образом с большим HTTP-ответом. Я поместил полный путь в Keys.plist, чтобы я мог загрузить свой код на github, и разбил некоторые аргументы на переменные, чтобы я мог программно установить их позже в будущем.

// 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()
}

Путь Mailgun находится в Keys.plist в виде строки mailgunAPIPath со значением:

https://API:key-<my key>@api.mailgun.net/v3/<my domain>.com/messages?

Надеюсь, это решение для всех, у кого есть проблемы с MailGun и которые хотят избежать стороннего решения!

1
Rudest Buddhist 3 Окт 2016 в 02:44

requests.post отправляет HTTP-запрос POST, кодируя пары ключ / значение как application/x-www-form-urlencoded. Вам нужно сделать то же самое.

1
Community 23 Май 2017 в 12:10