How to Iterate Each Record with Custom Functions in AC

In the world of marketing automation with Adobe Campaign, there are situations where you need to perform tasks for each individual record. This can happen when the default out-of-the-box functions do not provide the needed functionality. Tasks might include calling a third-party service, sending web requests, or enriching your record set with personalized data based on third-party responses. The need arises to iterate through records and execute custom functions for each one, no matter the targeting method used (Query, Read List, Union, Intersection, Split, Enrichment, Change dimension, etc.).

A critical aspect of this process is dynamically capturing and handling the name of the targeting schema, which may change or be generated on the fly without following a consistent naming convention. To solve this, you need a flexible approach that does not depend on the schema name itself but rather uses dynamic targeting mechanisms.

Step-by-Step Process for Iterating Records

Here’s how to accomplish this using Adobe Campaign workflows:

1. Capture the Targeting Schema Dynamically

First, dynamically capture the name of the targeting schema using a variable vars.targetSchema. This will ensure flexibility as the schema name could vary with each iteration..

//Get the schema name (skipping namespace)
var schemaName = vars.targetSchema.substring(vars.targetSchema.indexOf(":") + 1);

The variable schemaName assigned above plays a critical role as it will be used in steps ahead while iterating the records.

2. Query the Record Set

After capturing the schema name, you can query the record set from the previous step (targeting schema) to retrieve the records.

var datalayer = {
  get: {
    records: function( ) {
      var query = xtk.queryDef.create(  
        <queryDef schema={vars.targetSchema} operation="select">
          <select>
            <node alias="Id" expr="@Id"/>
            <node alias="Field1" expr="@Field1"/>
            <node alias="Field2" expr="@Field2"/>
            <node alias="Field3" expr="@Field3"/>
            <node alias="CreationDate" expr="@CreationDate"/>
          </select>
          <where>
            <condition expr={"@id IS NOT NULL"} />
          </where>
        </queryDef>
      ).ExecuteQuery();

      return query;
    }
  }
}

3. Iterate Through the Records and Call Custom Function

Use the processResponses method to iterate through each record in the targeting schema and call a custom function for each one.

var businessLogic = {
  createTempResponse : function(response, myResponseVariable){
    return {
            Id:response.Id,
            Field1:response.Field1,
            Field2:response.Field2,
            Field3: response.Field3,
            CreationDate: response.CreationDate,
            myVariable: myResponseVariable
          }
  },
  processResponses : function(records, schemaName){
    //Iterating through the record set here
    for each ( var record in records[schemaName] ) {
      
      myResponseVariable = myCustomFunction(record.Field1, record.Field2);
      datalayer.save( businessLogic.createTempResponse(record, myResponseVariable));
      
    }
  },
  //This is the custom function that calls third party or perform any specific functionality not available in AC
  myCustomFunction: function(field1, field2){
    
    //Add custom function code here that say returns a data stored in variable myResponseVariable
    return myResponseVariable;
  }
}

The method myCustomFunction() is the custom method which can be used to add custom behaviors. All the required parameters from targeting schema can be passed to this method and responses can be captured and stored in temprary table if required.
The method processResponses() is iterating through the recordset and uses schemaName to fecth the value of each field in teh record.

4. Save the Results to a Temporary Table

The results from each record can be saved into a temporary table, which can then be used for further enrichment or processing later in the workflow.

var datalayer = {
  save: function ( data ) {
    //Save record to Temporary Table "TempResponses"
      xtk.session.Write(
        <TempResponses xtkschema="cus:TempResponses" _operation="insert" Id={data.Id}
          Field1={data.Field1}  Field2={data.Field2} Field3 = {data.Field3} CreationDate = {data.CreationDate}, Field4 = {data.myVariable} />);
     }
}

5. Call the Consolidated Functions

Finally, consolidate the steps into one seamless flow to execute the process. The records will be iterated, and the custom functions will be applied.

var records = datalayer.get.records();

businessLogic.processResponses(records, schemaName);

So, finally the whole code would look something like this:

//Get the schema name (skipping namespace)
var schemaName = vars.targetSchema.substring(vars.targetSchema.indexOf(":") + 1);

/*****************************************************************************************************/
var datalayer = {
  get: {
    records: function( ) {
      var query = xtk.queryDef.create(  
        <queryDef schema={vars.targetSchema} operation="select">
          <select>
            <node alias="Id" expr="@Id"/>
            <node alias="Field1" expr="@Field1"/>
            <node alias="Field2" expr="@Field2"/>
            <node alias="Field3" expr="@Field3"/>
            <node alias="CreationDate" expr="@CreationDate"/>
          </select>
          <where>
            <condition expr={"@id IS NOT NULL"} />
          </where>
        </queryDef>
      ).ExecuteQuery();

      return query;
    }
  }
  save: function ( data ) {
    //Save record to Temporary Table "TempResponses"
      xtk.session.Write(
        <TempResponses xtkschema="ahl:TempResponses" _operation="insert" Id={data.Id}
          Field1={data.Field1}  Field2={data.Field2} Field3 = {data.Field3} CreationDate = {data.CreationDate}, Field4 = {data.myVariable} />);
     }
}
/*****************************************************************************************************/

var businessLogic = {
  createTempResponse : function(response, myResponseVariable){
    return {
            Id:response.Id,
            Field1:response.Field1,
            Field2:response.Field2,
            Field3: response.Field3,
            CreationDate: response.CreationDate,
            myVariable: myResponseVariable
          }
  },
  processResponses : function(records, schemaName){
    //Iterating through the record set here
    for each ( var record in records[schemaName] ) {
      
      myResponseVariable = myCustomFunction(record.Field1, record.Field2);
      datalayer.save( businessLogic.createTempResponse(record, myResponseVariable));
      
    }
  },
  //This is the custom function that calls third party or perform any specific functionality not available in AC
  myCustomFunction: function(field1, field2){
    
    //Add custom function code here that say returns a data stored in variable myResponseVariable
    return myResponseVariable;
  }
}
/*****************************************************************************************************/

var records = datalayer.get.records();

businessLogic.processResponses(records, schemaName);

The workflow configuration for the use case is depicted as below:

Workflow Configuration:

Once the custom functions and logic are set up, you can configure your workflow in Adobe Campaign to process each record using the aforementioned logic.

This solution ensures that you can iterate over large sets of records, apply personalized logic, and even call third-party APIs or services. The ability to dynamically capture schema names and use customized workflows gives you great flexibility and scalability.

(Visited 3,889 times, 1 visits today)