How to trigger a Journey API Entry event with AMPscript and server-side JavaScript

How to trigger a Journey API Entry event with AMPscript and server-side JavaScript

This article explains how trigger a Journey API Entry event with AMPscript and server-side Javascript in Salesforce Marketing Cloud.

Not a fan of reading? Jump to the code snippet.

Why use it

Why indeed!? We can accomplish the same result by selecting Data Extension as Entry Source in a Journey. Or can we really?

By using the API Entry Event, we are able to make a customer enter the journey instantly, without waiting for the scheduling assistant to run through the new records.

Therefore, if the first Activity in your Journey is an Email, it will be sent without delay.

Before we start

Before we can start injecting our customers into Journeys, we first need to create a database, a Journey and an API integration app.

Data Extension

Please create a Data Extension as follows.

NameNullable
SubscriberKeyNo
EmailAddressNo
PostalCodeYes

Journey

Create a Journey from scratch, add an API Event as Entry Source, configure it by adding an event and selecting our new Data Extension, add some Activities, make tea, activate the Journey and be golden.

API integration app

This is the complicated part, please bear with me.

First, you need to access your Marketing Cloud Setup options, where under the Platform Tools category you will find Installed Packages menu in the Apps folder.

Then, install a new package and add a Component named API Integration. Please choose Server-to-Server integration type and define the scope of your integration according to your liking (but of course, allow it write in a Data Extension).

We are all set! We can start building our code, which will work in Automations, Emails and Cloud Pages.

Pulling the trigger

The flow we are going to build is very simple:

  1. Generate a token.
  2. Use the token to send the customer data to the Journey.

But before we can do it, let’s gather all the access information from the Journey and the API Integration.

API configuration

Please have a look at the following object variables.

Data variable contains the customer data imported from AMPscript.

Setup variable on the other hand contains the secret keys for the API Integration and the Journey Event.

The first 4 values (authBaseURI, restBaseURI, clientId and clientSecret) can be found in your API Integration component from the Marketing Cloud setup.

The last value (eventDefinitionKey) is in the API Event of your Journey.

var data = {
	SubscriberKey: Variable.GetValue("@SubscriberKey"),
	EmailAddress: Variable.GetValue("@EmailAddress"),
	PostalCode: Variable.GetValue("@PostalCode")
}

