Unlocking Efficiency: Designing a Modular Approach for Marketing Cloud REST API Integration

Unlocking Efficiency
Home Page

Unlocking Efficiency: Designing a Modular Approach for Marketing Cloud REST API Integration

In this tutorial, we will delve into the exciting world of Marketing Cloud REST API integration and explore how to design a modular approach for seamless integration using SSJS (Server-Side JavaScript).

Gone are the days of tangled and cumbersome integrations. With a modular approach, you'll learn how to break down your Marketing Cloud REST API integration into smaller, independent modules, making your code more organized, maintainable, and reusable.

We'll start by understanding the fundamentals of the Marketing Cloud REST API and how it can empower your marketing efforts. Then, we'll explore the power of SSJS, a versatile scripting language that allows you to harness the full potential of Salesforce's Marketing Cloud.

Throughout the tutorial, we'll guide you step-by-step, demonstrating how to design and implement a modular architecture for your Marketing Cloud REST API integration. You'll learn how to identify logical components, define their interfaces, and leverage SSJS to build robust, reusable modules.

By the end of this tutorial, you'll have a deep understanding of the modular approach to Marketing Cloud REST API integration and be equipped with the knowledge to design efficient, scalable, and maintainable integrations. Take your marketing efforts to the next level with this advanced tutorial on modular design in Marketing Cloud REST API integration with SSJS.

Step by Step to build Marketing Cloud REST API :

1. Create Install Package :

  • To learn how to create install package click here
    If you want check Marketing Cloud REST API v1 reference click here
    Review the permission ID, the path to the permission in Marketing Cloud, and the Installed Packages scope for each REST API resource. Click here

2. Create Data Extension :

  • Install Package
    Profile
  • APIMethods
    Profile
  • API Exception
    Profile

3. Populate data for Install Packages And Method API Details :

  • Method API Details
    Profile

