I have a custom object named "application" that is associated with People/Leads. I'm aiming to incorporate the fields from the "application" into an email. This email should be triggered whenever there is a change in the status of any application field. To achieve this, I'm utilizing a velocity email script.
To start, I've generated an email script token named "my.application."
My current approach within the email is as follows:
Hello {{lead.First Name:default=Friend}},
We wanted to inform you that the status of your application {{{{my.application}}.applicationID}} has been updated to: {{{{my.application}}.status}}.
Unfortunately, this approach isn't yielding the expected results. Similarly, the following alternative isn't proving successful either:
Your application {{my.application.applicationID}}'s status has been modified to {{my.application.status}}.
I'm seeking guidance on the best course of action:
It seems like you haven’t read past posts about iterating Custom Object lists in Velocity. There’s much to understand about how lists (technically, ArrayLists) of objects (LinkedHashMaps) are sorted, filtered, and properly output.
Your token — and please post actual code using the Syntax Highlighter in the future, not screenshots! — is simply accessing the first custom object in what should be treated as an unsorted list. If you’re immediately accessing the record at index 0 that’s generally a sign you’re doing something wrong or incomplete.
The item at index 0 is an arbitrary object; even if you believe there’s only one such object per person, you still should sort the list by specific fields. Marketo itself will never ensure there’s only one object. (Often we see that multiple test objects have been attached to a person who supposedly only has one!)
After sorting, the item at index 0 has meaning.
Do you need distinct tokens vs. consolidating output within a single token? Depends on how much static content you have and who’s charged with editing it. I wouldn’t generally advise putting more than 1 or 2 lines of static content in the token itself. You don’t want everyday users having to open Script Editor (where they can easily break things) to make simple content changes.
To use multiple tokens you should first have a token that does the sorting, but doesn’t have any output, like:
#if( !$application_cList.isEmpty() )
#set( $sortedApplications = $sorter.sort( $application_cList, "createdAt:desc" )
#set( $latestApplication = $sortedApplications[0] )
#end
Note you will need to check Created At in the tree in order to sort by that field.
Then you can have other tokens that only do output:
${latestApplication.applicationID}
${latestApplication.status}
etc.
Hi @SanfordWhiteman ,
Thanks for the reply.
Regarding this =>
@SanfordWhiteman wrote:
The item at index 0 is an arbitrary object; even if you believe there’s only one such object per person, you still should sort the list by specific fields. Marketo itself will never ensure there’s only one object. (Often we see that multiple test objects have been attached to a person who supposedly only has one!)
In the documentation (https://developers.marketo.com/email-scripting/), it states that by accessing the 0th index, we retrieve the latest updated CO record (the one responsible for triggering the email and the one I require) and that is why we accessed the 0th index.
For each custom object, the 10 most recently updated records per person/contact are available at runtime and are ordered from most recently updated (at 0) to oldest updated (at 9).
In the documentation (https://developers.marketo.com/email-scripting/), it states that by accessing the 0th index, we retrieve the latest updated CO record (the one responsible for triggering the email and the one I require) and that is why we accessed the 0th index.
It's always a best practice to sort the custom object list, before referencing the record directly by its index # assuming they'd be in the right order you'd hope them to be in. You should give Sandy's article on sorting objects and lists in Velocity a read: https://blog.teknkl.com/sorting-objects-and-lists-in-velocity/
Hi @Darshil_Shah1 ,
Okay, I will sort before using the 0th custom object of a lead. But I have tried multiple times, and ever time I am getting the most recently updated record at position 0. So can you please confirm whether your statement is correct =>
The docs claim so, but actually, the CO records are sorted by create date in descending order.
Regardless of what order Marketo stores the data, I'd always recommend sorting the custom object list based on the field that fits your use case w/o assuming that the list would already be pre-sorted in a particular order. 🙂
Okay, I will sort before using the 0th custom object of a lead. But I have tried multiple times, and ever time I am getting the most recently updated record at position 0. So can you please confirm whether your statement is correct =>
The docs claim so, but actually, the CO records are sorted by create date in descending order.
Please show the code you’re using to sort and access the sorted list.
Well, you need to reference the velocity names of the fields instead of referencing them through the tokenized way (i.e., with the curly braces). In general, you should get familiarized with the velocity construct, how to work COs, the need to sort them before referencing, and pick the correct CO. You could make use of the $TriggerObject to reference the CO data of the CO that triggered your campaign. I'd say you should read Email Scripting and articles on Sandy's blog: https://blog.teknkl.com/tag/velocity/
Edit: Note that the $TriggerObject only works for “Added” triggers and not for “Updated” triggers, and since your specific use case requires the updated triggers, this, unfortunately, won't work.
- Alternatively, should I draft the entire email directly within the email script?
Well, if you have a lot of other pieces of non-dynamic content, then you shouldn't consider placing it in the velocity token (no point in editing 100s lines of static HTML/CSS in the script token). A very limited static content accompanying the dynamic content controlled by the velocity is fine though.
Additionally, your Marketo instance needs to be on the Orion infrastructure for you to be able to trigger the custom object data value changes. By default, you won't have the CO change triggers enabled for your instance, you'd need to reach out to the Marketo support team to make the necessary infrastructure updates and add them to your instance. Read this product documentation article on the same here.
Hi @Darshil_Shah1 ,
Regarding this =>
In your case, you should make use of the $TriggerObject to reference the CO data of the CO that triggered your campaign.
I have tried this.
1. I created an Email script token and named it my.Updated_Application_ID =>
${TriggerObject.applicationID}
(Note: I have checked the Application ID checkbox for the application CO in email script)
2. I have created an email =>
Dear {{lead.First Name:default=Friend}},Updated Application => {{my.Updated_Application_ID}}
3. Now when I try to trigger this email by making changes in the status of an application, I am getting the email like so =>
Dear Milan,Updated Application => ${TriggerObject.applicationID}
So, this is not working. But it does work when I make a trigger for "Added to Application CO". And in the documentation ( https://developers.marketo.com/email-scripting/marketo-objects/#trigger_objects ) also this is written =>
Note 2: The $TriggerObject only works for “Added” triggers and not for “Updated” triggers.
So will it only work when new applications are linked to the lead or am I doing something wrong ?
Yeah, this makes sense, The $TriggerObject reference only works for “Added” triggers and not for “Updated” triggers. You can sort the CO records using the sort tool, but when used as-is, there's a catch/caveat associated with that.
#set( $sortedList = $sorter.sort($customObjList,"updatedAt:desc") )
In case multiple CO records are updated at almost the same time for the same person (i.e. before the campaign has done processing the flow triggered through previous updates), your email would reference the last updated CO record, and not the one that actually triggered the campaign flow. $TriggerObject solves this problem, but unfortunately, it isn't available for the updated triggers.