Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
AMPscript for Email Marketing
1. Introduction to AMPscript for Email Marketing
Avanish Kumar
Salesforce Udaipur Admin Group
Sponsored By,
EPAM Systems
July 2022
2. This presentation may contain forward-looking statements that involve risks, uncertainties, and assumptions. If any such uncertainties materialize or if any of the assumptions
proves incorrect, the results of salesforce.com, inc. could differ materially from the results expressed or implied by the forward-looking statements we make. All statements other
than statements of historical fact could be deemed forward-looking, including any projections of product or service availability, subscriber growth, earnings, revenues, or other
financial items and any statements regarding strategies or plans of management for future operations, statements of belief, any statements concerning new, planned, or upgraded
services or technology developments and customer contracts or use of our services.
The risks and uncertainties referred to above include – but are not limited to – risks associated with developing and delivering new functionality for our service, new products and
services, our new business model, our past operating losses, possible fluctuations in our operating results and rate of growth, interruptions or delays in our Web hosting, breach of
our security measures, the outcome of any litigation, risks associated with completed and any possible mergers and acquisitions, the immature market in which we operate, our
relatively limited operating history, our ability to expand, retain, and motivate our employees and manage our growth, new releases of our service and successful customer
deployment, our limited history reselling non-salesforce.com products, and utilization and selling to larger enterprise customers. Further information on potential factors that could
affect the financial results of salesforce.com, inc. is included in our annual report on Form 10-K for the most recent fiscal year and in our quarterly report on Form 10-Q for the most
recent fiscal quarter. These documents and others containing important disclosures are available on the SEC Filings section of the Investor Information section of our Web site.
Any unreleased services or features referenced in this or other presentations, press releases or public statements are not currently available and may not be delivered on time or
at all. Customers who purchase our services should make the purchase decisions based upon features that are currently available. Salesforce.com, inc. assumes no obligation
and does not intend to update these forward-looking statements.
Statement under the Private Securities Litigation Reform Act of 1995
Forward-Looking Statement
3. ANURAG SAHA
Lead Software Engineer, EPAM Systems
• 6+ Years of IT Experience
• 3x Salesforce Marketing Cloud Certified
Speaker
@AnuragSaha
https://www.linkedin.com/in/anurag-saha/
6. Personalization Strings - Syntax
Also referred to as Merge or Substitution strings
Personalization Strings are used for building AMPscript expressions and passing identifiers.
Insert Subscriber Attribute, System-derived value or Data
Extension field values in an Email
%%First Name%%
%%Last Name%%
7. Attribute Strings
Also referred to as Merge or Substitution strings
Personalization Strings are used for building AMPscript expressions and passing identifiers.
Based on the context of the Contact or Subscriber to which they are sent - values are
derived from a field or attribute related to the Contact or Subscriber
• Email Subscriber Profile Attributes
• Sendable Data Extension Fields
• Journey Builder Entry Source Attributes
• MobileConnect Data Strings
• MobileConnect Contact Data Strings
• MobilePush Attributes
Example:
Profile Attribute named Member ID can be referenced in two ways:
1. attribute personalization string in an AMPscript block as [Member ID]
2. inline as %%Member ID%%.
8. System Strings (1/4)
System-based personalization strings which can be included in a message or on a page to output a value,
based on the context of the Subscriber, Contact or a message
STRING DESCRIPTION EXAMPLE OUTPUT
xtmonth Full name of the month when email is sent January
xtmonthnumeric Current month as a number 1
xtday Current day of the month when the email was sent 10
xtdayofweek Current day of the week when the email was sent Monday
xtyear Current year when the email was sent 2022
xtshortdate Current date when the email was sent in short format 01/10/2022
xtlongdate Current date when the email was sent in long format Monday, January 10, 2022
Email Date Strings
9. System Strings (2/4)
STRING DESCRIPTION EXAMPLE OUTPUT
emailname_ Name assigned to the email Spring Newsletter
_emailid The system-defined numeric identifier of the email 33345
_messagecontext
The context in which the Subscriber viewed the message
or page. Either:
•SEND - an email that is sent to a Subscriber
•PREVIEW - an email that is previewed within the email editor
•VAWP - an email opened as "view as web page" (from a view email_url link in an
email)
•FTAF - an email that is sent as a "Forward to a Friend“ message
•LANDINGPAGE - content is viewed on a landing page, microsite page or CloudPage
code resource
•VALIDATION - email is validated using the validation option in Marketing Cloud
•LINKRESOLUTION - a URL in an email that is resolved as a click-through link
•SMS - an SMS message that is sent to a Subscriber
•SOCIAL - email content that is shared using the Social Forward feature
Refer to Description
Email Date Strings
10. System Strings (3/4)
Email Date Strings
STRING DESCRIPTION EXAMPLE OUTPUT
_replycontent
Used in a Triggered Send Email that has been set as the "Triggered
send to forward" option in a Sender Profile when Reply Mail
Management is configured. Returns the email body that was
included in the reply message.
Refer to Description
_IsTestSend
Resolves to true if the email was sent as a Test Send from Email
Studio. otherwise the value is false
false
jobid Returns the unique job identifier related to the email send 3210123
_JobSubscriberBatchID
A numeric identifier of the batch associated with a Triggered Email;
this value defaults to 0 for a List send
5554321
_PreHeader
The preheader attribute assigned to the email. This string only
returns a value when used in an Attribute Value function. For
example. %%=AttributeValue(" Preheader")=%%
30% off store-wide, this
weekend only!
_DataSourceName
The value of the List, Group, Sendable Data Extension or Data
Extension Filter related to the email send; returns an empty value if
the All Subscribers list is used
VIP Members
_listname
The user-defined list name; returns an empty value if the All
Subscribers list is used
Loyalty Members
11. System Strings (4/4)
Subscriber Data Strings
STRING DESCRIPTION EXAMPLE OUTPUT
emailaddr The email address of the Subscriber max.vestapin@email.com
firstname_ or firstname
The Subscriber's first name from the "FirstName" Subscriber Profile
Attribute
Max
lastname_ or lastname
The Subscriber's last name from the "LastName" Subscriber Profile
Attribute
Vestapin
subscriberid A system-defined numeric identifier representing a Subscriber 1234
_subscriberkey A user-defined unique identifier representing a Subscriber M123456
listid
The corresponding list identifier of the Subscriber; returns the All
Subscribers list id if the email is not sent to a specific list
12345
list
The listid value suffixed with an underscore character and the email
type (either TEXT or HTML)
12345 HTML
listsubid
A system-defined identifier representing the Subscriber's
relationship to the list
987654321
messagetypepreference
The Subscriber's preferred email type, as defined as in the HTML
Emails Attribute in the Subscriber record; either TEXT or HTML
HTML
13. What is AMPscript?
A proprietary scripting language used within Marketing Cloud content (emails, landing pages,
Exclusion scripts, SMS and PUSH messages)
Syntax - Block
%%[
AMPscript code here
]%%
• Declare and set variables
• Process conditional logic
• Large amounts of data formatting / processing
Syntax - Inline
<td>
<p>%%=v(@fname) = %%</p>
</td>
• Output variables or function responses
• Embed easily into HTML
14. • Everything is case insensitive
• Comments are made with a block delimiter /* my comment */
• Strings can be delimited with " or ‘
• AMPscript is essentially procedural and processed top down
• PreHeader > HTML body > Text Body > Subject Line
AMPscript Editors - VS Code, Sublime Text
- Add AMPscript plugin for VS Code or AMPscript Highlighter plugin
for Sublime Text– it will then highlight your code properly
AMPscript – Thing to know
15. Variables – a container that holds information
• Designated in AMPscript with @
• Needs a unique name that begins with a letter and contain letters, numbers and – or _
• Dynamic typing allows the same variable to contain a number, date, Boolean, or string
Declaring Variables
VAR @fname
Var @loyaltymem
var @lname, var @gender, var @dob
Initializing/Setting Variables
SET @fname = “Max”
Set @lname = [Last Name]
Set @gender = Gender
set @dob = ‘1985-10-03’
Set @loyaltymem = TRUE
16. Assignment Operator
= Assign
Comparison Operators
== Equal To
!= Not Equal To
> Greater Than
< Less Than
>= Greater Than or Equal To
<= Less Than or Equal To
Logical Operators
NOT, AND, OR
Operators
17. Conditional Flow
Conditional logic flow using IF .. THEN .. ELSE .. ENDIF
%%[
If empty(@memid) THEN
set @dispMemId = “You are not
a Loyalty Member”
else
set @dispMemId = Concat(“Your
Loyalty membership id is: ”, @memid)
endif
]%%
%%[IF expression1 <comparison operator> expression2
THEN]%%
%%[ELSEIF expression1 <comparison operator>
expression3 THEN]%%
%%[ELSE]%%
%%[ENDIF]%%
%%[
IF @pts > 1000 THEN ]%%
<div>Platinum Status</div>
%%[ELSEIF @pts > 500 THEN]%%
<div>Gold Status</div>
%%[ELSEIF @pts > 100 THEN]%%
<div>Silver Status</div>
%%[ELSE]%%
<div>Bronze Status</div>
%%[ENDIF
]%%
18. Looping in AMPscript
Loop using FOR .. NEXT
Most commonly used with row sets but can be used for other purposes as well.
%%[ FOR @Variable = <start expression>
TO|DOWNTO <end expression> DO ]%%
[wrapped script or email content]
%%[ NEXT @Variable ]%%
%%[
FOR @i = 1 TO @rowCount DO
SET @row = Row(@rowSet, @i)
NEXT @i
]%%
19. Date Functions
Now() and GetSendTime()
DURING A SEND
AFTER A LIST, DE,
OR MANUAL SEND
AFTER A TRIGGERED OR
JOURNEY SEND
Now() Current system time Current system time Current system time
Now(1) Current system time Job start time Job publish time
GetSendTime() Current system time
Individual subscriber send completed
time
Individual subscriber send completed
time
GetSendTime(1) Current system time Job start time Job publish time
Note: Date functions use CST Server time zone by default
20. Date Functions
DateAdd(Date, Numeric, String)
DatePart(Date, String)
SET @tomorrow = DateAdd(Now(), 1, "D")
-> returns tomorrow’s date, along with a timestamp.
-> parameter 3 – valid values include Y, M, D, H and MI
SET @curryear = DatePart(Now(), “Y”)
-> returns current year
-> Parameter 2 – valid values include Y, M, D, H and MI
22. Formatting Functions
Format(String, String, String, String)
SET @formatted = Format(@today, "MM/dd/yyyy")
-> Parameter 3 = "Date" or "Number"
-> Parameter 4 = Culture code - e.g. "en-US", "en-GB" "fr-ER"
FormatDate(String, String, String, String)
FormatDate("2012-10-05 03:21:34.567890", "MMM DD,
YYYY","HH:MM:SS.MMM","en-US")
-> returns Oct 05, 2012 03:21:34.567
-> Parameter 2 = "long“,"short", "ISO" or "RFC“
-> Parameter 3 = "Date" or "Number“
-> Parameter 4 = Culture code - e.g. "en-US", "en-GB", "fr-FR"
SET @UKdate = FormatDate(Now(), "short", " “, "en-GB")
-> returns 23/05/2020
Short - 01/10/2011
Long - 01 October 2011
ISO-2011-10-01T10:25:27.3088597-06:00
RFC - Sun. 01 Oct 2011 10:25:27 GMT
23. String Functions
Concat(String, String [, String …])
• %%=Concat('a', 'b',’c’)=%% -> returns ‘abc’
Length(String)
• Set @abc="Hello world"
• %%=Length(@abc)=%% -> returns 12
Replace(String, String, String)
• Set @name = "The 2007 model is better"
• %%=Replace(@name, "2007", "2008)=%%
-> returns "The 2008 model is better"
[Upper/Lower/Proper]Case(String)
• %%=UpperCase("aBc") = %% -> returns 'ABC’
• %%=LowerCase ("aBc")=%% -> returns 'abc’
• %%=ProperCase ("aBc")=%% -> returns 'Abc'
ReplaceList(String, String, String [,String ...])
• ReplaceList("ABCDEFG“,"X","A""C“,"E“,"G")
-> returns "XBXDXFX"
Trim(String)
• %% =Trim(" Text ")=%%
-> returns "Text"
24. Utility Functions
V(String)
• Set @abc="Hello world“
• %%=v(@abc)=%% ->"Hello World"
AttributeValue(String)
• Set @abc=[First Name]
• %%=AttributeValue(@abc)=%% -> "Mark“
-> returns null if attribute is not available in context
IIF(String, String, String)
%%=IIF(Empty(@fname), 'Customer',@fname)=%%
Empty(String)
%%[
set @firstName = [First Name]
if empty(@firstName) then
set @displayName = "friend"
else
set @displayName = @firstName
endif
]%%
25. Math Functions
Add(Numeric, Numeric)
• %%=Add(@x,@y)=%% -> 26
• Set @x=20
• Set @y=6
Subtract(Numeric, Numeric)
• %%=Subtract(@x,@y)=%% -> 14
Mod(Numeric, Numeric)
• %%=Mod(@x,@y)=%% -> 2
Divide(Numeric, Numeric)
• %%=Divide(@x,@y)=%% -> 3
Multiply(Numeric, Numeric)
• %%=Multiply(@x,@y)=%% -> 120
• Set @low=1
• Set @high=100
Random(Integer, Integer)
• %%=Random(@low,@high)=%%
26. Lookup vs. LookupRows Function
Lookup LookupRows
Returns a single column value from a single
row
Returns a rowset, specific number of rows
from a data extension (or similar object -
Data View, Mobile List, etc.).
27. DE Lookup Functions
Lookup(String, String, String, String [,String, String] …)
%%=Lookup(“CustomerDE”,”FirstName”,”SubscriberKey”,[_subscriberkey])=%%
From
CustomerDE Retrieve
FirstName Where SubscriberKey
= SubscriberKey of current
Contact
NOTE: If the specified name and value pair criteria match more than one row in the Data Extension, a single value is still returned. The
row chosen for the return value cannot be specified and should be not considered consistent
EMAILADDRESS SUBSCRIBERKEY FIRSTNAME LASTNAME CREATED
doug@email.com 4235 Doug Smith 2021-10-21 12:01
suzy@email.com 6254 Suzy Jackson 2021-11-12 08:21
dale@email.com 8792 Dale Cameron 2021-12-11 06:12
28. DE Lookup Functions
From CustomerDE retrieve all rows
Where Region =
North
NOTE: Use
LookupOrderedRowsCS
if the Parameter 4 needs
to be Case Sensitive
EMAIL ADDRESS SUBSCRIBER KEY FIRST NAME REGION
doug@email.com 4235 Doug north
suzy@email.com 6254 Suzy North
dale@email.com 8792 Dale West
bard@email.com 3456 Barb North
curt@email.com 6565 Curt north
nora@email.com 8876 Nora South
leon@email.com 6123 Leon East
lily@email.com 4467 Lily East
LookupRows(String, String, String [,String, String] …)
%%Set @rows = LookupRows(“CustomerDE”,”Region”, “North”)=%%
29. DE Lookup Functions
LookupOrderedRows(String, Numeric, String, String, String [,String, String] …)
%%Set @rows = LookupOrderedRows(“CustomerDE”,0,”rank desc, firstname asc”,”Region”, “North”)=%%
EMAILADDRESS SUBSCRIBERKEY FIRSTNAME REGION RANK
doug@email.com 4235 Doug north 1
suzy@email.com 6254 Suzy North 3
dale@email.com 8792 Dale West 2
bard@email.com 3456 Barb North 1
curt@email.com 6565 Curt north 2
nora@email.com 8876 Nora South 1
leon@email.com 6123 Leon East 3
lily@email.com 4467 Lily East 1
NOTE: Use
LookupOrderedRowsCS
if the Parameter 4 needs
to be Case Sensitive
From CustomerDE
Retrieve all
rows(max 2000) Order by Rank Desc &
First Name Asc
Where
Region =
North
30. DE Rowset Related Functions
Row(String, Numeric)
• %%=Row(@rowset,@i)=%%
Field(String, Numeric [,String])
• %%=Field(@row,’City’)=%%
• Parameter 3 – default value ‘1’ returns error if field does not exist, ‘0’ returns NULL
RowCount(String)
• %%=RowCount(@rowset)=%%
%%[
set @rowset = LookupRows("LoyaltyMembers", "EmailAddress", [emailaddr])
set @rowCount = rowcount(@rows)
if @rowCount > 0 then
var @firstName, @lastName
set @row = row(@rows,1) /* get row #1 */
set @firstName = field(@row,"firstName")
set @lastName = field(@row,"lastName")
]%%
31. DE Data Manipulation Functions
InsertDE(String, String, String [,String, String] ... )
•InsertDE("CustomerDE","Customer ID", @cid, "First Name", @fname, "Last Name"@Iname, "EmaillD", @emailid)
UpdateDE(String, Numeric, String, String [,String, String ..], String, String [,String,String] ...)
• UpdateDE ("CustomerDE", 1, "Customer ID", @cid, "EmailID", @newemail)
No. of pairs for Where Clause
Where Customer ID = @cid
Update Email ID with @newemail value
DeleteDE(String, String, String [,String, String] …)
DeleteDE ("CustomerDE", "Customer ID', @cid)
InsertData, UpdateData, UpsertData and DeleteData cannot be used in Email - only
for Cloudpages and Mobile. InsertDE, UpdateDE, UpsertDE and DeleteDE can only
be used in an Email context.
UpsertDE will be
similar to UpdateDE
but if Where clause
not found, will insert
32. Few more Functions
RedirectTo(String)
<a href="%%=RedirectTo(@url)=%%">Click Here</a>
TreatAsContent(String)
• %%=TreatAsContent(@contentText)=%%
ContentBlockByID(Numeric)/ContentBlockByKey(String) /
ContentBlockByName
• %%=ContentBlockbyld("384201")=%%
• %%=ContentBlockbyKey("myContentBlock")=%%
• %%=ContentBlockbyName(“/myContentBlockName")=%%
RaiseError(String [,Boolean])
RaiseError(Concat("Error occurred for Customer ",@cid), true)
Parameter 2 value of true skips the send for current subscriber and moves to next subscriber. A
value of false stops the send and returns an error. Function defaults to false.
RaiseError still counts towards the Send and hence consumes SuperMessages - so use sparingly
Impression Tracking
AMPscript lets you determine which sections of an email
message perform better in sends. We may know intuitively that
random cat pictures attract more attention than a block of text,
but now you have the statistics to prove it! Surround a piece of
content—pulled in using
the ContentArea() or ContentAreaByName() functions—with
the BeginImpressionRegion() and EndImpressionRegion() fun
ctions and use impression tracking reports to see how your cat
pictures measure up.
%%=BeginImpressionRegion("PrimaryNavigation")=%% <a
href="https://limedash.com/shop" alias="Shop">Shop</a> | <a
href="https://limedash.com/contact"
alias="Contact">Contact</a>
%%=EndImpressionRegion(0)=%%
33. Common Mistakes
Unmatched Parentheses
%%=Concat("Dear ", ProperCase(@FirstName)=%%
Referring to an Attribute rather than a variable
%%=Lookup(MyData, "First Name","ID", ID)=%%
Pasting in “curly quotes” from Word or other editor
%%=Lookup(@MyData, “First Name”, “ID”, @ID)=%%
Invalid conditional syntax and wrong evaluation operators
%%[
IF @isPerks = true
SET @rewards == "Gold"
]%%
Try FREE app https://ampscript.io/ for debugging. This application enables
easy AMPscript editing through syntax highlighting and it will warn you
about possible syntax errors in your code.
34. Few Best Practices
• Use "HTML" blocks with AMPscript content in Content Builder
• Place the majority of your AMPscript code at the top of the email or web page
• Limit look ups
• Use row sets, if more than one field is needed
• Always use conditionals to validate external content to avoid send-time errors
• Use RaiseError() sparingly and only to avoid send time errors not as segmentation
• Test with data identical to our live sendable data
• Add comments to your AMPscript code
• Output everything when debugging
%%[
set @debug=0 // set to 1 when debugging
if @debug == 1 then
<code for debug logging>
endif
]%%
37. Email 1
C
Email 2
Wait Time
15 days
nn
Email 2
yn
Email 2
ny
Email 2
yy
Relevant =
Fragment_3
New =
Fragment_4
Gap =
Fragment_2
Relevant = -
Fragment_3
New =
-
Fragment_4
Gap =
Fragment_1
Relevant =
-Fragment_3
New =
-
Fragment_4
Gap = N/A
New =
-Fragment_3
New =
-Fragment_4
Gap =
- Fragment_1
- Fragment_2
EMAIL 1 ENGAGEMENT
Fragment_1 y/n
Fragment_2 y/n
Wait Time
15 days
Email Deployment 1 and 2 – Reactive Email Sample
42. Useful Links to Learn Ampscript
• Eliot & Adam’s project
https://ampscript.guide/
• Salesforce Official Guide
https://sforce.co/3zqEc8V
• Online tool to Practice AMPscript
https://mcsnippets.herokuapp.com/
• Free AMPscript syntax validation tool
https://ampscript.io/
43. AMPscript for Email Marketing – Practice Setup
Data Preparation
1. Download the json and csv data files from the repository
2. Deploy the 4 Data Extensions in the json file using Deployment Manager - if you do not have this, install Deployment Manager from
AppExchange for Marketing Cloud
3. Once you have the 4 Data Extensions, import the data from each of the CSV files to the appropriate Data Extensions - you should
have the following DEs:
• NTO Customer - NTO (9 fields, 6 records)
• Abandoned Cart Audience - NTO (8 fields, 6 records)
• Product Catalog - NTO (7 fields, 126 records)
• Events (4 fields, 6 records)
4. Replace the email id column values with your email id in the NTO Customer - NTO and Abandoned Cart Audience - NTO DEs
Template Preparation
1. Create a Paste HTML template in Email Studio - Content using the NTO Blue HTML code
2. Save the NTO Blue template in your Content folder - we will use this Template for creating the sample email and add AMPscript code
for personalization