Writing a Simple MailChimp Web Service Using Merb
A while back, I was asked to build some code to help keep a businesses mailing list synchronized between SalesForce.com and their campaign management tool, which I suggested should be MailChimp and not the tool they were currently using, but I digress. The project never materialized, but I figured I would build it anyway and use it as a chance to explore Merb a bit.
My thinking at the time was that a standalone “wrapper” web service made sense. While it would have complicated application administration a bit, encapsulating the mailing list functionality in a simple service that could be called synchronously or asynchronously, as well as modified and deployed independent of core site logic, sounded reasonable.
So, let’s start with building a minimal Merb application to serve as a foundation:
merb-gen app mail_chimp_service --flat
This generates one controller, a few templates (if we want to build in some templated monitoring and for xml responses) and just enough configuration to get the Merb service started.
To test it out, just fire up Merb with the following command: merb and head to http://localhost:4000.
With a foundation in place, I started looking into my MailChimp plugin to see if I should turn it into a gem or do something simpler. I turned to hoe, thinking that making a gem would be interesting, but then decided otherwise, as I basically didn’t feel like writing that much. So instead, I wrote a simple chimp class to do the MailChimp API work:
require 'xmlrpc/client'
class Chimp
cattr_accessor :client, :auth
def add(subscriber)
chimp_subscribe(auth, Merb::Config[:chimp_settings]['mail_chimp']['mailing_list_id'],
subscriber.email, subscriber.mail_merge)
end
private
def chimp_subscribe(auth, mailing_list_id, email, merge_vars,
email_content_type="html", double_optin=true)
begin
client.call("listSubscribe", auth, mailing_list_id, email,
merge_vars, email_content_type, double_optin)
rescue XMLRPC::FaultException => e
Merb.logger e.faultCode
Merb.logger e.faultString
end
end
end
This class adds users to a specific MailChimp mailing list using the MailChimp APIs. The client and auth attributes are set in the Merb init.rb class, as they really only need to be loaded once and not initialized per each request:
Merb::BootLoader.after_app_loads do
Chimp.client = XMLRPC::Client.new2('http://api.mailchimp.com/1.0/')
Chimp.auth = XMLRPC::Client.new2('http://api.mailchimp.com/1.0/').call("login",
Merb::Config[:chimp_settings]['mail_chimp']['username'],
Merb::Config[:chimp_settings]['mail_chimp']['password'])
end
I’m loading the MailChimp configuration parameters in the init.rb file in the config block. I’m just loading in a yaml file with the relevant information one would presumably want externalized from the application code:
Merb::Config.use { |c|
.....
c[:chimp_settings] = YAML.load_file(Merb.root/'mailing.yml')
}
I then created a simple subscriber.rb class to encapsulate user elements and wired the relevant classes together in my single controller like so:
require 'chimp'
require 'subscriber'
class Foo < Merb::Controller
provides :xml
def _template_location(action, type = nil, controller = controller_name)
controller == "layout" ? "layout.#{action}.#{type}" : "#{action}.#{type}"
end
def index
subscriber = Subscriber.new(params)
chimp = Chimp.new
chimp.add(subscriber)
render false
end
end
I subsquently added an index.xml.erb class to my views directory in order to render successful responses, fired up my app with the merb command and then ran a test in a separate console to ensure everything was working:
curl -H "Accept: text/xml" -L -d
"email=matt@mandarinsoda.com&first_name=swanky&last_name=mango" http://localhost:4000
It worked - the very first time! (joking, but it did work after a bit of tinkering). I saw the content of my index.xml.erb and received a MailChimp opt-in email. Not too shabby for a few hours of tinkering. I’m sure there are interesting Merb features missing as well that could make this all the more compact. More to explore later.





you might also be interested in looking into the Dm salesforce adapter: http://github.com/wycats/dm-adapters/tree/master/salesforce
Thanks for the info! Probably makes sense to look into creating a MailChimp DM adapter.
Cheers.