Using Entry Source Data in Journey Builder Custom Activities

Journey Builder Custom Activities for Salesforce Marketing Cloud enable you to extend the platform capabilities by creating highly configurable interfaces which call externally-hosted endpoints when a Contact arrives at a custom activity in a published Journey.

There are several dependencies required by custom activities, which include Postmonger — a lightweight messaging Javascript utility for cross-domain messaging that is used to send data and event related information between Journey Builder and a custom activity interface, when a user configures a custom activity.

Use Cases

The available Postmonger methods and events are provided on developer.salesforce.com, however a common use case for custom activities is to retrieve Data Extension fields from the Journey Entry Source. For example, you might want to include a dropdown menu in your custom activity interface so a user can select a specific entry source field, then when the Journey is published, the field value for the Contact is included in the payload to the externally hosted ‘execute’ endpoint. Or, perhaps you want to retrieve the entire schema of the entry source, then include these field values (i.e. Journey Data) when the execute endpoint is called.

Custom Activities include the ability to define field values from the Data Source through support of Data Binding in the Event Context, which comprise of mustache formatted strings in the activity’s config.json file (a definition file that is loaded when the custom activity interface is opened). However, it’s generally not practical to define Entry Source fields in the config.json file, as these values will change between Journeys. Specifically, the format requires the assigned entry event key (a UUID value) along with the field name in the following format:

{{Event.entry-event-key.field-name}}

As a solution for these use cases, there are two undocumented Postmonger calls which enable the entry source schema to be retrieved, which can then be used by the custom activity interface, and/or programatically added as inArguments to to include defined key/value pairs when the execute endpoint is called.

Retrieving the Entry Source Schema

The connection.trigger Postmonger method can be used to retrieve the Entry Source schema as follows:

connection.trigger('requestSchema');

This returns the entire Data Extension schema of the Journey Entry Source, for example:

[
   {
      "key":"Event.APIEvent-1a11c19c-7952-488a-99d7-069fa2bc543c.Id",
      "type":"Text",
      "length":18,
      "default":null,
      "isNullable":null,
      "isPrimaryKey":null
   },
   {
      "key":"Event.APIEvent-1a11c19c-7952-488a-99d7-069fa2bc543c.FirstName",
      "type":"Text",
      "length":40,
      "default":null,
      "isNullable":null,
      "isPrimaryKey":null
   },
   {
      "key":"Event.APIEvent-1a11c19c-7952-488a-99d7-069fa2bc543c.LastName",
      "type":"Text",
      "length":80,
      "default":null,
      "isNullable":null,
      "isPrimaryKey":null
   }
]

In turn, the schema can then be evaluated by listening for the requestedSchema event using the connection.on method:

connection.on('requestedSchema', function (data) { /* do something */ });

Entry Source fields for Execute Call

The following example demonstrates how Postmonger can be used to retrieve the Entry Source schema and push the fields as inArguments, so the field values (i.e. Journey Data) are included in the payload sent to the execute endpoint when a Contact arrives at the custom activity in a published journey:

var connection = new Postmonger.Session();
var payload = {};

$(window).ready(onRender);

connection.on('initActivity', initialize);
connection.on('clickedNext', save);

function onRender() {
  connection.trigger('ready');
}

function initialize(data) {

  if (data) {
    payload = data;
  }

  connection.trigger('requestSchema');
  connection.on('requestedSchema', function (data) {

    // add entry source attributes as inArgs
    const schema = data['schema'];

    for (var i = 0, l = schema.length; i < l; i++) {
        var inArg = {};
        let attr = schema[i].key;
        let keyIndex = attr.lastIndexOf('.') + 1;
        inArg[attr.substring(keyIndex)] = '{{' + attr + '}}';
        payload['arguments'].execute.inArguments.push(inArg);
    }
  });

  let argArr = payload['arguments'].execute.inArguments;

}

