Loading
Ongoing maintenance for Salesforce HelpRead More
Feature degradation | Gmail Email delivery failureRead More
Table of Contents
Select Filters

          No results
          No results
          Here are some search tips

          Check the spelling of your keywords.
          Use more general search terms.
          Select fewer filters to broaden your search.

          Search all of Salesforce Help
          Custom Input and Output for Omnistudio Data Mappers in Omnistudio

          Custom Input and Output for Omnistudio Data Mappers in Omnistudio

          By default, Data Mappers handle JSON and XML data. To handle other data formats, you can configure a Data Mapper to use a custom input or output that you implement is a custom class. For example, you can define a Data Mapper Transform that accepts CSV-formatted data and outputs it as JSON.

          Options are as follows:

          • Data Mapper Load: Custom input (output is always a Salesforce object)

          • Data Mapper Transform: Custom input and output

          • Data Mapper Extract: Custom input and output

          To configure a Data Mapper to use a custom input or output, set its type to Custom. Then specify the class that contains the serialize and deserialize methods that perform the operation. The following table shows properties for a Data Mapper Transform configured with a custom input and output.

          Property Value
          Data Mapper Interface Name Custom Serialization Transform
          Interface Type Transform
          Input Type Custom
          Custom Input Class CSVProcessor
          Output Type Custom
          Custom Output Class CSVProcessor

          For ease of mapping, you can paste sample input into the Expected Input and Expected Output panes.

          To create the logic required to custom input and output, you must define a custom class that implements Callable. For custom output, implement the serialize method. For custom input, implement the deserialize method. You can’t rename the input and output parameters.

          The following example shows the basic structure of a customer serialization and deserialization class.

          global with sharing class PreprocessorClassExample implements Callable {
             public Object call(String action, Map<String, Object> args) {
          
                  Map<String, Object> input = (Map<String, Object>)args.get('input');
                  Map<String, Object> output = (Map<String, Object>)args.get('output');
                  Map<String, Object> options = (Map<String, Object>)args.get('options');
          
                  return invokeMethod(action, input, output, options);
              }
              private Object invokeMethod(String methodName, Map<String,Object> input, Map<String,Object> output, Map<String,Object> options) {
                  if (methodName == 'serialize') {
                      return serialize(input, output);
                  }
                  else if (methodName == 'deserialize') {
                      return deserialize(input, output);
                  }
                  return false;
              }
              /*
                  Serializes Apex objects into JSON content. Return String json
              */
              global Boolean serialize(Map<String, Object> input, Map<String, Object> output) {
                  String jsonString = '';            
                  // code
                  output.put('output', jsonString); // JSON String
                  return true;
              }
              /*
                  Deserializes the specified JSON string into collections of primitive data types. Return Object ((Map<String, Object>))
              */
              global Boolean deserialize(Map<String, Object> input, Map<String, Object> output) {
                  Map<String, Object> returnMap = new Map<String, Object>();
                  // code
                  output.put('output', returnMap); // ---> collections of primitive data types Map<String, Object>, List<Map<String, Object>>()
                  return true;
              }
          }

          The following example serializes and deserializes CSV data.

          global with sharing class CSVProcessor implements Callable {
              public Object call(String action, Map<String, Object> args) {
          
                  Map<String, Object> input = (Map<String, Object>)args.get('input');
                  Map<String, Object> output = (Map<String, Object>)args.get('output');
                  Map<String, Object> options = (Map<String, Object>)args.get('options');
          
                  return invokeMethod(action, input, output, options);
             }
             private Object invokeMethod(String methodName, Map<String,Object> input, Map<String,Object> output, Map<String,Object> options)
             {
             System.debug('METHOD NAME >>> ' + methodName);
                 if (methodName == 'deserialize')
                 {
                     return deserialize(input, output);
                 }
                 return false;
             }
             /*
             Example Output: 'Column2,Column1\nvalue0,value1.0\nvalue0.1,value1.1';
             */
             /*
             Deserializes the specified JSON string into collections of primitive data types. Return Object ((Map<String, Object>))
             Input: 'Column2,Column1\nvalue0,value1.0\nvalue0.1,value1.1';
             Output:
             [
                 {
                     "Column1Test": "value1.0",
                     "Column2Test": "value0"
                 },
                 {
                     "Column1Test": "value1.1sl",
                     "Column2Test": "value0.1"
                 }
             ]
             */
                  public class csvInput {
                      @AuraEnabled
                      public string VersionData;
                  }
                  global Boolean deserialize(Map<String, Object> input, Map<String, Object> output)
             {
                 System.debug(input);
                 System.debug(input.get('input'));
                 System.debug(input.toString());
                 //csvInput s = (csvInput)JSON.deserialize((string)input.get('input'), csvInput.class);
                 Object data = input.get('input');
                 csvInput s;
                 if(data instanceof String) {
                     s = (csvInput)JSON.deserialize(String.valueOf(data), csvInput.class);
                 } else { // try to preserve the source formatting
                     s = (csvInput)JSON.deserialize(JSON.serialize(data), csvInput.class);
                 }
                 Blob decodedInputBlob = System.EncodingUtil.base64Decode(s.VersionData);
                 String decodedCsvString = decodedInputBlob.toString();
                 Object inputValue = decodedCsvString;
                 System.debug(inputValue);
                 if (inputValue != null && inputValue InstanceOf String)
                 {
                     List<String> valueSet = ((String)inputValue).split('\n');
                     List<Map<String, String>> csvList = new List<Map<String, String>>();
                     List<String> columns = new List<String>();
                     for (Integer i = 0; i < valueSet.size(); i++)
                     {
                         String value = valueSet[i];
                         if (String.isBlank(value))
                         {
                             continue;
                         }
                         if (i == 0)
                         {
                             List<String> valSet = value.split(',');
                             for (Integer y = 0; y < valSet.size(); y++)
                             {
                                 columns.add(valSet[y]);
                             }
                         }
                         else
                         {
                             List<String> valSet = value.split(',');
                             if (columns.size() >= valSet.size())
                             {
                                 Map<String, String> rows = new Map<String, String>();
                                 for (Integer z = 0; z < valSet.size(); z++)
                                 {
                                     rows.put(columns[z], valSet[z]);
                                 }
                                 csvList.add(rows);
                             }
                         }
                     }
                     output.put('output', csvList);
                     //Map<String, Object> returnMap = new Map<String, Object>();
                     //output.put('output', returnMap);
                     System.debug(output);
                     return True;
                 }
                 return False;
             }
          }

          For example, suppose your CSV file has this content:

          Name

          Email

          Phone

          Mary Baker

          mbaker@example.com

          415-555-3331

          Joe Baker

          jbaker@example.com

          415-555-3332

          Russell Baker

          rbaker@example.com

          415-555-3333

          The example CSVProcessor class converts it to this JSON input:

          [
            {
              "Name": "Mary Baker",
              "Email": "mbaker@example.com",
              "Phone": "415-555-3331"
            },
            {
              "Name": "Joe Baker",
              "Email": "jbaker@example.com",
              "Phone": "415-555-3332"
            },
            {
              "Name": "Russell Baker",
              "Email": "rbaker@example.com",
              "Phone": "415-555-3333"
            }
          ]
           
          Loading
          Salesforce Help | Article