Setting Up - Adding a route to receive Mandrill emails

Update

I've written a separate node modules for handling inbound mandrill webhooks so as hacking my Ghost code is no longer required

mandrill-webhook-server

Ghost Mandrill Integration

In a previous post I mentioned that Ghost integrates nicely with Madrill for receiving emails. One of Mandrills great features is being able to process incoming emails. This is great because if you are running your own server with a dynamic ip it can be hard to set up email that isn't considered spam. This is because a lot of email systems require reverse ip lookups. However Mandrill does it you can send mails without worrying about it.

Receiving Emails

What about receiving emails. Mandrill has the facility to set up incoming routes. This is limited to then forwarding on received mails to a webhook. According to Wikipedia Webhooks are "user-defined HTTP callbacks". In this case Mandrill calls a post and sends you the details of any emails you have received at the defined address.

Setting up the Webhook

To set up the webhook you need to add a new route to Ghost that can be called by Mandrill and process your emails.There are relatively few code changes required for this:

1) Add route middleware to /core/server/routes

This will add you route to the express router and do whatever it is that you want to do to your email events. In my case I am using Ghosts mailer to send the mails on to my main email.

Using the mailer is pretty simple:

var mailer       = require('../mail');

var email = {        
    to: '[email protected]',
    html : 'email html',
    from : '[email protected]',        
    subject : 'subject' 
};

mailer.send(email).then(function onSuccess(){}, function onError(){});

If you don't have these properties the mailer will throw an error.

One final hack is to update the mailer to use the from address as it defaults to the from address as set in the config.js.

In /server/mail.js (line 79):
In V0.7 this has moved to /server/mail/index.js

GhostMailer.prototype.send = function (message) {
    //...
    message = _.extend(message, {
-       from: self.from()
+       from: message.from || self.from(),
        to: to,
        generateTextFromHTML: true,
        encoding: 'base64'
    });
    //...
};
2) Update /core/server/routes/index.js to include your new route
var api         = require('./api'),
    admin       = require('./admin'),
    frontend    = require('./frontend'),
+   email       = require('./email');

module.exports = {
    apiBaseUri: '/ghost/api/v0.1/',
    api: api,
    admin: admin,
    frontend: frontend,
+   email: email
};

There are two edits in this file

3) Update /core/server/middleware/index.js to call your new router
setupMiddleware = function (blogAppInstance, adminApp) {
    // ...
+   blogApp.use(routes.email());
    // ...
};

I put it in around line 144 seem to remember the order being important

4) Some of the web hook post bodys are quite big so you have to increase the bodyParser limit:
    blogApp.use(bodyParser.urlencoded({extended: true, limit: 1024*1000}));

Around line 131