MailChimp is a pretty awesome service. In a project I was working on, I wanted to create multiple lists for different types of email newsletters. The website I was using was powered by Express and Node.js. Here's a little bit of code to show how to manage subscriptions for multiple lists.
The first part was creating a sever layer to interact with MailChimp. This service provides access to the lists attached to your account. It also allows you to subscribe to different a lists at the same time.
var Q = require('q')
, _ = require('underscore')
, MailChimpAPI = require('mailchimp').MailChimpAPI
, apikey = 'MAIL_CHIMP_API_KEY'
, api
, subscribe
;
api = new MailChimpAPI(apikey, { version : '2.0' });
/**
* Retrieves the lists that are available
*
* @param {function} [next]
* @return {promise}
*/
exports.lists = function(next) {
var deferred = Q.defer();
api.call('lists', 'list', function(err, result) {
if(err) deferred.reject(err);
// result in form
// { total: 2, data: [ ], errors: [ ] }
else deferred.resolve(result.data);
});
return deferred.promise.nodeify(next);
};
/**
* Subscribes an email address to the list
*
* @param {object} opts
* @param {string} opts.id - the list id
* @param {string} opts.email - the email address
* @param {string} opts.fname - the first name
* @param {string} opts.lname - the last name
* @param {function} [next]
* @return {promise}
*/
exports.subscribe = subscribe = function(opts, next) {
var deferred = Q.defer()
, params = {}
;
params = {
id: opts.id,
email: {
email: opts.email
},
merge_vars: {
fname: opts.fname,
lname: opts.lname
},
double_optin: false,
update_existing: true
};
api.call('lists', 'subscribe', params, function(err, result) {
if(err) deferred.reject(err);
else deferred.resolve(result);
});
return deferred.promise.nodeify(next);
};
/**
* Subscribes an email address to the lists
*
* @param {array} opts.ids - the list of ids
* @param {string} opts.email - the email address
* @param {string} opts.fname - the first name
* @param {string} opts.lname - the last name
* @param {function} [next]
* @return {promise}
*/
exports.subscribeMany = function(ids, opts, next) {
var funcs;
funcs = ids.map(function(id) {
var newOpts = _.clone(opts);
newOpts.id = id;
return function() {
return subscribe(newOpts);
};
});
/* jshint es5:false */
/* jshint newcap:false */
return funcs
.reduce(Q.when, Q())
.nodeify(next);
/* jshint newcap:true */
};
With the above service in place, I then created an express controller method that accepts calls from the client side, validates the information, and uses the service to perform the appropriate action (GET or POST).
var mailSvc = require('../mail-service');
/**
* Adds the routes to the Express Application
*
* @param {Express} app
*/
exports.addRoutes = function(app) {
app.post ('/api/mail', subscribe);
};
exports.subscribe = subscribe;
/**
* API endpoint to subscribes the user to the specified lists
* Outputs the corresponding JSON response depending on
* the action taken.
*
* @param {ExpressRequest} req
* @param {ExpressReponse} res
*/
function subscribe(req, res) {
var opts
, verrors
, lists
;
req.assert('lists', 'At least one list must be selected').isArray().arrayHasValue();
req.assert('email', 'Invalid email address').isEmail();
req.assert('firstname', 'Invalid firstname').notEmpty();
req.assert('lastname', 'Invalid lastname').notEmpty();
verrors = req.validationErrors();
if(verrors) {
res.status(422).send(verrors);
return;
}
lists = req.body.lists;
opts = {
email: req.body.email,
fname: req.body.firstname,
lname: req.body.lastname
};
mailSvc.subscribeMany(lists, opts, function(err, result) {
if(err) {
res.status(500).send(err);
} else {
res.send(result);
}
});
}
You can use then construct a user interface however you would like!