How to send an email with AMPscript

How to send an email with AMPscript

Creating a triggered email in Marketing Cloud is not an easy task. But once mastered, the process doesn’t take too much time.

What do you need?

There are 3 steps that you need to follow in this exact order:

  1. Create a Triggered Send Data Extension
  2. Create an email with Content Builder
  3. Create a Triggered Send

Let’s examine each step separately.

Step 1: Create a Triggered Send Data Extension

In order to create a Triggered Send Data Extension, you need to use Contact Builder.

Choose Create From Template as the creation method and choose TriggeredSendDataExtension as the template.

You’ll notice that 2 fields are now mandatory: SubscriberKey and EmailAddress. For the sake of this tutorial, let’s add 2 more fields:

FirstName Text50Nullable
Language Text2Nullable

Step 2: Create an email

In order to create a Triggered Send Data Extension, you need to use Content Builder. Make it as simple as possible and use the following code for later customization:

%%[ 
	VAR @Greeting
	IF Language == "EN" THEN 
		SET @Greeting = "Hello"
	ELSE
		SET @Greeting = "Bonjour"
	ENDIF 
]%%
<h1>%%=v(@Greeting)=%% %%=v(FirstName)=%%</h1>

Step 3: Create a Triggered Send

In order to create a Triggered Send, you need to use Email Studio.

The process is straightforward, just make sure to choose the Email and the Triggered Send Data Extension you created previously.

If you get any errors when trying to save, it usually means that your Email contains AMPscript that uses different field names than what you have in your Triggered Send Data Extension.

The last step is to Start the Triggered Send by clicking on the Start/Restart button on the top.

Now, let’s take a note of the External Key of our Triggered Send and move forward to the coding.

Triggering an email with AMPscript

At first, let’s define some variables, where the SubsciberKey is a simple timestamp for the purpose of this tutorial and the TriggerSendExternalKey is the External Key generated by the creation of our Triggered Send.

SET @SubscriberKey = Format(SystemDateToLocalDate(NOW()), "yyddMMhhmmss")
SET @EmailAddress = "misterblue@mail.com"
SET @Language = "EN"
SET @TriggerSendExternalKey = "12345"

Then, let’s proceed with creating the TriggeredSend, Subscriber and Attribute objects. The names of the variables that we are setting are not important. In most cases you will not re-use them and therefore try to keep them as short as possible, unlike what I’m doing in this example.

Note that the names of the object properties are the same as in our Triggered Send Data Extension.

/* Specify the external key of the TriggerSend */
SET @TriggerSend = CreateObject("TriggeredSend")
SET @TriggerSendDefinition = CreateObject("TriggeredSendDefinition")
SetObjectProperty(@TriggerSendDefinition, "CustomerKey", @TriggerSendExternalKey)
SetObjectProperty(@TriggerSend, "TriggeredSendDefinition", @TriggerSendDefinition)

/* Specify the email address and the subscriber key */
SET @TriggerSendSubscriber = CreateObject("Subscriber")
SetObjectProperty(@TriggerSendSubscriber, "EmailAddress", @EmailAddress) 
SetObjectProperty(@TriggerSendSubscriber, "SubscriberKey", @SubscriberKey) 

/* Fill out the Language field in the TriggerSend data extension */
SET @TriggerSendLanguage = CreateObject("Attribute")
SetObjectProperty(@TriggerSendLanguage, "Name", "Language")
SetObjectProperty(@TriggerSendLanguage,"Value", @Language)
AddObjectArrayItem(@TriggerSend, "Attributes", @TriggerSendLanguage)

/* Fill out the FirstName field in the TriggerSend data extension */
SET @TriggerSendFirstName = CreateObject("Attribute")
SetObjectProperty(@TriggerSendFirstName, "Name", "FirstName")
SetObjectProperty(@TriggerSendFirstName,"Value", @FirstName)
AddObjectArrayItem(@TriggerSend, "Attributes", @TriggerSendFirstName)

AddObjectArrayItem(@TriggerSend, "Subscribers", @TriggerSendSubscriber) 

The only thing left to do is to use InvokeCreate method, which will send the data to the Triggered Send. The Triggered send will then write the data in the Triggered Send Data Extension and send the email.

SET @TriggerSend_statusCode = InvokeCreate(@TriggerSend, @TriggerSend_statusMsg, @errorCode) 

Let’s also add some basic error log if something goes wrong.

IF @TriggerSend_statusCode != "OK" THEN
	OUTPUTLINE(CONCAT("Status: ",@TriggerSend_statusMsg," / Code: ",@errorCode))