var setup = {
	authBaseURI: "https://xxxxxxxxxxxxxxxxxxxx-xxxxxxx.auth.marketingcloudapis.com/",
	restBaseURI: "https://xxxxxxxxxxxxxxxxxxxx-xxxxxxx.rest.marketingcloudapis.com/",
	clientId: "xxxxxxxxxxxxxxxxxxxxxxxx",
	clientSecret: "xxxxxxxxxxxxxxxxxxxxxxxx",
	eventDefinitionKey: "APIEvent-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

Keep in mind that this part contains critical information about our API Integration and Journey.

Keep it safe! Encode it if you must, put it in the dark corner of your Marketing Cloud configuration and don’t tell anyone.

Get a Token

To generate a token for our API call, we need to make an HTTP request to the API Integration using the secret keys and the authentication URL.

function getToken(setup) {

    var config = {
        url : setup.authBaseURI + "v2/token",
        contentType : "application/json",
        payload : {
            "client_id": setup.clientId,
            "client_secret": setup.clientSecret,
            "grant_type": "client_credentials"
        }
    }

    var req = HTTP.Post(config.url, config.contentType, Stringify(config.payload));

    if (req.StatusCode == 200) {
        var res = Platform.Function.ParseJSON(req.Response[0]);
        return res.access_token;
    } else {
        return false;
    }

}

Trigger the event

Once we have the token, we can use it to place a second HTTP request to the API Integration along with the customer data we want to send to the Journey.

This time, we are using the REST URL.

function triggerEvent(token, setup, data) {

    var config = {
        url : setup.restBaseURI + "interaction/v1/events",
        contentType : "application/json",
        headerName : ["Authorization"],
        headerValue : ["Bearer " + token],
        payload : {
            ContactKey: data.SubscriberKey,
            EventDefinitionKey: setup.eventDefinitionKey,
            Data: data
        }
    }

    var req = HTTP.Post(config.url, config.contentType, Stringify(config.payload), config.headerName, config.headerValue);

    if (req.StatusCode == 201) {
        var res = Platform.Function.ParseJSON(req["Response"][0]);
        if (res.eventInstanceId != null && res.eventInstanceId != "") return true;
    } else {
        return false;
    }
    
}

That’s it! Nothing too complicated.

Full code

%%[

    SET @SubscriberKey = "0x00000001"
    SET @EmailAddress = "icedtea@bag.com"
    SET @PostalCode = "2000"

]%%
<script runat="server">

    Platform.Load("Core", "1.1.1");

    var data = {
        SubscriberKey: Variable.GetValue("@SubscriberKey"),
        EmailAddress: Variable.GetValue("@EmailAddress"),
        PostalCode: Variable.GetValue("@PostalCode")
    }

    var setup = {
		authBaseURI: "https://xxxxxxxxxxxxxxxxxxxx-xxxxxxx.auth.marketingcloudapis.com/",
		restBaseURI: "https://xxxxxxxxxxxxxxxxxxxx-xxxxxxx.rest.marketingcloudapis.com/",
		clientId: "xxxxxxxxxxxxxxxxxxxxxxxx",
		clientSecret: "xxxxxxxxxxxxxxxxxxxxxxxx",
		eventDefinitionKey: "APIEvent-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
	}

    try {
        var token = getToken(setup);
        var success = false;
        if (!!token) success = triggerEvent(token, setup, data); 
        if (!!success) Write("Subscriber was successfully injected into the Journey"); 
        else  Write("Failed to inject subscriber into the Journey");
    } catch (err) {
        Write("Error: " + Stringify(err));
    }

    function getToken(setup) {

        var config = {
            url : setup.authBaseURI + "v2/token",
            contentType : "application/json",
            payload : {
                "client_id": setup.clientId,
                "client_secret": setup.clientSecret,
                "grant_type": "client_credentials"
            }
        }

        var req = HTTP.Post(config.url, config.contentType, Stringify(config.payload));

        if (req.StatusCode == 200) {
            var res = Platform.Function.ParseJSON(req.Response[0]);
            return res.access_token;
        } else {
            return false;
        }

    }

    function triggerEvent(token, setup, data) {

        var config = {
            url : setup.restBaseURI + "interaction/v1/events",
            contentType : "application/json",
            headerName : ["Authorization"],
            headerValue : ["Bearer " + token],
            payload : {
                ContactKey: data.SubscriberKey,
                EventDefinitionKey: setup.eventDefinitionKey,
                Data: data
            }
        }

        var req = HTTP.Post(config.url, config.contentType, Stringify(config.payload), config.headerName, config.headerValue);

        if (req.StatusCode == 201) {
            var res = Platform.Function.ParseJSON(req["Response"][0]);
            if (res.eventInstanceId != null && res.eventInstanceId != "") return true;
        } else {
            return false;
        }
        
    }

</script>

Troubleshooting

Please make sure that your API Integration is properly configured.

For exemple, this code uses the v2 authentication process to generate the token, which means that if your API Integration has been set up some time ago, it might still use v1 and in this case the code won’t work.

Considerations

Please note that when the data is registered in the Data Extension, there is no validation on the type of the field.

Therefore, there is a risk of invalid data being pushed.

For exemple, we can push test@@test.com into an EmailAddress field.

Have I missed anything?

Please poke me with a sharp comment below or use the contact form.

Pay me a coffee

Want to say thanks? Pay me a coffee! Remember, I turn coffee into code.

  1. It’s been sometime since I’ve used this method, however, I do recall using a standard DE with just the subscriber key. The email address we used was just from the root DE (contact attribute).

Leave a Reply

Your email address will not be published. Required fields are marked *

Salesforce Marketing Cloud
Up Next:

3 methods for better segmentation in SFMC 

3 methods for better segmentation in SFMC