This article explains how to use AMPscript to enhance server-side JavaScript in Salesforce Marketing Cloud and use it in Script Activities and Automations.
AMPscript vs SSJS
There is no secret that AMPscript and server-side JavaScript have many differences, in both synthax and features.
At the first glance, server-side JavaScript seems like a superior language, but there are some key areas where AMPscript excels over SSJS.
For instance, it’s rather hard to make date and time calculations in SSJS because it uses an older version of JavaScript, introduced in 1999.
<script runat="server">
Platform.Load("core", "1");
var minutesToAdd = 1;
var currentDate = new Date();
var addOneMinute = new Date(Now() + minutesToAdd * 60000);
Write(addOneMinute);
</script>
But in AMPscript, date and time calculations are easy, thanks to a collection of dedicated methods.
%%[
SET @AddOneMinute = DateAdd(Now(), 1, "MI")
Output(Concat(@AddOneMinute))
]%%
Another example: AMPscript can natively perform requests to Salesforce, in order to retrieve, create and update Salesforce objects.
%%[
SET @id = CreateSalesforceObject(
'Lead', 2,
'FirstName', 'John',
'LastName', 'Malkovitch'
)
]%%
Something that server-side JavaScript is incapable of.
¯\_(ツ)_/¯
So what?
Well, the good news is that we can use both AMPscript and server-side JavaScript in Salesforce Marketing Cloud to fit our needs.
But the bad news is that when it comes to the Script Activities in Automations, AMPscript is simply not allowed!
AMPscript in Script Activities
There are 2 main methods that allow us to use AMPscript in Script Activities: block integration and text to JavaScript conversion.
Block integration
This method is not recommended but it works flawlessly nonetheless.
It consists of putting our AMPscript code inside an HTML block in the Content Builder and then rendering it in server-side JavaScript thanks to the ContentBlockByID and TreatAsContent functions.
<script runat="server">
Platform.Load("core", "1");
var ampscript = Platform.Function.ContentBlockByID("123456");
Write(TreatAsContent(ampscript));
</script>
Text to JavaScript conversion
This method is not perfect either, but can be very powerful thanks to its full integration with the rest of our JavaScript code.
It consists of creating the AMPscript code as plain text using the JavaScript synthax and then rendering it thanks to TreatAsContent function.
<script runat="server">
Platform.Load("core", "1");
var scr = "";
scr += "\%\%[";
scr += "SET @Hello = 'Hello World'";
scr += "Output(Concat(@Hello))";
scr += "]\%\%";
Write(TreatAsContent(scr));
</script>
Both of these methods are valid and have the right to exist but it’s the latter that can allow us to enhance server-side JavaScript and elevate it to the new heights!
Enhance SSJS thanks to AMPscript
Now that we understand the why and the how, let’s take a look at several examples of SSJS enhancement in the context of date and time manipulation and native Salesforce integration.
Date and time
Example #1: How to convert a date to ISO format
<script runat="server">
Platform.Load("core", "1");
var localTime = DateTime.SystemDateToLocalDate(Now());
var iso = formatDateISO(localTime);
Write(Stringify(iso));
function formatDateISO(dt) {
Variable.SetValue("DateString", dt);
var scr = "";
scr += "\%\%[";
scr += "SET @DateISO = FormatDate(@DateString, 'iso')";
scr += "Output(Concat(@DateISO))";
scr += "]\%\%";
return Platform.Function.TreatAsContent(scr);
}
</script>
Example #2: How to add time to an existing date
<script runat="server">
Platform.Load("core", "1");
var localTime = DateTime.SystemDateToLocalDate(Now());
var plus = plusTime(localTime, 1, "H");
Write(Stringify(plus));
function plusTime(dt, amount, unit) {
Variable.SetValue("Date", dt);
Variable.SetValue("Amount", amount);
Variable.SetValue("Unit", unit);
var scr = "";
scr += "\%\%[";
scr += "SET @Plus = DateAdd(@Date, @Amount, @Unit)";
scr += "Output(Concat(@Plus))";
scr += "]\%\%";
return Platform.Function.TreatAsContent(scr);
}
</script>
Example #3: How to calculate the difference between 2 dates
<script runat="server">
Platform.Load("core", "1");
var localTime = DateTime.SystemDateToLocalDate(Now());
var systemTime = DateTime.LocalDateToSystemDate(Now());
var diffMin = dateDiff(systemTime, localTime, "MI");
Write(Stringify(diffMin));
function dateDiff(dt1, dt2, unit) {
Variable.SetValue("@Date1", formatDateISO(dt1));
Variable.SetValue("@Date2", formatDateISO(dt2));
Variable.SetValue("@Unit", unit);
var scr = "";
scr += "\%\%[";
scr += "SET @Result = DateDiff(@Date1, @Date2, @Unit)";
scr += "Output(Concat(@Result))";
scr += "]\%\%";
return Number(Platform.Function.TreatAsContent(scr));
}
function formatDateISO(dt) {
Variable.SetValue("DateString", dt);
var scr = "";
scr += "\%\%[";
scr += "SET @DateISO = FormatDate(@DateString, 'iso')";
scr += "Output(Concat(@DateISO))";
scr += "]\%\%";
return Platform.Function.TreatAsContent(scr);
}
</script>
Example #4: How to convert a date to h format
<script runat="server">
Platform.Load("core", "1");
var localTime = DateTime.SystemDateToLocalDate(Now());
var hDate = formatDateH(localTime);
Write(Stringify(hDate));
function formatDateH(dt) {
Variable.SetValue("DateString", dt);
var scr = "";
scr += "\%\%[";
scr += "SET @DateH = Format(@DateString, 'h')";
scr += "Output(Concat(@DateH))";
scr += "]\%\%";
return Platform.Function.TreatAsContent(scr);
}
</script>
Example #5: How to convert a date to a custom format
<script runat="server">
Platform.Load("core", "1");
var localTime = DateTime.SystemDateToLocalDate(Now());
var cDate = formatDateCustom(localTime, "YYYY-MM-DD");
Write(Stringify(cDate));
function formatDateCustom(dt, format) {
Variable.SetValue("DateString", dt);
Variable.SetValue("CustomFormat", format);
var scr = "";
scr += "\%\%[";
scr += "SET @DateH = FormatDate(@DateString, @CustomFormat)";
scr += "Output(Concat(@DateH))";
scr += "]\%\%";
return Platform.Function.TreatAsContent(scr);
}
</script>
Salesforce integration
Let’s move up in difficulty and examine a couple of examples of Salesforce integration functions.
Example #1: How to create a Salesforce object
<script runat="server">
Platform.Load("core", "1");
var id = createSalesforceObject('Individual', {
"FirstName": "John",
"LastName": "Malkovitch",
"Custom_Date": "2020-06-06"
});
Write(Stringify(id));
function createSalesforceObject(name, object) {
var i = 0;
var scr = "";
scr += "\%\%[";
scr += "SET @Id = CreateSalesforceObject( ";
scr += "'" + name + "', ";
scr += (object.length + 1) + ", ";
for(var k in object) {
i++;
var nm = k;
var val = object[k];
val = val.replace(/'|’/g, "'");
scr += "'" + nm + "', ";
scr += '"' + val + '" ';
if(i < object.length + 1) scr += ", ";
}
scr += ") ";
scr += "Output(Concat(@Id)) ";
scr += "]\%\%";
var res = Platform.Function.TreatAsContent(scr);
return res
}
</script>
Example #2: How to retrieve Salesforce objects
<script runat="server">
Platform.Load("core", "1");
var req = retrieveSalesforceObjects(
"Contact",
["Id", "Salutation", "AccountId"],
[
{
Property: "Email",
SimpleOperator: "equals",
Value: "john.malkovitch@mail.com"
},
{
Property: "LastName",
SimpleOperator: "equals",
Value: "Malkovitch"
}
]
);
Write(Stringify(req));
function retrieveSalesforceObjects(name, cols, filters) {
var filterStr = "";
var colStr = cols.join(", ");
for(var k in filters) {
var filter = filters[k];
filter.Value = filter.Value.replace(/'|’/g, "'");
filterStr += "'" + filter.Property + "', ";
filterStr += "'" + ((filter.SimpleOperator == "equals") ? "=" : "!=") + "', ";
filterStr += "\"" + filter.Value + "\"";
if(k < filters.length - 1) filterStr += ", ";
}
var scr = "";
scr += "\%\%[";
scr += "SET @Result = '[' ";
scr += "SET @Rows = RetrieveSalesforceObjects('" + name + "', '" + colStr + "', " + filterStr + ") ";
scr += "SET @RowCount = ROWCOUNT(@Rows) ";
scr += "IF @RowCount > 0 THEN ";
scr += "FOR @i = 1 TO @RowCount DO ";
scr += "SET @Row = Row(@Rows, @i) ";
scr += "SET @Result = CONCAT(@Result, '{') ";
for(var i = 0; i < cols.length; i++) {
var col = cols[i];
scr += "SET @Result = CONCAT(@Result,'\"" + col + "\": ', '\"', FIELD(@Row, '" + col + "'), '\"') ";
if(i < cols.length - 1) scr += "SET @Result = CONCAT(@Result,', ') ";
}
scr += "SET @Result = CONCAT(@Result, '}') ";
scr += "IF @i == @RowCount THEN ";
scr += "SET @Result = CONCAT(@Result,', ') ";
scr += "ENDIF ";
scr += "NEXT @i ";
scr += "ENDIF ";
scr += "SET @Result = CONCAT(@Result, ']') ";
scr += "OUTPUT(CONCAT(@Result)) ";
scr += "]\%\%";
var res = Platform.Function.TreatAsContent(scr);
return Platform.Function.ParseJSON(res)
}
</script>
Conclusion
Keep in mind that these are just examples and not a list of all available AMPscript functions rewritten to work natively with server-side JavaScript in Automation Script Activities.
Feel free do adapt the code to your liking and perhaps create some of your own.
Have I missed anything?
Please poke me with a sharp comment below or use the contact form.
Very very interesting article, thank you for you efforts Ivan. I have one question, what are the use cases of each language ? I mean how I can know where I should use Ampscript or SSJS ?
Believe me you’ll know it 😉 When you realize that SSJS can’t do something that AMPscript can do, for example, encrypt something with a symmetric key.
These are awesome examples. I wish there were a Like button. Thank you!
This comment is way better than any given Like 😉
Hi Ivan – Thanks for these great methods! For my purposes, the inclusion of the AMPScript as a block was the simplest way to accomplish what I’m doing (importing a RSS feed to a DataExtension for a blog feed newsletter). I’ve been successful in running the AMPScript via automation studio using the “run once” activity script, but when I include that very same script into a multi-step automation (and the script activity is the very first step) it fails. Any idea why?
No idea. But I suggest you first try your script on a Cloud page using the try…catch method, so that you are able to see if your script creates errors.