4. Code Snippet :

  • DefineDataExtensionRetrieve
                                                
    <script runat="server">
    function DefineDataExtensionRetrieve(propName,operator,propValue,customerKey)
    {
        var simpleOperatorsPropsConfig = {
                                      "Property":propName
                                     ,"SimpleOperator":operator
                                     ,"Value" :propValue
                                   }
    
        var dataExtensionPropsConfig={
                                  "Init":customerKey
                                 ,"filter":SimpleOperators(simpleOperatorsPropsConfig)
                               }
        return dataExtensionPropsConfig;
    }
    </script>
                                                
                                                
  • DataExtensionRowsRetrieve
                                                
    <script runat="server">
    function DataExtensionRowsRetrieve(dataExtensionProps)
      {
        try{
        var dataExtension = DataExtension.Init(dataExtensionProps.Init);
        var dataSet = dataExtension.Rows.Retrieve(dataExtensionProps.filter);
        return dataSet;
        }
        catch(ex)
        {
          var APIExceptionDE = DataExtension.Init("APIException");
          APIExceptionDE.Rows.Add(
                                    {
                                       Message:ex.message
                                      ,Description:ex.description
                                      ,InnerException:ex.jintException
                                      ,FunctionName:"DataExtensionRowsRetrieve"
                                    });
           throw ex;
        }
      }
    </script>
                                                 
                                                
  • SimpleOperators
                                                
    <script runat="server">
    function SimpleOperators(simpleOperatorsProps)
      {
        try{
        var filter = { 
                        Property:simpleOperatorsProps.Property
                       ,SimpleOperator:simpleOperatorsProps.SimpleOperator
                       ,Value:simpleOperatorsProps.Value
                     };
        return filter;
        }
         catch(ex)
        {
          var APIExceptionDE = DataExtension.Init("APIException");
          APIExceptionDE.Rows.Add(
                                    {
                                       Message:ex.message
                                      ,Description:ex.description
                                      ,InnerException:ex.jintException
                                      ,FunctionName:"SimpleOperators"
                                    });
           throw ex;
        }
      }
    </script>
                                                
                                                
  • AccessToken
                                                
    <script runat="server">
    function AccessToken(dataExtensionPropsAPIConfig,dataExtensionPropsAPIMethod)
      {
        try{
        // Call DataExtensionRowsRetrieve function to retrieve for API Config
        var APIConfiDE=DataExtensionRowsRetrieve(dataExtensionPropsAPIConfig);
        
        // Call DataExtensionRowsRetrieve function to retrieve for APIMethod Config
        var APIMethodDE=DataExtensionRowsRetrieve(dataExtensionPropsAPIMethod);
        
        //Assign properties values for v2/Token
        var memberID = Platform.Recipient.GetAttributeValue('memberid');
        var clientId = APIConfiDE[0]["ClientID"];
        var clientSecret= APIConfiDE[0]["ClientSecret"];
        var grantType="client_credentials";
        var authAPI=APIConfiDE[0]["AuthAPI"];
        var contentType = "application/json";
        var headers= {
                        "client_id":clientId
                       ,"client_secret":clientSecret
                       ,"grant_type":grantType
                       ,"account_id": memberID
                     };
        var httpProtocol = APIMethodDE[0]["HttpProtocol"];
        var methodURL = APIMethodDE[0]["MethodURL"];
        
        var accessTokenResult = HTTP.Post(authAPI+methodURL, ContentType, Stringify(headers));
        return accessTokenResult;
        }
         catch(ex)
        {
          var APIExceptionDE = DataExtension.Init("APIException");
          APIExceptionDE.Rows.Add(
                                    {
                                       Message:ex.message
                                      ,Description:ex.description
                                      ,InnerException:ex.jintException
                                      ,FunctionName:"AccessToken"
                                    });
           throw ex;
        }
      }
    </script>
                                                
                                                
  • RESTAPIPOST
                                                
     <script runat="server">
      function InvokeRESTAPI(installPackageConfig,accessTokenConfig,methodAPIConfig,payload,key)
      {
        // Call AccessToken function to retrieve for Access Token
        var accessTokenResult=AccessToken(installPackageConfig,accessTokenConfig);
        var statusCode = accessTokenResult["StatusCode"];
        var response = accessTokenResult["Response"][0];
        var accessToken = Platform.Function.ParseJSON(response).access_token;
        var tokenType = Platform.Function.ParseJSON(response).token_type;
        //Write("Access Token :" + tokenType + " " +accessToken +"\n");
        
        var httpHeadersName=["Authorization"];
        var httpHeaderValues=[tokenType + " " +accessToken];
        
        // Call DataExtensionRowsRetrieve function to retrieve for API Config
        var APIConfiDE=DataExtensionRowsRetrieve(installPackageConfig);
        var restAPI=APIConfiDE[0]["RESTAPI"];
        
        // Call DataExtensionRowsRetrieve function to retrieve for APIMethod Config
        var APIMethodDE=DataExtensionRowsRetrieve(methodAPIConfig);
        var httpProtocol = APIMethodDE[0]["HttpProtocol"];
        var methodURL = APIMethodDE[0]["MethodURL"];
        var methodURL_1 = APIMethodDE[0]["MethodURL_1"];
        var methodURL_2 = APIMethodDE[0]["MethodURL_2"];
        var contentType = "application/json;charset=UTF-8";
        if(methodURL_1)
        {
          var URL=restAPI+methodURL+methodURL_1.replace("{configKey}",key);
        }
        else
        {
          var URL=restAPI+methodURL;
        }
        //Write('\n' + URL + '\n' );
        
        var postPayload=payload;
        //Write('\n' + Stringify(postPayload) + '\n'  );
        
        var httpResponse =HTTP.Post(URL,contentType,Stringify(postPayload),httpHeadersName,httpHeaderValues);
      
        return httpResponse;
      }
    </script>                                           
                                                
                                                
  • ModularAPIIntegration
                                                
     <script runat="server" >
      Platform.Load("core", "1");
      var contentDE = Platform.Function.ContentBlockByKey("DataExtensionRowsRetrieve");
      var contentSimpleOperators = Platform.Function.ContentBlockByKey("SimpleOperators");
      var contentAccessToken = Platform.Function.ContentBlockByKey("AccessToken");
      var contentRESTAPIPOST = Platform.Function.ContentBlockByKey("RESTAPIPOST");
      var contentDefineDataExtensionRetrieve = Platform.Function.ContentBlockByKey("DefineDataExtensionRetrieve");
      
      try{
        
        // Define properties for API Config
        var installPackageConfig=DefineDataExtensionRetrieve("APIConfig","Equals","TransactionalAPI","InstallPackages");
        
        // Define properties for Access token
        var accessTokenConfig=DefineDataExtensionRetrieve("MethodName","Equals","Request SFMC Token","APIMethod");
        
        // Define properties for REST API Method call
        var methodAPIConfig=DefineDataExtensionRetrieve("MethodName","Equals","{{UpdateThis}}","APIMethod");
        
        var payload="{{UpdateThis}}";
        var key="{{UpdateThis}}";
        var restResponse=InvokeRESTAPI(installPackageConfig,accessTokenConfig,methodAPIConfig,payload,key);
        Write(Stringify(restResponse));
      }
      catch(ex)
      {
        var APIExceptionDE = DataExtension.Init("APIException");
        APIExceptionDE.Rows.Add(
          {
            Message:ex.message
            ,Description:ex.description
            ,InnerException:ex.jintException
            ,FunctionName:"Main Block"
          }
        );
        Write(ex.message + '\n');
        Write(ex.description + '\n');
        Write(ex.jintException + '\n');
      }
    </script>                                                             
                                                
                                                

4. Code Resource :

  • Example : Asynchronously insert data into an identified data extension
    • Create a JS Code Resource Profile
    • Empty Code Resource and pull the "ModularAPIIntegration" code snippet Profile
    • Update the code to call "/data/v1/async/dataextensions/key:{configKey}/rows" as highlighted below Profile
    • Final code change as highlighted below Profile