ENDIF

Voilร ! If everything was executed correctly, it works like magic!

Full code

%%[

	SET @SubscriberKey = Format(SystemDateToLocalDate(NOW()), "yyddMMhhmmss")
	SET @EmailAddress = "misterblue@mail.com"
	SET @Language = "EN"
	SET @TriggerSendExternalKey = "12345"

	/* Specify the external key of the TriggerSend */
	SET @TriggerSend = CreateObject("TriggeredSend")
	SET @TriggerSendDefinition = CreateObject("TriggeredSendDefinition")
	SetObjectProperty(@TriggerSendDefinition, "CustomerKey", @TriggerSendExternalKey)
	SetObjectProperty(@TriggerSend, "TriggeredSendDefinition", @TriggerSendDefinition)

	/* Specify the email address and the subscriber key */
	SET @TriggerSendSubscriber = CreateObject("Subscriber")
	SetObjectProperty(@TriggerSendSubscriber, "EmailAddress", @EmailAddress) 
	SetObjectProperty(@TriggerSendSubscriber, "SubscriberKey", @SubscriberKey) 

	/* Fill out the Language field in the TriggerSend data extension */
	SET @TriggerSendLanguage = CreateObject("Attribute")
	SetObjectProperty(@TriggerSendLanguage, "Name", "Language")
	SetObjectProperty(@TriggerSendLanguage,"Value", @Language)
	AddObjectArrayItem(@TriggerSend, "Attributes", @TriggerSendLanguage)

	/* Fill out the FirstName field in the TriggerSend data extension */
	SET @TriggerSendFirstName = CreateObject("Attribute")
	SetObjectProperty(@TriggerSendFirstName, "Name", "FirstName")
	SetObjectProperty(@TriggerSendFirstName,"Value", @FirstName)
	AddObjectArrayItem(@TriggerSend, "Attributes", @TriggerSendFirstName)

	AddObjectArrayItem(@TriggerSend, "Subscribers", @TriggerSendSubscriber)  

	SET @TriggerSend_statusCode = InvokeCreate(@TriggerSend, @TriggerSend_statusMsg, @errorCode) 

	IF @TriggerSend_statusCode != "OK" THEN
		OUTPUTLINE(CONCAT("Status: ",@TriggerSend_statusMsg," / Code: ",@errorCode))
	ENDIF

]%%

Troubleshooting

Your code doesn’t work? Let’s figure out why!

Can’t create a Triggered Send?

  1. Did you specify the correct Email, Data Extension and choose the correct List with an add/update subscribers option?
  2. Check your Email and test it with a record from your Triggered Send Data Extension.

Email not sent?

  1. Check the Triggered Send Data Extension. If your record exists, the email should arrive shortly, unless it got queued for some reason, in which case I advise you to restart the Triggered Send from the Email Studio.
  2. Check the status of your Triggered Send, it might be on Pause.
  3. The person might be blacklisted or unsubscribed from the List you chose when creating the Triggered Send.

Error 500?

  1. Does the External Key exist? Please check the Trigger Send in the Email Studio.
  2. The Trigger Send object property name doesn’t exist in the Triggered Send Data Extension or is in an incorrect format (in short, don’t try to write letters in a Boolean type field).
  3. Syntax error. Please, try to debug AMPscript to see what went wrong.

Have I missed anything?

Please poke me with a sharp comment below or use theย contact form.

Pay me a coffee

