Integrate Salesforce using MailChimp webhook

mailchimp

MailChimp is a marketing automation platform, which provides a good REST API (MailChimp API 3.0) to communicate with other systems. MailChimp provides ‘MailChimp for Salesforce’ Appexchange app to integrate Salesforce to Mailchimp. Through this app, we can sync the Contact, Lead, Campaign from Salesforce to MailChimp and vise versa.

In this blog, I am going to demonstrate how can we listen to the change made on the MailChimp side and update the record in the Salesforce based on the change event.

MailChimp webhook allow us to collect the changed information based on the events (like Unsubscribe, Subscribe, Email Change, etc). To get the changed data we have to provide the URL for webhook, that URL going to be our Salesforce public site URL.

Below are the steps we need to follow to implement the functionality.

  • Create a Visulforce page that will listen to the changes from MailChimp.
<apex:page controller="MCUnsubscribeCntrl" sidebar="false" showHeader="false" action="{! UpdateUnsubscribeMembers}" >
MailChimp Webhooks...
</apex:page>
view raw MCUnsubscribe hosted with ❤ by GitHub
  • Create an Apex controller for the Visualforce page, this Apex class will get the changed data from MailChimp and update the record in the Salesforce.
public without sharing class MCWebhookCntrl {
public PageReference UpdateUnsubscribeMembers() {
String sCode = fetchSecrateCode();
System.debug('***Secrate Code: ### ' + sCode );
String MCrequestCode = ApexPages.currentPage().getParameters().get('code');
if (MCrequestCode == null || !sCode.equals(MCrequestCode )) {
System.debug('Code is not valid: Please use valid code: ' + MCrequestCode );
return null;
}
String eventType= ApexPages.currentPage().getParameters().get('type');
system.debug('Type of event: '+ eventType);
if(eventType == 'upemail'){ //Email Changed event
// Getting New Email
String newEmail = ApexPages.currentPage().getParameters().get('data[new_email]');
system.debug('Changed Email: ' +newEmail);
// Getting Old Email
String oldEmail = ApexPages.currentPage().getParameters().get('data[old_email]');
system.debug('Old Email: ' +oldEmail );
if (oldEmail == null || oldEmail.length() <= 0) {
System.debug('Email Id is null or blank');
return null;
}
else {
System.debug('Email for Email Opt Out: ' + oldEmail );
}
String safeEmail = String.escapeSingleQuotes(oldEmail);
safeEmail.replace('*', '\\*');
safeEmail.replace('?', '\\?');
// SOSL search for records (Contact)
List<List<SObject>> searchList = [FIND :oldEmail IN EMAIL FIELDS RETURNING Contact(id) limit 1];
//Contact List
List<Contact> contacts = ((List<Contact>)searchList[0]);
// Getting first record. you can iterate the list to get all records.
List<Contact> conListForUpdate = [select id,Email,MailChimpActivity__c from Contact where id =: contacts[0].id ];
for (Contact c : conListForUpdate ) {
if( c.MailChimpActivity__c ==null)
c.MailChimpActivity__c ='';
c.MailChimpActivity__c += 'Email chnaged from '+c.Email+ ' to '+newEmail+' \r\n' ;
c.Email = newEmail;
}
// Update Lists
if (conListForUpdate.size() > 0) {
update conListForUpdate;
}
}
// Unsubscribe/ Subscribe
else if(eventType != 'profile'){
String emailAddr = ApexPages.currentPage().getParameters().get('data[email]');
if (emailAddr == null || emailAddr .length() <= 0) {
System.debug('Email Id is null or blank');
return null;
}
else {
System.debug('Email for Email Opt Out: ' + emailAddr );
}
String safeEmail = String.escapeSingleQuotes(emailAddr);
safeEmail.replace('*', '\\*');
safeEmail.replace('?', '\\?');
// SOSL search for records (Contact/Lead)
List<List<SObject>> searchList = [FIND :emailAddr IN EMAIL FIELDS RETURNING Contact(id), Lead(id) ];
//Contact List
List<Contact> contacts = ((List<Contact>)searchList[0]);
//Lead List
List<Lead> leads = ((List<Lead>)searchList[1]);
for (Contact c : contacts) {
if(eventType =='subscribe'){
c.HasOptedOutOfEmail = false;
}else if(eventType =='unsubscribe'){
c.HasOptedOutOfEmail = true;
}
}
for (Lead l : leads) {
if(eventType =='subscribe'){
l.HasOptedOutOfEmail = false;
}else if(eventType =='unsubscribe'){
l.HasOptedOutOfEmail = true;
}
}
// Update Lists
if (contacts.size() > 0) {
update contacts;
}
if (leads.size() > 0) {
update leads;
}
}
return null;
}
public String fetchSecrateCode() {
try {
StaticResource sr = [ SELECT Body, Name FROM StaticResource WHERE Name = 'WebHooksConfig' LIMIT 1 ];
String xml = sr.Body.toString();
System.debug('XML data: ' + xml);
//XML parsing
Dom.Document doc = new Dom.Document();
doc.load(xml);
Dom.XMLNode webhooks = doc.getRootElement();
for (Dom.XMLNode node : webhooks.getChildElements()) {
String id = node.getAttribute('id', '');
if (id.equalsIgnoreCase('unsubscribe')) {
return node.getAttribute('code', '');
}
}
}
catch (Exception e) {
System.debug('*** Something went wrong: Error Occured! : ' + e.getMessage());
}
return null;
}
}
view raw MCWebhookCntrl hosted with ❤ by GitHub
  • Create an XML file. Upload this file in the static resource, static resource Name will be ‘WebHooksConfig’.
<webhooks>
<webhook id="unsubscribe" code="YOUR_SECRETE_CODE"/>
</webhooks>
view raw xmlFile hosted with ❤ by GitHub
  • Create the public site (force.com site) in Salesforce.
  • Go to quick search and type – Site -> click Sites -> Create a domain if it is not created. Otherwise, click on the ‘New’ button to create a new site.
  • Click on ‘Public Access Settings’ and give the view/edit access Contact/Lead for fields. e.g- (HasOptedOutOfEmail, MailChimpActivity__c )

Also, give access for Apex class and Visualforce page.

  • Create Webhook for MailChimp List. Login into your MailChimp account and click on ‘List’ tab.
  • Enter Webhook URL:( https://YourOrgDomain-developer- edition.ap5.force.com/webhooks/MCUnsubscribe?code=YOUR_SECRETE_CODE). Select the types of updates to be sent (Subscribe, Unsubscribe, email changed) and click on Save.
Result:
Now, If you made an update on the MailChimp side like if you Unsubscribe the member from MailChimp then that record Contact/Lead (with the same email) inside salesforce will be updated with ‘Email Opt Out‘ checkbox checked. If the user again Subscribe that member then ‘Email Opt Out’ field will be Unchecked.
If the Email of member changed from MailChimp side then the Field on Contact (MailChimpActivity__c) will be updated.
Hope this blog post helps many.
Thanks.

Arun Kumar

Arun Kumar is a Certified Salesforce developer and Salesforce Champions (Platform Champions), a Computer Science graduate, working on the Salesforce platform and providing customer solutions using force.com as a Salesforce consultant/developer. He is the founder of SFDCLessons. :)

Leave a Reply