5. Full Code :

                                            
 <script runat="server" >
  Platform.Load("core", "1");
  var contentDE = Platform.Function.ContentBlockByKey("DataExtensionRowsRetrieve");
  var contentSimpleOperators = Platform.Function.ContentBlockByKey("SimpleOperators");
  var contentAccessToken = Platform.Function.ContentBlockByKey("AccessToken");
  var contentRESTAPIPOST = Platform.Function.ContentBlockByKey("RESTAPIPOST");
  var contentDefineDataExtensionRetrieve = Platform.Function.ContentBlockByKey("DefineDataExtensionRetrieve");
  
  try{
    
    // Define properties for API Config
    var installPackageConfig=DefineDataExtensionRetrieve("APIConfig","Equals","TransactionalAPI","InstallPackages");
    
    // Define properties for Access token
    var accessTokenConfig=DefineDataExtensionRetrieve("MethodName","Equals","Request SFMC Token","APIMethod");
    
    // Define properties for REST API Method call
    var methodAPIConfig=DefineDataExtensionRetrieve("MethodName","Equals","Upsert Row - DE Key Async","APIMethod");
    
    var payload={
    "items": [
      {
        "SubscriberKey": "b2.shashi@gmail.com",
        "FirstName": "Sasee",
        "LastName": "Prasad",
        "Email": "b2.shashi@gmail.com"
      },
       {
        "SubscriberKey": "shashi@gmail.com",
        "FirstName": "Sasee",
        "LastName": "Prasad",
        "Email": "b2.shashi@gmail.com"
      }
    ]
  }
    
    var key="UpsertRowDE";
    var restResponse=InvokeRESTAPI(installPackageConfig,accessTokenConfig,methodAPIConfig,payload,key);
    Write(Stringify(restResponse));
  }
  catch(ex)
  {
    var APIExceptionDE = DataExtension.Init("APIException");
    APIExceptionDE.Rows.Add(
      {
        Message:ex.message
        ,Description:ex.description
        ,InnerException:ex.jintException
        ,FunctionName:"Main Block"
      }
    );
    Write(ex.message + '\n');
    Write(ex.description + '\n');
    Write(ex.jintException + '\n');
  }
</script>                                                                             
                                            
                                            

6. Save, Publish and Run


7. Don't forget to watch the video.

Conclusion

By adopting a modular approach in designing your Marketing Cloud REST API integration with SSJS, you have unlocked the power of reusability and efficiency. You are now equipped with the knowledge and skills to build robust, maintainable, and scalable integrations that can supercharge your marketing efforts. Embrace the modular mindset and elevate your Marketing Cloud integration to new heights, making your code cleaner, more manageable, and future-proof. Start designing your modular Marketing Cloud REST API integration today and experience the benefits of a streamlined and agile marketing automation workflow.



Comments


Knowledge Article

Most Viewed

CLOUD PAGE ENABLEMENT - PART 1

EMAIL NOT SENT IN JOURNEY BUILDER

CONSIDERATIONS FOR JOURNEY BUILDER

Journey Builder REST API Documentation

Preference Center Demystified

Popular Posts

CLOUD PAGE ENABLEMENT - PART 1

EMAIL NOT SENT IN JOURNEY BUILDER

CONSIDERATIONS FOR JOURNEY BUILDER

Journey Builder REST API Documentation

Preference Center Demystified

SEND LOG EANBLEMENT

Share with Friends

Disclaimer:

The information provided on this technical blog is for general informational purposes only. As a SFMC (Salesforce Marketing Cloud) Technical Architect, I strive to offer accurate and up-to-date content related to SFMC and its associated technologies. However, please note that technology is constantly evolving, and the information provided may become outdated or inaccurate over time.

The content published on this blog represents my personal views and experiences as a SFMC Technical Architect and does not necessarily reflect the official views or opinions of any organization or employer I may be affiliated with.

While I make every effort to ensure the accuracy and reliability of the information presented, I cannot guarantee its completeness, suitability, or applicability to your specific circumstances. Therefore, it is essential to verify any information provided and make your own independent assessments or seek professional advice if needed.

Furthermore, any actions taken based on the information provided on this blog are at your own risk. I shall not be held liable for any damages, losses, or inconveniences arising from the use of the information presented here.

Please keep in mind that SFMC and its associated technologies are complex and require technical expertise for proper implementation and management. It is recommended to consult with qualified professionals or official SFMC documentation for comprehensive guidance.

Finally, please note that any product or company names mentioned on this blog are trademarks or registered trademarks of their respective owners. The mention of these trademarks or registered trademarks does not imply any endorsement or affiliation with the blog.

By accessing and using this blog, you agree to the terms of this disclaimer. If you do not agree with any part of this disclaimer, please refrain from using this blog.