mailchimp
Version:
A node.js wrapper for the MailChimp API.
114 lines (92 loc) • 3.64 kB
JavaScript
var http = require('http'),
util = require('util'),
url = require('url'),
qs = require('qs'),
EventEmitter = require('events').EventEmitter;
/**
* A server that listens for POST requests from MailChimp which are issued on
* special events as specified on their Webhook page. Please refer to that page
* on how to set everything up.
*
* @see http://www.mailchimp.com/api/webhooks/
*
* If the server receives a valid request from MailChimp the received data is
* wrapped in a nice object and an event is emitted which you can listen for
* in your application and then take further action.
*
* Available options are:
* - port Port the server is going to listen on. Defaults to 8100.
* - secret Secret key as suggested on the Webhook page which is then simply
* added as a pathname to the Webhook URL in your MailChimp account
* and checked for here. Nothing too fancy but a small enhancement to
* security. Leave empty (default setting) if you don't want to use a
* secret key. Example: If you set the secret to 'ChimpSecret' you
* would enter the Webhook URL http://www.yourdomain.com/ChimpSecret
* in the MailChimp Webhook settings.
* - secure Takes credentials generated by the crypto module and enables HTTPS
* support for the server when present.
*
* @param options Configuration options
* @return Instance of {@link MailChimpWebhook}
*/
function MailChimpWebhook (options) {
var self = this;
if (!options)
options = {};
EventEmitter.call(this);
this.httpPort = options.port || 8100;
this.secret = options.secret || '';
this.secure = options.secure || false;
this.allowedTypes = [
'subscribe',
'unsubscribe',
'profile',
'upemail',
'cleaned',
'campaign'
];
var server = http.createServer(function (request, response) {
var requestBody = '';
var requestUrl = url.parse(request.url);
if (self.secret !== '' && requestUrl.pathname !== '/'+self.secret) {
self.emit('error', 'Received a request with an invalid secret key.');
response.writeHead(500, { 'Content-Type' : 'text/plain' });
response.end();
return;
}
// Say "hi" to the webhook validator, the only request not sent via POST
if (request.headers['user-agent'] === 'MailChimp.com WebHook Validator') {
response.writeHead(200, { 'Content-Type' : 'text/plain' });
response.end();
return;
}
if (request.method != 'POST') {
self.emit('error', 'Received something other than a POST request.');
response.writeHead(500, { 'Content-Type' : 'text/plain' });
response.end();
return;
}
request.on('data', function (chunk) {
requestBody += chunk;
});
request.on('end', function () {
var payload = qs.parse(requestBody);
var meta = { type : payload.type, fired_at : payload.fired_at };
var data = payload.data;
if (meta.type && ~self.allowedTypes.indexOf(meta.type)) {
self.emit(payload.type, data, meta);
response.writeHead(200, { 'Content-Type' : 'text/plain' });
response.end();
} else {
self.emit('error', 'Received a request with an unknown type of payload.');
response.writeHead(500, { 'Content-Type' : 'text/plain' });
response.end();
}
});
});
if (this.secure)
server.setSecure(this.secure);
server.listen(this.httpPort);
}
util.inherits(MailChimpWebhook, EventEmitter);
module.exports = MailChimpWebhook;