Emailing with no pain but pleasure

We all know that awkward moment when your only ticket left is “Emailing / newsletter module”. Which basically means :

  • Email server setup … Oh wait … You did it once and still have nightmares !
  • Investigate Amazon SES. Read the doc and you’ll want to hang yourself
  • Finally found a way to send emails through Gmail
  • Erm … damn spam filters …
  • Wait ! What ? The marketing team wants to be able to edit templates whenever they want …

1. Do it the right way !

Fortunately, like so many things today, there’s an API for sending email and making your life easier ! As a lazy developer I started investigating plug-and-play solutions first. Here is a non exhaustive list of what came up.

The features are pretty nice:
  • SMTP
  • Send API (through http)
  • ESP feedback, SPF, DKIM, clean IP, etc…
  • Transactional emails
  • Campaigns with user list
  • Live logs / statistics
  • Webhooks event notifications (bounce, unsubscribe, complaint …)
  • Mobile application

I choose MailChimp because it provides all of this nice features and has a good reputation. If you are looking for more informations about providers, you can read this article


2. Getting started with MailChimp

Fun monkey, lot of features, clean UI and 12000 emails/month included in the free plan. Nice start !

You can’t send transactional emails with MailChimp, they have a dedicated project called “Mandrill”. No worries, you can link your accounts, it’s pretty straightforward !


You can start with their “pre-designed” templates but I have to warn you, most of them are ugly … They have a basic WYSIWYG editor, useful if the market team needs to tweak some text ! I started from scratch (yeah I love 1990 html coding style …) and used the import tool. Just upload a zip and MailChimp’ll do the magic monkey dance for you ! Pretty cool :=)

Two things you have to understand to make it dynamic :

  • Merge vars : Contextual variables (*|EMAIL|*, *|FNAME|*, *|LNAME*| …). Defined in User lists.
  • Editable blocks : <span mc:edit=”myid”>.Set them when you send your emails.
If you need complex dynamic content you can also use the “feedblock”. Can’t wait to test it !


User lists

This is your user database, the backbone. If you already built your own database, you can sync it through their api. Use the *|MERGE|* tags as fields, such as birthdate, id, premium user, location etc … Then you generate groups or segments based on those fields.

This part is really powerful. The next time you’ll send a newsletter, no need to extract a csv from your database or handle unsubscriptions ! Each user has a rating based on emails opened / clicks / unsubscription / complaints / etc. You’ll easily know which users are really active or annoyed by your email.

The fields you defined in a list are accessible in your templates with *|MYFIELD*|.

Web Forms

MailChimp allows you to create web form widgets from your lists. Nothing else to say, just click it and embed it in your site or Facebook.


This part is the combination of templates and user lists. It sends massive emails. You can send a newsletter to a segment of your users with advanced filters. A/B split and rss-driven campaigns look nice but I haven’t tried it so far.

3. Send transactional emails with Mandrill

In MailChimp go to Account > extras > integrations and link your account with Mandrill. You’re good to go ! The free plan includes 12 000 more emails/month (remember MailChimp newsletter, Mandrill transactional).

Now in your templates list, click “send to Mandrill”. The template name will be your template id in Mandrill.


If you don’t need the MailChimp’s goodies, Mandrill is a standalone project.

Python Developer ? Here is the “official” repo named mail-snake. I maintain a fork for python 3k here. I’ll push the py3k support upstream as soon as possible.

mapi = MailSnake('YOUR MANDRILL API KEY', api='mandrill')
   template_name = 'template-id',
   template_content = [{
      'edit-block-id' : 'test_block',
      'content' : 'my dynamic content'
   global_merge_vars = [
   message = {
      'subject' : 'Hello World',
      'from_email' : '',
      'from_name' : 'Awesome Project Name Here',
      'headers' : {},
      'to' : [
         'email' : '',
         'name' : 'Toto 42'
      'metadata' : {
         'uid' : 'user id',
         'another_one' : 'premium'
      'tags' : ['welcome'],
      'google_analytics_domains' : [''],
      'google_analytics_campaign' : ['ga_campaign'],
      'auto_text' : True,
      'track_opens' : True,
      'track_clicks' : True

> template_name : The template name in MailChimp / Mandrill

> template_content : Fill the mc:edit=”myid” you defined in your template

> global_merge_vars : Override merge vars (eg : *|FNAME|*)

> metadata : Mandrill logs all the emails you send. Use this option as a key/value index. (eg: Find all the emails I sent to a specific user). You can index up to 10 fields.

> tags : Simple tags. This will display a label in your logs

> Google analytics : Configure it if you want to associate the traffic from your mails to your website in google analytics.


MailChimp + Mandrill + RabbitMQ FTW !


Links :

4 thoughts on “Emailing with no pain but pleasure

  1. I’m doing something very similar to your example, yet my merge_vars are not getting replaced in the template when the email goes out. I’ve tried passing them in as global_merge_vars and merge_vars. Note that I’m not using predefined merge_vars, but rather custom variables that I’ve defined in the template like:

    Username: *|USER_NAME|*

    Then when calling:

    message = {
    ‘global_merge_vars': [
    …other args removed for clarity….
    ‘USER_NAME': ‘a username’,


  2. With merge vars you have to predefine variables and that’s a pity … I you can’t/don’t want to do it, use editable blocks :

    message = {
    template_content: [{
    ‘edit-block-id’ : ‘user_name’,
    ‘content’ : ‘a username’

    This should work :)

  3. It appears my scheme does work providing I send the global_merge_vars in correctly.

    ‘global_merge_vars’: [

    {‘name': ‘user_name’, ‘content': ‘a username’},


    I was attempting to send in a simple dictionary, but in fact, one must send in a list of dicts with the keys ‘name’ and ‘content’. My bad.

  4. I must not understand something…

    My template is like this

    My json

    template_content = [{
    ‘edit-block-id’ : ‘mainbody’,
    ‘content’ : ‘Hello’
    global_merge_vars = [

    However nothing is replace and it seems that it even stripes/empty the div

    Would you know what happens here ?

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>