3

I'm writing some code to send emails with attachments through the Mailgun email service. They give the following example in their API docs using CURL and I need to figure out how to do the same thing in Node.js (preferably using the Request library).

curl -s -k --user api:key-3ax6xnjp29jd6fds4gc373sgvjxteol0 \
    https://api.mailgun.net/v2/samples.mailgun.org/messages \
    -F from='Excited User <me@samples.mailgun.org>' \
    -F to='obukhov.sergey.nickolayevich@yandex.ru' \
    -F cc='sergeyo@profista.com' \
    -F bcc='serobnic@mail.ru' \
    -F subject='Hello' \
    -F text='Testing some Mailgun awesomness!' \
    -F html='\<html\>HTML version of the body\<\html>' \
    -F attachment=@files/cartman.jpg \
    -F attachment=@files/cartman.png

My current code (Coffescript) looks like the following:

r = request(
  url: mailgun_uri
  method: 'POST'
  headers:
    'content-type': 'application/x-www-form-urlencoded'
  body: email
  (error, response, body) ->
    console.log response.statusCode
    console.log body
)
form = r.form()
for attachment in attachments
  form.append('attachment', fs.createReadStream(attachment.path))
Kyle Mathews
  • 3,240
  • 24
  • 22

1 Answers1

6

For the basic authorization part you have to set the right headers and send username and password base64 encoded. See this SO question for more information. You can use the headers option for this.

How to send a POST request with form fields is described in the request docs:

var r = request.post('http://service.com/upload')
var form = r.form()
form.append('from', 'Excited User <me@samples.mailgun.org>') // taken from your code
form.append('my_buffer', new Buffer([1, 2, 3]))
form.append('my_file', fs.createReadStream(path.join(__dirname, 'doodle.png')) // for your cartman files
form.append('remote_file', request('http://google.com/doodle.png'))

There also some existing modules on npm that support mailgun, like

an example for nodemailer would be

var smtpTransport = nodemailer.createTransport("SMTP",{
    service: "Mailgun", // sets automatically host, port and connection security settings
    auth: {
        user: "api",
        pass: "key-3ax6xnjp29jd6fds4gc373sgvjxteol0"
    }
});

var mailOptions = {
  from: "me@tr.ee",
  to: "me@tr.ee",
  subject: "Hello world!",
  text: "Plaintext body",
  attachments: [
    {   // file on disk as an attachment
        fileName: "text3.txt",
        filePath: "/path/to/file.txt" // stream this file
    },
    {   // stream as an attachment
        fileName: "text4.txt",
        streamSource: fs.createReadStream("file.txt")
    },
  ]
}

transport.sendMail(mailOptions, function(err, res) {
  if (err) console.log(err);
  console.log('done');
});

Haven't tested it because I don't have a mailgun account but it should work.

Community
  • 1
  • 1
zemirco
  • 16,171
  • 8
  • 62
  • 96
  • I followed the above pattern for appending the files and Mailgun sent back an error saying the "'from' parameter is missing" which made me assume I'm doing something wrong. node-mailgun doesn't support attachments (or html emails for that matter...) I hadn't thought about using nodemailer. It does support attachments and Mailgun although through the SMTP gateway, which is fine, but I'm still curious how – Kyle Mathews Dec 06 '12 at 18:53
  • did you add your authorization params like `url = "https://api:key-3ax6xnjp29jd6fds4gc373sgvjxteol0@api.mailgun.net/v2/samples.mailgun.org/log";` to the `mailgun_uri`? I added some code for nodemailer in my answer. – zemirco Dec 06 '12 at 21:24
  • Yeah -- I didn't show all my code. I'll give nodemailer a whirl later. – Kyle Mathews Dec 07 '12 at 01:36