While Kentico EMS offers an excellent feature set for working with contacts, I am often asked to integrate it into third-party systems and keep contact information in sync between them. Frequently, these integrations are for mailing systems such as MailChimp or ConstantContact.
Before I get into the solution, I’d first like to say that Kentico offers a great mailing list management solution of its own in the Email Marketing module. In Kentico 11, they even have a user-friendly drag and drop email builder.
If you have set up your SMTP servers correctly using a service such as SendGrid or MailGun, the built-in solutions are just as good, if not better than many third-party mailing list managers. Integrating with third-party systems will cost you more money both up front and in the long term as you will have to maintain the integration as and when the third parties update their APIs. For that reason, every Kentico admin should first consider using the built-in tools for this rather than integrating with a third party.
That said, when I am forced to integrate…
Here’s How I Do It…
Requirements and Required Reading
Firstly, you must ensure that you have somewhere in your third-party system to store the Kentico ContactID for each contact. This is how you will identify the contact in some cases.
Using Kentico’s global events, I can capture the “insert” and “update” events for the contacts. If you are unfamiliar with Kentico global events, I recommend the following links as required reading:
Global Events
The events you will need to handle are registered in your module’s OnInit() method like so:
1. ContactInfo.TYPEINFO.Events.Insert.After += HandleContactInsertUpdate;
2. ContactInfo.TYPEINFO.Events.Update.After += HandleContactInsertUpdate;
3. ContactInfo.TYPEINFO.Events.Delete.After += HandleContactDelete;
4. ContactManagementEvents.ContactInfosDeleted.Execute += HandleMultipleContactsDeleted;
5. DataProtectionEvents.RevokeConsentAgreement.Execute += HandleRevokeConsent;
The above event-handlers cover all scenarios where you would need to take action in your third-party system in relation to a Contact from Kentico.
Handling the Events
Insert and Update are going to perform the same functionality so can use the same method:
1.
private
void
HandleContactInsertUpdate(
object
sender, ObjectEventArgs e)
2. {
3. var contact = e.Object
as
ContactInfo;
4.
5.
// If the objec tisn't a contact return out.
6.
if
(contact ==
null
)
return
;
7.
8.
// Prevent recursion
9.
if
(e.DetectRecursion($
"ContactInsertUpdate-{contact.ContactID}"
))
return
;
10.
11.
// If the contact doesn't have the fields we need currently, return out.
12.
if
(
string
.IsNullOrWhiteSpace(contact.ContactEmail) ||
13.
string
.IsNullOrWhiteSpace(contact.ContactFirstName) ||
14.
string
.IsNullOrWhiteSpace(contact.ContactLastName))
15.
return
;
16.
17.
/*
18. * If we're in Kentico 11 we also need to check for consent.
19. *
20. * If you're in an older version of Kentico you can ignore the consent-related
21. * code below but will likely have to implement your own consent methods to
22. * comply with GDPR.
23. */
24.
25.
// Get the consent - replace the "ThirdPartySystemConsentName" with the name of the relevant Consent in your site
26. ConsentInfo consent = ConsentInfoProvider.GetConsentInfo(
"ThirdPartySystemConsentName"
);
27.
28.
// Initializes an instance of the consent agreement service
29. IConsentAgreementService consentAgreementService = Service.Resolve<IConsentAgreementService>();
30.
31.
// Checks if the contact has given an agreement with the consent
32.
bool
agreed = consentAgreementService.IsAgreed(contact, consent);
33.
34.
if
(agreed)
35. {
36.
// Do your work to insert/update the contact in the third-party system.
37. }
38.
else
39. {
40.
// Check the third-party system for the existence of this contact and delete them from there. Use the contacts email address and remove all references to it in your third-party system
41. }
42. }
If you’re using Kentico 11 then you also need to handle the event when a contact revokes their consent:
1.
private
void
HandleRevokeConsent(
object
sender, RevokeConsentAgreementEventArgs e)
2. {
3. var contact = e.Contact;
4. var consent = e.Consent;
5.
6.
// replace the "ThirdPartySystemConsentName" with the name of the relevant Consent in your site
7.
if
(consent.ConsentName !=
"ThirdPartySystemConsentName"
)
return
;
8.
9.
// now delete the contact from your third-party system here. Use the contacts email address and remove all references to it in your third-party system
10. }
When a single contact is deleted, we need to handle it and delete it from the third-party system:
1.
private
void
HandleContactDelete(
object
sender, ObjectEventArgs e)
2. {
3. var contact = e.Object
as
ContactInfo;
4.
5.
// If the objec tisn't a contact return out.
6.
if
(contact ==
null
)
return
;
7.
8.
// Prevent recursion
9.
if
(e.DetectRecursion($
"ContactDelete-{contact.ContactID}"
))
return
;
10.
11.
// now delete the contact from your third-party system here. Use the contacts email address and remove all references to it in your third-party system
12. }
Finally, if multiple contacts are deleted at the same time, Kentico calls a different event:
1.
private
void
HandleMultipleContactsDeleted(
object
sender, ContactInfosDeletedHandlerEventArgs e)
2. {
3. var contacts = e.DeletedContactsIds;
4.
5.
// Note that we only have the contact ID's here. You must ensure that your third-party system stores the ContactID from Kentico in some way.
6.
// In most third-party mailing list systems you can add it as a merge field to the recipient.
7.
8.
// now delete the contact from your third-party system here.
9. }
In Summary
The solution given above ensures that contacts are kept in sync with third-party systems while also honoring the Kentico 11 consent system. It could easily be adapted for use in Kentico 9 or 10 with minimal work, but if you are considering this level of integration relating to contacts, then I would highly recommend upgrading to Kentico 11 to make use of the GDPR module and consents.