Advanced Personalization is a powerful feature in Dengage that lets you create content that adapts to each individual user. By leveraging data from your Master Contact or Master Device tables, you can make messages more relevant, engaging, and effective. This goes beyond simple name personalization, your content can dynamically respond to user attributes, behaviors, and preferences.
But it doesn't stop there. Using Query Data From Data Space, you can fetch data from any table in your data space. This allows you to create even more advanced, personalized experiences by including information from multiple sources and applying conditions based on that data. The result is dynamic content that automatically changes for each recipient, helping your campaigns feel truly personal and impactful.
How It Works
You can use JavaScript to make dynamic content in the D·engage platform.
This template system is similar to the Embedded JavaScript (EJS) template language (EJS site ).
Template System
The difference is that in D·engage, the open and close delimiters for JavaScript blocks are:

This code checks if the contact has a name field. If the data exists, it shows Hello, [Name]!. If there's no name, it shows Hello, valued customer!.
This approach ensures that your messages always look complete and personal, even if some data is missing.

If the contact's order ID is 12345, this will display: Your order number is 12345. It inserts the actual value dynamically into your content.
This allows you to dynamically show information such as order numbers, appointment times, or account details in your content.

If the contact’s city is saved as Milan, the system will escape the unsafe code and only show: City: Milan. This ensures your content stays safe even if the data contains HTML or scripts. This setup allows you to personalize your messages dynamically and safely, with appropriate fallbacks, so that each recipient sees content that is relevant and well-formatted.
Global Variables in Templates
There are three global variables that you can use in templates:
$Contact
This object includes information about the current contact. Properties of this object are columns from the master_contact table, such as contact_key. This object can be null in Push sends.
$Device
This object includes information about the current device. Properties of this object are columns from the master_device table, such as a token. This object is only available for Push content and will be null for other channels.
$Current
This object contains extra columns coming from a selected audience. This can be from a Send List Table or a SQL Segment. When sending a message using these sources, additional columns from the table or segment can be accessed through $Current.
Example 1: Product Recommendations from a Send ListImagine you have a send list created for product recommendations. The table has two columns: contact_key, which identifies the contact, and recommended_product_id, which contains the product you want to recommend. When sending content using this table, contact_key identifies the user, and recommended_product_id becomes part of the $Currentobject. You can access it in your content as $Current.recommended_product_id.
You can also enrich the content further by looking up additional product details, such as title, URL, or image URL, from a product table and using them in your message. This demonstrates both how $Current data is accessible and how it can be combined with a lookup to enhance content.
This allows your content to dynamically personalize messages based on extra data from the selected audience, making campaigns more relevant and engaging.
Example 2: Shopping Cart Products from a SQL SegmentSome SQL segments include extra columns, especially predefined segments related to shopping carts. For instance, there might be columns named shopping_carts and products. When sending content using such a segment, the $Currentobject includes a products array containing all products in the user's cart. You can access this array directly with $Current.products and display the items in your content either as a list, a table, or any format that fits your message.
This allows content to dynamically include multiple items from the user's cart, providing a personalized experience for each recipient.
Query Data from Data Space
You can make queries in your templates and get arbitrary data from any table in the data space. For this, you must use the $from function with the table name. Then you must add filter options by calling relevant functions of the query object.
var items = $from("myTable")
.where("contact_key", "=", $Contact.contact_key)
.where("name","=","abcd")
.where("birthdate",">", "2018-04-01 14:11")
.order("birthdate", "DESC")
.take(5)
.skip(2)
.get();
Explanation
-
$from("db_table_name"): Retrieve data from table "db_table_name"
- db_table_name: Case-sensitive table name on the database
-
.where("column_name", "operator", "column_value"): (optional), SQL where clause, can be repeated
- column_name: Case sensitive table column name
- operator: SQL operator (“=”, “>”, “<”, “<>” etc.)
- column_value: Column value for where clause
-
.order("column_name", "direction"): (optional) sorting mechanism
- direction: ASC = Ascending, DESC = Descending
-
.take(n): (optional) limiting query, n = integer value
-
.skip(n): (optional) offset point, n = integer value
-
.random():(optional) shuffle data for randomization
After applying filters, you must execute the query using one of the following functions;
-
.get(columns): get the result as an array of objects. If you don't provide columns, all columns will be selected.
-
.first(columns): get the first row as object. If you know that result contains only one row, you can use this. If you don't give columns, all columns will be selected.
-
.value(column): get the given column value for the first row. If you know that the result is one row and a single column value, you can use this.
{%
var products = $from("product_recommendation")
.where("contact_key","=",$Contact.contact_key)
.take(5)
.get();
%}
{% if (products.length > 0) { %}
<table>
<tr>
<th>Product Name</th><th>Price</th><th>Link</th>
</tr>
{% for (var i = 0; i < products.length; i++) { %}
<tr>
<td>{%= products[i].name %}</td>
<td>{%= products[i].price %}</td>
<td><a href="{%= products[i].link %}">link</a></td>
</tr>
{% } %}
</table>
{% } else { %}
<h2>See new producst</h2>
<a href="https://example.com/products?user_id={%= $Contact.contact_key %}">Go to products</a>
{% } %}
Canceling Send
If you want to cancel sending for some contacts when evaluating JavaScript, you can use the $blockSend function.
$blockSend(reason): Provide a reason as string
Making API Calls to Remote Endpoints
If you want to make an HTTP request to get data from external sources, you have to define these endpoints in the Dengage Admin.
In Dengage panel by going to the "Settings > Custom API Endpoints" page, you can only add GET requests.
All the endpoints defined in the settings will be available in contents, under the $CustomApi object.
$CustomApi.getPromoCode($Contact.contact_key);
Utility Functions
FormatDate(date[, format]): Format dates
FormatDate(date);
FormatDate(new Date());
FormatDate(date, 'yyyy-MM-dd HH:mm');