Building our own Salesforce SFMC integration with Sitecore Forms
Tags: sitecore, salesforce, csharp, webdev
Published: 2020-09-30 10:06:50

Some time ago, our Marketing team asked if it was possible to integrate a Sitecore website with Salesforce SFMC. More specifically, they asked if they could add data submitted by some Sitecore Forms to Salesforce Marketing Cloud’s data extensions.
At that time, Sitecore had already several connectors for integrating xDB and the Media Library with SFMC, but no solution specifically for Sitecore Forms. We looked at the possibility to integrate it with Salesforce open APIs.

#The force is strong with Salesforce
Before continuing further, let me briefly talk about Salesforce, so readers that are not familiar with it understand what I’m talking about.

Salesforce is a big platform offering quite a lot of SaaS solutions like CRM, Marketing Automation, e-Commerce, etc… In this post I’ll be talking specifically about Salesforce Marketing Cloud, used by marketers. In this software there is something called Data Extensions and is similar to database tables. Each Data Extension has a name and different columns, containing data that can be used in marketing automation workflows. Each DE (data extension) column has a name, a type and several other properties. Records can be added, edited or deleted from a DE.

#Start of a journey

Although it seemed quite simple at first, the journey wasn’t. Obviously the first thing we did, was to do a little research on what we could use. Firstly we landed on the [Salesforce docs](https://developer.salesforce.com/docs/atlas.en-us.noversion.mc-apis.meta/mc-apis/index-api.htm) and found out that Salesforce offers an extensive soap and rest API. This definitely offered all the features we required four our project, but as developers we did not want to reinvent the wheel and wanted to see around on the internet if there were some nuget packages available that we could use. That way, we don’t have to write any DAO (data access object) code handling the parsing of the api request data. This was the time we arrived at the [fuelSDK](https://github.com/salesforce-marketingcloud/FuelSDK-CSharp), a nuget package that is available under the MIT license.

#FuelSdk, our savior?
After we found the package, we tested it out, to see if it delivered what we needed. Setting up the package was fairly easy as you just needed to install the package using nuget. The only additional thing developers need to do is to add some configuration to your project’s web config. The configuration exists mostly of api keys and instance urls and looks something like this:

```xml
<?xml version="1.0"?>
<configuration>
  <configSections>
    <section name="fuelSDK" type="FuelSDK.FuelSDKConfigurationSection, FuelSDK" />
  </configSections>
  <fuelSDK
    appSignature="none"
    clientId="YOUR_CLIENT_ID"
    clientSecret="YOUR_CLIENT_SECRET"
    authEndPoint="YOUR_AUTH_TSE"
    restEndPoint="YOUR_REST_TSE"
    useOAuth2Authentication="true" 
    applicationType="server"||"public"||"web" //if you are using oauth2 for public or web app. By default, this will be "server" 
    authorizationCode="AUTHORIZATION_CODE"
    redirectURI="REDIRECT_URI_FOR_PUBLIC/WEB_APP"
    accountId="TARGET_ACCOUNT_ID"
    scope="DATA_ACCESS_PERMISSIONS" />
</configuration>
```

When the configuration is done, you could simply add data to data extensions using this piece of code:
```csharp
var deRow = new ETDataExtensionRow {
                    AuthStub = client,
                    DataExtensionName = dataExtensionName,
                };
                
deRow.ColumnValues.Add("CustomerNumber", "Customer_" + i.ToString());
deRow.ColumnValues.Add("FirstName", "FirstName_" + i.ToString());
deRow.ColumnValues.Add("LastName", "LastName_" + i.ToString());

var derResponse = deRow.Post();
Assert.AreEqual(derResponse.Code, 200);
```

In this piece of code, we are adding values to a dictionary where each entry has as key the column name of the data extension’s column. This is the column we’ll be inserting this data into. The values of the dictionary entries are the actual (string based) data that we’ll be adding.

So, in order, to reach our goal, which is to add the data from a (Sitecore) form submit to a SFMC Data Extension, we’ll need a Save Action that executes the code above, but adjusted for that specific form and data extension. This means that the keys of the dictionary must be the right column names (no typos allowed!) and that the values should be the value of the right submitted form field. Although it is remarkable easy to use, it is not a silver bullet.

#Adding more fuel
The first issue, as you may notice, is that although adding this to a single form is easy and fast, adding this to multiple forms isn’t. This is because the shared code can’t be abstracted away. You’ll still need to build that dictionary with the right keys and values (typos not allowed) for each form. Apart from development time you must also consider the fact that this must be tested for each form on each environment which increases the cost a lot. On a side note, it might also take a while between the marketer or client asking for such a form submit action and the moment it is deployed and working on production. This is because you’ll need to follow the full software development cycle (build, test , release).

The second issue is that it is error prone. If a typo would slip in the code, especially the part of the dictionary (the column names and the field names to be more specific) you can experience massive delays. Not only that , you aren’t guaranteed that the code will work on different environments, as exactly (and when I mean exactly, I mean including the names of the fields)  the same forms are a must on each environment and that is something that is not possible in many cases.

The last issue is that the above code is not future proof: as soon as a data extension changes it won’t work and neither will it work in the case of a form change (renaming or removing fields). Also, every time you need a change (e.g. a form must change etc) you’ll need to adjust the code to cope with the change and redeploy and test it on all environments.

For those reasons and because Sitecore is such an open platform that can be easily extended, we’ve decided to experiment with our own Forms extension module. The idea is to build a Sitecore integrated application that does not require any coding nor deploys, is movable between environments and is easily adjustable in Sitecore for non tech savvy users. We will add soon the result of our experiments as a module for the Sitecore community.

If you are not sure that the module is something for you, I’ll be discussing the many features it brings to the users and developers in my future blogposts!

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/xg333m6e65yg9a89j05o.png)