function save() {

  /* the following code is optional, but provides an example of 
     how to append additional key/value pair(s) as inArguments, 
     for example, a form field value from the custom activity html

  var fieldVal = document.getElementById('your-field-id').value;
  var keyObj = { InsertKeyName: fieldVal };
  payload['arguments'].execute.inArguments.push(keyObj);

  */

  payload.metaData.isConfigured = true;
  connection.trigger('updateActivity', payload);

}

The for loop in this code programatically builds an array of entry source data as key/value pairs in the required data binding syntax, for example:

[
   {
      "Id":"{{Event.APIEvent-1a11c19c-7952-488a-99d7-069fa2bc543c.Id}}"
   },
   {
      "FirstName":"{{Event.APIEvent-1a11c19c-7952-488a-99d7-069fa2bc543c.FirstName}}"
   },
   {
      "LastName":"{{Event.APIEvent-1a11c19c-7952-488a-99d7-069fa2bc543c.LastName}}"
   }
]

The connection.trigger method (on the last line) updates the custom activity with these key/value pairs so they can be used as inArguments for the execute endpoint (as an alternative to hardcoding the key/value pairs in config.json).

Including Entry Source fields in a form field

The following example indicates how to retrieve the entry source schema, then display field values in the custom activity interface:

var connection = new Postmonger.Session();
var payload = {};

$(window).ready(onRender);

connection.on('initActivity', initialize);
connection.on('clickedNext', onClickedNext);

function onRender() {

    connection.trigger('ready');

    $('#select1').change(function() {
        var name = $('#select1').find('option:selected').html();
        console.log('PNR Field selected : ', name);
    });
}

function initialize(data) {
    $('#step1').show();
    if (data) {
        payload = data;
    }

    connection.trigger('requestSchema');
    connection.on('requestedSchema', function(data) {
        const schema = data['schema'];

        for (var i = 0, l = schema.length; i < l; i++) {
            let attr = schema[i].key;

            // populate select dropdown 
            let option = $('<option></option>')
                .attr('id', schema[i].key)
                .text(schema[i].name);

            $('#idField').append(option);

        }
    });
}

function onClickedNext() {
    var idField = $('#idField').find('option:selected').html();
    payload['arguments'].execute.inArguments.push({
        idField: idField
    })
    payload['metaData'].isConfigured = true;
    connection.trigger('updateActivity', payload);
}

The for loop creates option tags which are appended to an empty select tag in the html file. The following code can then be included in the index.html file (which is used to render the custom activity interface).

  <select class="slds-select" id="idField"></select>

When the user has finished configuring the activity (by clicking the Next button). the connection.trigger method (on the last line) updates the custom activity with the selected field as an inArgument (using idField as the key), so the corresponding field value will be sent to the execute endpoint when a Contact reaches the activity in a published journey.

Summary

Journey Builder Custom Activities extend the customer journey management and integration capabilities of the platform. The additional ability to retrieve Journey Entry Source fields and display them in a custom activity or include field values in a payload to an execute endpoint is an invaluable feature, as it unlocks many data integration use cases.


Want to do more with Journey Builder and learn how to improve the integration capabilities of your own Marketing Cloud platform? Get in touch! We’d love to discuss how you can customize your Salesforce Marketing Cloud to deliver the best possible experience for your clients and maximize the ROI for your organization.

You may be interested in

The New 2024 Anti-Spam Regulations

What is the new Google/Yahoo anti-spam upgrade? Google and Yahoo are aiming to improve security and reduce the amount of spam received by their users by upgrading their defence system, in what they are calling “one of the largest defence upgrades in recent years”. This upgrade uses AI to detect and flag spammy emails, which […]

Read More

Data Harmonization in Salesforce Data Cloud

This post in the Data Cloud Primer series explains the data harmonization process in Salesforce Data Cloud. Data Cloud accepts data from a variety of sources. Harmonization refers to the process of transforming (or modeling) different data sources into one. Once data has been unified (or harmonized) into a standardized data model, it can then […]

Read More

Sign up for the latest tips & news from CloudKettle

Thank you for subscribing.