Many times we get stuck in situations where we have to perform a task for each record particularly when the default out-of-box functions provided by Adobe Campaign does not provide the required capability. The task could be anything like calling a third party or sending web request for each record with personalized data and capturing the responses from third party and back enriching our record set based on responses. So, the ask is iterating through the records irrespective of targeting (Query, Read List, Union, Intersection, Split, Enrichment, Change dimension etc) and call that custom function for each record.
Another key important point to be taken care here, is the name of targeting schema itself which we have to iterate. The name could be generated dynamically or assigned on the run without being taken care of with proper naming convention. So, we need to do something flexible enough that it should not depend on the nomenclature of targeting schema.
Below are the basic steps that would help solving the problem here:
- Capturing the name of targeting schema that exists at previous step dynamically using variable
vars.targetSchema
.//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. - Querying the record set received from previous targeting.
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; } } }
- Iterating the records, calling custom function and recording the responses.
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 methodprocessResponses()
is iterating through the recordset and usesschemaName
to fecth the value of each field in teh record. - We can Save the result in a temporary table and can later use it through enrichment to map back to targeting through primary key (@id in our case) and do further tasks 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} />); } }
- Now, the last part is to call the consolidate these bits and pieces and call them to make it work.
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:
Enjoy!!