Want to say thanks? Pay me a coffee! Remember, I turn coffee into code.

  1. I’m a newbie at this. I get an error on cloud page “Status: Unable to queue Triggered Send request. There are no valid subscribers. / Code: 180008”

  2. I have nightmares about this error ๐Ÿ˜€ There are 2 possible causes: the TriggeredSend interaction was not configured properly (please check the checkbox to update the Contact) or you are trying to push some data in a TriggeredSend Data Extension field that the Data Extension rejects (it can happen if you are pushing words in a Number field or a Boolean field, or for example, a value of 25 characters into a field that can only accept 20).

  3. My fields match my form. But the funny part is that this happens as soon I replace
    SET @ts_email = “mymail@gmail.com”
    WITH
    SET @ts_email = RequestParameter(“EmailAddress”) to read data from the form.

    How do I get the data from the form then?

  4. This is the correct way if you are submitting the form with POST. I just noticed that you use German quotes โ€œโ€ … is that how it is in your code? If so, that might be the problem.

  5. I’ve corrected it. Strangely everything works fine but cloud page still displays an error. (Status: / Code: 180008) Here is the whole code (a bit different than yours).

    %%[
    VAR @ts_email, @FirstName, @LastName, @OptIn, @Date, @IPNaslov, @ts_subkey, @ts, @ts_def, @ts_extkey, @ts_fname, @ts_lname, @ts_opin, @ts_date, @ts_ip, @ts_statusCode, @ts_statusMsg, @errorCode

    SET @ts_email = RequestParameter(“EmailAddress”)
    SET @FirstName = RequestParameter(“FirstName”)
    SET @LastName = RequestParameter(“LastName”)
    SET @OptIn = RequestParameter(“OptIn”)
    SET @Date = SystemDateToLocalDate(Now(1))
    SET @IPNaslov = RequestParameter(“IPNaslov”)
    SET @ts_extkey = “58556”

    /* Trigger Send Object Creation */
    SET @ts = CreateObject(“TriggeredSend”)
    SET @ts_def = CreateObject(“TriggeredSendDefinition”)
    SET @ts_subkey = @ts_email

    /* Specify the external key of the TriggerSend */
    SetObjectProperty(@ts_def, “CustomerKey”, @ts_extkey)
    SetObjectProperty(@ts, “TriggeredSendDefinition”, @ts_def)

    /* Create the Subscriber Object */
    SET @ts_sub = CreateObject(“Subscriber”)
    SetObjectProperty(@ts_sub, “EmailAddress”, @ts_email)

    /* Set SubscriberKey to EmailAddress */
    IF NOT EMPTY(@ts_subkey) THEN
    SetObjectProperty(@ts_sub, “SubscriberKey”, @ts_subkey)
    ELSE
    SetObjectProperty(@ts_sub, “SubscriberKey”, @ts_email)
    ENDIF

    /* Fill out the FirstName field in the TriggerSend data extension */
    SET @ts_fname = CreateObject(“Attribute”)
    SetObjectProperty(@ts_fname, “Name”, “FirstName”)
    SetObjectProperty(@ts_fname,”Value”, @FirstName)
    AddObjectArrayItem(@ts, “Attributes”, @ts_fname)

    /* Fill out the LastName field in the TriggerSend data extension */
    SET @ts_lname = CreateObject(“Attribute”)
    SetObjectProperty(@ts_lname, “Name”, “LastName”)
    SetObjectProperty(@ts_lname,”Value”, @LastName)
    AddObjectArrayItem(@ts, “Attributes”, @ts_lname)

    /* Fill out the OptIn field in the TriggerSend data extension */
    SET @ts_optin = CreateObject(“Attribute”)
    SetObjectProperty(@ts_optin, “Name”, “OptIn”)
    SetObjectProperty(@ts_optin,”Value”, @OptIn)
    AddObjectArrayItem(@ts, “Attributes”, @ts_optin)

    /* Fill out the Date field in the TriggerSend data extension */
    SET @ts_date = CreateObject(“Attribute”)
    SetObjectProperty(@ts_date, “Name”, “Date”)
    SetObjectProperty(@ts_date,”Value”, @Date)
    AddObjectArrayItem(@ts, “Attributes”, @ts_date)

    /* Fill out the Date field in the TriggerSend data extension */
    SET @ts_ip = CreateObject(“Attribute”)
    SetObjectProperty(@ts_ip, “Name”, “IPNaslov”)
    SetObjectProperty(@ts_ip,”Value”, @IPNaslov)
    AddObjectArrayItem(@ts, “Attributes”, @ts_ip)

    AddObjectArrayItem(@ts, “Subscribers”, @ts_sub)

    SET @ts_statusCode = InvokeCreate(@ts, @ts_statusMsg, @errorCode)

    IF @ts_statusCode != “OK” THEN
    OUTPUTLINE(CONCAT(“Status: “,@TriggerSend_statusMsg,” / Code: “,@errorCode))
    ENDIF

    ]%%

  6. Got it. I was missing an attribute for the channel member id. Now there is no error msg. Tnx! You can now enjoy your coffee (bought on March 24th) ๐Ÿ˜‰

  7. Ivan one more question. I’m using a cloudpagesurl link with attributes from triggered send de. Link heads to a preference page and shows the data correctly. On that page, subscriber can select additional newsletter topics. When trying to save original data from ts de and added data to a new DE it goes through but no data is inserted.

  8. Aaah, you are building a preference page, been there ๐Ÿ˜€ But your question has nothing to do with ts. You need to analyse how you insert the data. In most cases, the problem comes from the primary key.

Leave a Reply

Your email address will not be published. Required fields are marked *

Salesforce Marketing Cloud
Up Next:

How to protect your Cloud pages

How to protect your Cloud pages