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.
Name | Nullable |
---|---|
SubscriberKey | No |
EmailAddress | No |
PostalCode | Yes |
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:
- Generate a token.
- 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.
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).
Thanks so much Ivan for this post! For anyone else trying to get this to work for a Journey Entry, I had to define the following scopes to get this to work…
Journeys:Read, Write, Execute
List and Subscribers:Read, Write
Data Extensions:Read, Write
Hope it helps someone!
Where Do I execute this code? Can I use it from an external web?
This is an API call, therefore yes 🙂 Try it using Postman first though.
Hi Ivan,
Thank you for this!
Are you able to create an example for form submission like you have in the example?
I’ll add it to my todo list 😉
Is there a WSProxy version of this implementation?
That would have been too easy 😉 I’ve been told that there is an API ready for it since January but they still didn’t document it 🙁
This is an awsome How-To. I Had trouble follwoing the steps as I am quite new to ssjs and Rest Apis, but I have been able to solve my Task with your resources. Thanks alot!
I was wondering if we can use above code to send email when new record gets added to DE. If I do it with script activity in the automation, I have to run it hourly.
Hey! You could but why? You can simply trigger a Triggered Send Interaction from your Automation. No need to use a Journey API event.
Hi Ivan,
Thanks for the solution,what incase if we have to send the email to multiple subscribers ,then how can we achieve through this .
a loop 😉