Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Uses /messages.mime endpoint #42

Open
gabegorelick opened this issue Aug 5, 2016 · 4 comments
Open

Uses /messages.mime endpoint #42

gabegorelick opened this issue Aug 5, 2016 · 4 comments

Comments

@gabegorelick
Copy link

gabegorelick commented Aug 5, 2016

It seems like a more robust approach would be to use Mailgun's /messages.mime endpoint to send raw emails. This is what the nodemailer-ses-transport does, for example: nodemailer already gives you the mime-formatted email, and all you need to do is pipe that to Mailgun.

@gabegorelick gabegorelick changed the title Uses /message.mime endpoint Uses /messages.mime endpoint Aug 5, 2016
@orliesaurus
Copy link
Owner

Would you like to send a pull request with that feature please? It sounds like a nice thing to have

@duanefields
Copy link

duanefields commented Feb 23, 2018

here's an implementation of just that (coffeescript)

axios = require 'axios'
FormData = require 'form-data'

module.exports = class MailgunMIMETransport
  name: "MailgunMIMETransport"
  version: "1.0.0"

  constructor: (@options={}) ->

  send: (mail, callback) =>
    mailStream = mail.message.createReadStream()
    this.readStream mailStream, (err, raw) =>
      if err?
        return typeof callback is 'function' and callback(err)
      this.handleMessage mail, raw, callback

  readStream: (mailStream, callback) ->
    chunks = []
    totalLength = 0

    mailStream.on 'data', (chunk)  ->
      chunks.push chunk
      totalLength += chunk.length

    mailStream.on 'end', ->
      callback null, Buffer.concat(chunks, totalLength).toString()

  handleMessage: (mail, raw, callback) ->
    envelope = mail.message.getEnvelope()
    form = new FormData()
    form.append "to", envelope.to.join ','
    form.append "message", raw, 'message.eml'

    requestOptions =
      baseURL: "https://api.mailgun.net/v3/#{@options.domain}"
      headers: form.getHeaders()
      auth:
        username: 'api'
        password: @options.apiKey
    axios.post '/messages.mime', form, requestOptions
    .then (result) ->
      response = result.data
      info =
        envelope: envelope
        response: response.message
        messageId: response.id
      if typeof callback is 'function' then callback(null, info) else info
    .catch (err) ->
      return typeof callback is 'function' and callback(err)

@gabegorelick
Copy link
Author

Here's a JS version:

const nodemailer = require('nodemailer');
const mailgun = require('mailgun-js')();

class MailgunTransport {
    constructor (options) {
        this.name = 'Mailgun';
        this.version = '1.0.0';

        this.mailgun = mailgun(options);
    }

    send (mail, callback) {
        const envelope = mail.data.envelope || mail.message.getEnvelope();
        const stream = mail.message.createReadStream();
        stream.once('error', callback);

        const chunks = [];
        let chunkLength = 0;
        stream.on('readable', () => {
            let chunk;
            while ((chunk = stream.read()) !== null) {
                chunks.push(chunk);
                chunkLength += chunk.length;
            }
        });
        stream.on('end', () => {
            const mimeMessage = Buffer.concat(chunks, chunkLength);
            this.mailgun.messages().sendMime({
                to: envelope.to.join(','), // envelope.to contains the message's To, CC, and BCC
                message: mimeMessage.toString('ascii') // nodemailer encodes with quoted-printable, so it's already ASCII
            }, (err, body) => {
                if (err) {
                    return callback(err);
                }

                return callback(null, {
                    envelope: {
                        from: envelope.from,
                        to: envelope.to
                    },
                    response: body,
                    messageId: body.id
                });
            });
        });
    }
}

Happy to throw up a PR, but this would potentially be a breaking change.

@orliesaurus
Copy link
Owner

Mmmh I don't know about this one ultimately - I don't want to upset all the people - unless it was properly documented and unit tests are added, it'll have to wait :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants