I would never think of building a tire to use on my car, I’d buy one that is refined, tested and works! So why do so many developers insist in re-inventing the wheel?
I was talking to a Developer recently who wanted to build a mass emailing system to add value to their CRM product. Rather than building from scratch and having to become an expert in the world of email marketing, tracking, spam, and the best practices in that area I suggested looking at integrating a 3rd party email marketing software.
The benefit of taking something that is already refined and feature rich is a quicker time to market, less to develop and maintain (and is improved constantly for you). Additionally, you can often find nuggets that are worth drawing back into your existing systems to improve additional functionality – such as the Member Rating from MailChimp.
What is MailChimp?
MailChimp is a market leading mass mail system and is what I use for my personal blog e-mail list (just scroll down its on the right if you want to sign up 🙂 – MailChimp’s free plan gives a generous 2000 registered user which is ideal for many small businesses / start ups etc to start benefiting from. They also offer services for nurture campaigns etc which are hugely beneficial in turning prospects into customers.
MailChimp Member Rating
MailChimp is organised by lists, and each subscriber to that list is a member of that list. The MailChimp Member Rating is a star value (1 to 5) that is calculated based on a members engagement with your email blasts for that list.
The MailChimp Member Rating is highly useful to prioritise who to contact first, who are your most engaged subscribers/customers that are likely to respond positively. While it is clearly visible in the online portal as a star rating. (see image) it would be great to have that inside your own software; which brings me back to the huge value I want to immediately get pulled into my application.
MailChimp API and getting the MailChimp Member Rating
Now on its 3rd iteration, the MailChimp API is JSON based and is self documenting (to a point) as the JSON data packets returned have a links section built in describing the paths available to drill deeper into the data (including JSON Schemas on the returned data). In addition the MailChimp documentation online is pretty good, describing how you can define data packet fields, number of records returned and filter based on search criteria.
The MailChimp API is generally based on REST standards, the MailChimp API is broken up into a number of logical sections allowing you to discover
- Authorised Applications
- Automations (part of their paid service)
- Batch Operations
- Campaign Folders
- Email Campaigns
- Conversations from emails sent
- File Management (of images used)
- Lists; that your subscribers belong to
- Reports on Campaigns
- Email Templates
Calling the MailChimp API and Lists
The MailChimp Member Rating is part of the Lists section. To get the rating for a member you need to first
- Get a list of the lists
- Choose the relevant lists
- Query the list for the member and retrieve their rating from the data returned.
You can also return the entire list of members using a search (I would recommend breaking this into pages based on the data returned with the list (including size) that you fetch in multiple threads simultaneously – but that is for a later post if I get time)
Calling MailChimp API v3 with Delphi
I covered in an earlier post linking to Azure using the REST components in Delphi. While Azure uses XML data packets in the response, MailChimp uses JSON which makes it a lot simpler to integrate quickly. In the rest of this post I will cover what I needed to do to Integrate with the Mail Chimp API.
Step 1 – Authentication
There are 2 authentication methods for the API: HTTP Basic authentication and OAuth2. The easiest way to authenticate is using HTTP Basic authentication. Mail Chimp takes any string as your username and your API Key as the password (you create the MailChimp API Key from your MailChimp account)
Step 2 – Setup Base URL
With the THTTPBasicAuthenticator setup, you are ready to add the TRESTClient component. The TRESTClient allows you to easily manage the location of the API that you are calling and makes it easy to switch between servers for testing and live or for different clients. In this case we are just calling the live data.
- BaseURL – https://<dc>.api.mailchimp.com/3.0
- Note: replace <dc> with the server your account is linked to – you can see this when you log in to your MailChimp account. My account was on Server us11
- Connect the Authenticator to manage the authorisation headers/handshake.
Step 3 – Getting a list of list from your MailChimp account
Lists exist under the verb “lists” – To get the lists you need to call the API BaseURL + “/lists” e.g.
The lists verb is added to a TRESTRequest component, which is linked to the TRESTClient. You also will need a TRESTResponse to collect the output from the RESTRequest. Lets start with just getting the raw JSON results and then look at how to work with it.
The image below shows the components added and the properties you nee to check are set on the RESTRequest.
At this point. You have the URL and authentication setup and somewhere to put the resulting data packet. You should be able to right click on the RESTRequest and Execute, (YES AT DESIGN TIME)
Resulting in a 200 result.
The Delphi REST Components have now fetched the data packet using the authentication provided, and you can now see that the data by checking the Content property of the RESTResponse.
WOW that was easy! No code written yet and data being fetched! Now to get the actual list.
To access an individual list, a GET request is required. This is a slight de-normalisation of REST standards, as a parameter is used like a VERB, however it makes sense for the readability of the URL and the way it drills down so lets roll with it.
Getting the ListID from the JSON data packet
The first step to calling the list specific API call is to get the ListID. To extract the ListID out of the data packet fetched, you need to parse the JSON, but how best to do that? Lets explore two different options depending on your preference.
Option 1) Like TDataSet? Is the data in a JSON Array?
Using TDataSet is great, as it provides a quick easy way to SaveToFile / LoadFromFile or linked into a local database allowing caching of data with little work.
If the data packet returns a JSON array, you can convert this array into a TDataSet using the TRESTResponseDataSetAdapter. Linking the RESTResponse and a TDataSet, the resulting RESTRequest will automatically populate the DataSet with the node specified in the RootElement when it returns.
Converting to a TDataSet, you can then work with the result like any other TDataSet. (e.g. Bind it to a Grid) and get the value by referencing the TField.
Option 2) Would you rather work with a Classes and Object representations of your JSON?
I posted on how to build a Delphi Object from JSON using JsonToDelphiClass, a tool I stumbled across while researching the MailChimp API. (see video below for demo)
Using JsonToDelphiClass you can create a Delphi class based on an actual JSON data packet. Using the steps above, the JSON data is easily accessible to copy from the TRESTResponse.Content property ready to paste into JsonToDelphiClass to create the Delphi unit.
While the tool does a good job at creating something that will work, its definitely worth checking the created class against the JSON schema for the data packet in case of missing properties.
The default is to have a unit called RootUnit and TRootClass. You can modify those defaults in the JsonToDelphiClass UI or use refactoring afterwards. Either way you now have classes that can be used to make objects to work with at run time.
Click for my earlier post on using TJson.JsonToObject.
Date Times from JSON in Delphi
Note: While the generated unit works out the box, I added [joIgnoreEmptyStrings, joDateFormatISO8601] to the TJsonToObject calls as I updated some of the object properties to be TDateTime rather than strings. This resulted in TDateTime rather than strings for date and time values.
Using the Generated Delphi Class based on JSON
Using the new unit, just add it to your project and to your uses clause and then you can covert the JSON to Objects at runtime with code similar to this… (note – I change TRootClass to TMCLists)
procedure TForm2.Button2Click(Sender: TObject); var RC: MailChimpLists.TMCLists; begin RESTRequest1.Execute; RC := TMCLists.FromJsonString(RESTResponse1.JSONText); try ShowMessage(Length(RC.lists).ToString); finally RC.Free; end; end;
Step 4 – Details on a MailChimp List Member
Now you have a list of the MailChimp lists on the account, its possible to check each one based on the list ID for the members email address.
The introduction of System.Hash in RAD Studio XE8 makes the use of MD5 really easy. e.g. to convert an email into a hashed string you could do something like
uses System.Hash; ... hash := THashMD5.GetHashString('firstname.lastname@example.org');
In a similar way to selecting the lists before hand it is possible to add in a new RESTRequest, connected to the RESTClient and a RESTResponse, connected to the RESTRequest.
Setting the RESTRequest Resource property will automatically create parameters, as named inside the curly brackets.
Using the steps described above, it is now just a case of repeating the process, making sure the parameters are defined (select on in the dialog window to enter the value). The member Rating is on the returned data so will be a property of the new generated class.
If you want to fetch the JSON without having to use the components, you can use the REST Debugger.
- If you have Delphi, C++ Builder or RAD Studio its under Tools > REST Debugger)
- Or download the free REST Debugger from Embarcadero.
Getting the Member Rating from the JSON
Rather than writing out the same steps again, I’ve covered the steps using JsonToDelphiClass and the REST Debugger in the following video. Which includes how to set the parameters on the REST Debugger.