Mail Chimp Add/Update e-mail to List and Subscribe API V3






3.28/5 (12 votes)
How to add, and update an existing, entry on MailChimp list, using API V3. Optionally, you can add to one or more groups easily. Written in VB.NET, but could be easily converted to C#
Introduction
So my mission was to add simple code to my VB.NET website (can be easilly converted to c# using a converter), to subscribe customers to a newsletter, via a MailChimp list with 3 sub-groups (can be on one or many groups), and update the same entry if user changed details, or needed adding to another MailChimp group. Then let MailChimp automation take over the process of sending the e-mail automatically. A simple task, I thought. Wow, was I wrong!
So the guys and gals at MailChimp have done an excellent job of implementing an API to do almost anything, to lists, groups, automation, etc. but I would say that 98% requirements are simple as mine, but in order to achieve my objective, we have to know so much about JSON, GET and POST operation with authorization, etc..
Background
So I currently have 3 MailChimp lists:
One was for testing called “Test
” which had no groups.
Standard fields:
Then I had two more which have the same field names but different groups. We are going to Use “Test
” and “List Sage
” for examples.
“List Sage
” structure:
Implementation
Firstly, I read the MailChimp API, which has no documentation for C# or VB.NET, then I looked at the two API wrappers available. Both required an install into .NET, which I was reluctant to do as either I would have to do it on my web server or remember to do it when I change development machine in the future. Also reading the documentation all over again seemed too complicated.
So my objective required:
- Getting my head around the fact Groups are called “Interests” in the API.
- Get the IDs needed to update a List, with a groups and group values.
- Implement function to
GET
data from the MailChimp API, with basic authentication. - Implement function to
POST
data to the API, with basic authentication. This took some time as I got a lot of {"The remote server returned an error: (401) Unauthorized."} until I worked out how to do it. This seems to be a common problem from what I read. - Having got the code to add customers to the list, to update entries on a list, you have to do a different call. This means you have to first check whether the customer is on the list, if so to
PUT
, to update entry. - When updating the contact don't change the value'status' as they may have opted out of the list.
Using the Code
Now I’m a simple guy, as you will see from my code which I could spend more days refining but don’t have the time to spend for little return. Being self-employed and an extensive job list. Time is money!
The class exposes two simple functions:
Function getListIDandGroupsAndWriteToFile() As String
Which returns all the list IDs and Groups IDs in the account. You only need to call this once or whenever you make changes to groups. These IDs can be stored in your own code or database.
Function addSubscriber(ListID$, email$, fieldList$, groupList$) As Boolean
Add or update entry on list, identified by email. See examples below.
It also exposes a function to get member details if alread on list, but not generally needed.
Function getMemberIfAlreayExists(ListID$, email$, response$) As String
Examples
First, we call getListIDandGroupsAndWriteToFile()
, which I logged to a file, and gave:
List ID:44b9dccea3 - 'Test' - members 4
List ID:9b2e63f0b9 - 'List Sage' - members 4
Group ID:5a84f8f68e - 'Interests'
Group Value ID:407da9f47d - 'Sage One' - members 0
Group Value ID:05086211ba - 'Sage 50' - members 4
Group Value ID:2ba200b991 - 'Sage 200' - members 1
List ID:e1a0e32d08 - 'List Exchequer' - members 3
Group ID:62ddcc8bf3 - 'Interest'
Group Value ID:68b98284d3 - 'PostTrans' - members 3
Group Value ID:a940bf543c - 'PostTrans XML Gateway' - members 0
Group Value ID:b9d4006df3 - 'All Other' - members 3
Now we have the IDs, which we only have to retrieve once, we can add subscriber easily:
Add/Update to list - 'Test' SIMPLE
Dim mailchimp As New ZmailChimp
Dim ListId$ = "44b9dccea3" 'List Exchequer' List
Dim email$ = "samsmith17@anymail.com"
Dim fieldListOnAdd = "FNAME,Sam,LNAME,Smith"
Dim fieldListOnUpdate = "FNAME,Sam,LNAME,Smith"
Dim groupList = ""
With mailchimp
.API$ = "46cMailChimpAPIKeyd1de-us14" 'MailChimp API key
.dataCenter$ = "us14" 'Last 4 letters of API key
.password$ = "Password!"
MsgBox(.addSubscriber(ListId$, email, fieldListOnAdd, fieldListOnUpdate, groupList))
End With
mailchimp = Nothing
In my application, when adding a subscriber I wanted to set the value of field, but not on updates. Hence the need for a seperate file list for updates.
Add/Update to list - 'List Sage' with groups
1 Group
Dim mailchimp As New ZmailChimp
Dim ListId$ = "9b2e63f0b9" 'List Sage' List
Dim email$ = "samsmith20@anymail.com"
Dim fieldListOnAdd = "FNAME,Sam,LNAME,Smith,MTYPE,User,MID,631637"
Dim fieldListOnUpdate = "FNAME,Sam,LNAME,Smith,MID,631637" 'Don't change MTYPE
'Put on 'Sage One' and 'Sage 50' group
Dim groupList = "407da9f47d,05086211ba"
With mailchimp
.API$ = "46cMailChimpAPIKeyd1de-us14" 'MailChimp API key
.dataCenter$ = "us14" 'Last 4 letters of API key
.password$ = "Password!"
MsgBox(.addSubscriber(ListId$, email, fieldListOnAdd, fieldListOnUpdate, groupList))
End With
mailchimp = Nothing
where:
FNAME = First Name
LNAME = Surname
MTYPE = Field added to store a type of user
MID = UserID in my system
2 Groups
Dim mailchimp As New ZmailChimp
Dim ListId$ = "9b2e63f0b9" 'List Sage' List
Dim email$ = "samsmith19@anymail.com"
Dim fieldListOnAdd = "FNAME,Sam,LNAME,Smith,MTYPE,User,MID,631637"
Dim fieldListOnUpdate = "FNAME,Sam,LNAME,Smith,MID,631637" 'Don't change MTYPE
Dim groupList = "407da9f47d" 'Put on 'Sage One' group
'Put on 'Sage One' and 'Sage 50' group
Dim groupList = "Interests,407da9f47d,05086211ba"
With mailchimp
.API$ = "46cMailChimpAPIKeyd1de-us14" 'MailChimp API key
.dataCenter$ = "us14" 'Last 4 letters of API key
.password$ = "Password!"
MsgBox(.addSubscriber(ListId$, email, fieldListOnAdd, fieldListOnUpdate, groupList))
End With
mailchimp = Nothing
Simple. Once the entry has been added to the Groups/List, then MailChimp automation can take over to schedule the sending of mail, etc. which is very powerful.
Impact on your system
I actually wrote another class to store ListId,email,fieldListOnAdd,fieldListOnUpdate,groupList in a table, then process the contents of the table every hour. Thus the MailChimp subscribe process had no impact on the response of the sign up and billing process which it was added too.
Here is the code to give you some idea:
Imports Microsoft.VisualBasic Imports System.Data.SqlClient 'This class takes mail chimp data and puts in table, then every hour is called to process, so user see no delays Public Class zMailChimpTop 'addSubscriber - Add to list for latter procecssing Function addSubscriber(Server As Object, ListID$, email$, McFieldListADD$, McFieldListUPDATE$, groupList$, Optional MCAccID& = 1) As Boolean 'Save Object and create new one if need be Dim SQL$ = "", ErrorDesc$ = "" addSubscriber = False SQL = "INSERT INTO RegMailChimpProcess (MCAccID,McDate,McListID,McEmail,McFieldListUPDATE,McFieldListADD,McGroupList )" SQL += " SELECT " & MCAccID & " as expr1" SQL += ", " & DB.QueryDate(Now(), True) & " as expr2a" SQL += ", " & DB.CleanTextForSQL(ListID, 20) & " as expr3" SQL += ", " & DB.CleanTextForSQL(email, 200) & " as expr4" SQL += ", " & DB.CleanTextForSQL(McFieldListUPDATE, 400) & " as expr5" SQL += ", " & DB.CleanTextForSQL(McFieldListADD, 400) & " as expr6" SQL += ", " & DB.CleanTextForSQL(groupList, 200) & " as expr7;" If DB.ExecuteSQL(SQL, ErrorDesc) = 0 Then logError(Server, "Error SQL:Insert Company", SQL & " - " & ErrorDesc) Else Return True End If End Function Sub processUpdate(Server As Object) Dim SQL$ = "" Dim totalToPay# = 0, TotalOwed# = 0 Dim DB As New zzDatabaseStuff(Globalv.DBConnectionSupportProg2) SQL = "SELECT RegMailChimpProcess.* from RegMailChimpProcess order by McID; " '==================== Process Mail Chimp Updates =================== Dim DBConnection As SqlConnection DBConnection = New SqlConnection(Globalv.DBConnectionSupportProg2) Try DBConnection.Open() Dim cmd As New SqlCommand(SQL, DBConnection) Dim dr As SqlDataReader = cmd.ExecuteReader() Do While dr.Read Dim mailchimp As New ZmailChimp Dim ListId$ = dr.Item("McListID") ' "9b2e63f0b9" 'List Sage' List Dim email$ = dr.Item("McEmail") '"sam10@postcodelite.com" Dim McFieldListUPDATE = dr.Item("McFieldListUPDATE") ' "FNAME,Sam,LNAME,Smith,MTYPE,User,MID,631637" Dim McFieldListADD = dr.Item("McFieldListADD") ' "FNAME,Sam,LNAME,Smith,MTYPE,User,MID,631637" Dim groupList = "" '"Interests,407da9f47d,05086211ba" If Not IsDBNull(dr.Item("McGroupList")) Then groupList = dr.Item("McGroupList") End If With mailchimp .API$ = "46c9 MailChimp API key d1de-us14" 'MailChimp API key .dataCenter$ = "us14" 'Last 4 letters of API key .password$ = "Your Password!" If Not .addSubscriber(ListId$, email, McFieldListADD, McFieldListUPDATE, groupList) Then logError(Server, "zMailChimpTop:Failed to update ", email & " - ") Else SQL = "DELETE [RegMailChimpProcess] FROM [RegMailChimpProcess] where McID=" & dr.Item("McID") & ";" Dim errorDesc$ = "" DB.ExecuteSQL(SQL, errorDesc$) End If End With mailchimp = Nothing Loop dr.Close() Finally DBConnection.Close() End Try End Sub End Class
Some of my library functions are missing, but it gives you the idea.
SQL to create Table
USE [supportprog2]
GO
/****** Object: Table [dbo].[RegMailChimpProcess] Script Date: 19/10/2016 11:07:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[RegMailChimpProcess](
[McID] [int] IDENTITY(1,1) NOT NULL,
[MCAccID] [int] NULL,
[McDate] [datetime] NULL,
[McListID] [varchar](20) NULL,
[McEmail] [varchar](200) NULL,
[McFieldListADD] [varchar](400) NULL,
[McGroupList] [varchar](200) NULL,
[McFieldListUPDATE] [varchar](400) NULL,
CONSTRAINT [PK_RegMailChimpProcess] PRIMARY KEY CLUSTERED
(
[McID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
Code Download
I’m sure I will get loads of comments about the crudeness of this implementation, and yes, it is a bit crude, but I didn’t want to load any third party objects or code.
This could easily be converted to c# using a Vb.net to c# converter, easily found using goole.
Let me know if it was help to you :-)
History
- 17th October, 2016: Initial version