Skip to main content
Build the future with Agentforce at TDX in San Francisco or on Salesforce+ on March 5–6. Register now.

Build Your Preference Center

Learning Objectives

After completing this unit, you’ll be able to:

  • Build a collection and landing page in CloudPages.
  • Use the CloudPages URL AMPscript function.
  • Code a LogUnsub Event to update All Subscribers.

Get Started

Now that Terry’s solution is documented and approved, they can begin creating the Cumulus preference center. Let’s review each step in more detail. 

Create a CloudPage Collection and Landing Page

After receiving the HTML design and content and confirming the private domain is set up in the account, Terry’s ready to create a collection in CloudPages. A collection is where you store all your pages associated with your preference center. Once the collection is created, Terry creates 3 pages. 

A collection of 3 pages in the Cumulus Preference Center.

Learn how to create a collection and page in CloudPages in this video. 

CloudPages URL

In order to securely pass information from a subscriber’s email into a CloudPage preference center, Terry plans to use the developer function: CloudPagesURL. This method passes information in an encrypted query string without passing subscriber information or values. This is used in the preference center code and in the email footer links. Let’s review the required syntax. 

Syntax: CloudPagesURL(1, 2, 3, [4a,4b]...)

Ordinal

Required

Type

Description

1

Required

string

Use the Page ID for the CloudPage you are referencing. 

2

Not required

string

Include the name for any additional parameters that should be included in an encrypted query string, for example, JobId. 

3

Not required

string

Include the value for the additional parameter included in an encrypted query string, for example, the specific job 1234.

4a

Not required

string

Include an additional parameter name.

4b

Not required

string or number

Include an additional parameter name.

Example: CloudPagesURL(44609, JobId, 1234)

Additional parameter names and value pairs can also be appended as arguments.  

Example: CloudPagesURL(ID, 'CampaignCode', @CampCode, 'SegmentName', @SegmentName)

Find a Page ID

Once a page has been created in CloudPages, you can find the Page ID by clicking the gear icon below your page.

Gear icon circled from the Cumulus Preference Center collection.

 The Page ID (1) is found under page details. 

Page Details shows the status, published date, created date, last updated date, URL, and Page ID. Page Details shows the status, published date, created date, last updated date, URL, and Page ID.]

Code Your Pages

Now that Terry has Page IDs and the CloudPages URL AMPscript ready, they can begin to add in the code needed to fulfill the functionality for each page within the preference center. 

There are various options for developers to complete these steps. While pages can be coded directly in CloudPages, the page needs to be republished after each update. To avoid republishing CloudPages frequently during development, pages can be built and tested outside of CloudPages. Let’s review those options.  

Coding Option

Description

AMPscript

Code in Content Builder 

Build your content in a Code Snippet in Content Builder and then use AMPscript in your CloudPage to automatically update changes.

%%=ContentBlockbyID("myContentBlock")=%%

Code externally

Build and host your code in a place like Dropbox or GitHub that can provide you with a public URL for your file. Then use AMPscript in your CloudPage to pull in your content.

%%=TreatAsContent(HTTPGet('https://somePublicallyAccessibleUrl'))=%%

While both of these options are helpful for development and testing, we recommend replacing the AMPscript with a copy of your final code pasted directly into CloudPages. By doing this you can avoid any data risks or processing issues, ensuring the fastest rendering times. 

Terry decides to code in Content Builder. Let’s review the code needed for each of the pages Terry creates for Cumulus Bank. 

Code the Unsubscribe Page

The unsubscribe page has two functions. First, update the preference center data extension. Second, update the All Subscribers list with a subscriber’s status. The first step is to look up a subscriber’s information based on the information passed via the URL using the CloudPagesURL AMPscript function. If either a subscriber key or email address is available, the subscriber’s information is updated in the Cumulus Preference Center using an upsert function.

%%[
      SET @SubscriberKey = [_subscriberkey]
      SET @EmailAddress = [emailaddr]
          IF EMPTY(@SubscriberKey) OR EMPTY(@EmailAddress) THEN
             SET @error = true
          ELSE
/*THE CLOUDPAGESURL WILL BE USED TO INDICATE THE PAGE THAT THE CONTENT WILL POST TO AFTER THE SUBSCRIBER SUBMITS THE FORM */
     SET @preferenceCenterLink = CloudPagesURL(44594)
     SET @Status = 'Unsubscribed'
     SET @WeeklyNews = 0
     SET @InvestmentRecs = 0
     SET @CashBack = 0
     SET @Savings = 0
     SET @Investments = 0
     SET @Retirement = 0
     SET @results = UpsertData('Cumulus Preference Center', 2, 'EmailAddress', @EmailAddress, 'SubscriberKey', @SubscriberKey, 'WeeklyNews', @WeeklyNews, 'InvestmentRecs', @InvestmentRecs, 'CashBack', @CashBack, 'Savings', @Savings, 'Investments', @Investments, 'Retirement', @Retirement, 'ModifiedDate',Now())

Next Terry uses the SOAP API via an AMPscript LogUnsubEvent call once the page is loaded to search for the user in the All Subscriber list. If the subscriber is not already unsubscribed, their status is updated to unsubscribe.

SET @rrObj = CreateObject("RetrieveRequest")
    SetObjectProperty(@rrObj, "ObjectType", "Subscriber")
    AddObjectArrayItem(@rrObj,"Properties","SubscriberKey")
    AddObjectArrayItem(@rrObj,"Properties","EmailAddress")
    AddObjectArrayItem(@rrObj,"Properties","Status")
SET @cObj = CreateObject("SimpleFilterPart")
    SetObjectProperty(@cObj, "Property", "SubscriberKey")
    SetObjectProperty(@cObj, "SimpleOperator", "equals")
    AddObjectArrayItem(@cObj, "Value",@SubscriberKey)
    SetObjectProperty(@rrObj, "Filter", @cObj)
SET @ResultSet = InvokeRetrieve(@rrObj)
IF Rowcount(@ResultSet) == 1 THEN
   SET @row = ROW(@ResultSet,1)
IF Field(@row,"Status") != @Status THEN
   SET @sub = CreateObject("Subscriber")
       SetObjectProperty(@sub,"EmailAddress", @EmailAddress)
       SetObjectProperty(@sub,"SubscriberKey", @SubscriberKey)
       SetObjectProperty(@sub,"Status",@Status)
   SET @options = CreateObject("UpdateOptions")
   SET @save = CreateObject("SaveOption")
       SetObjectProperty(@save,"SaveAction","UpdateAdd")
       SetObjectProperty(@save,"PropertyName","*")
       AddObjectArrayItem(@options,"SaveOptions", @save)
   SET @update_sub = InvokeUpdate(@sub, @update_sub_status,@update_sub_errorcode,  @options)
ENDIF   

If the call is successful, a success message is displayed. If an error occurs during the call, an error message is displayed. 

%%[
IF @error THEN
]%%
<div class="pref-block-noborder form-wrapper-noborder">
<p class="slds-text-heading_small" style="font-size: 1.45rem">
An error has occurred when updating your preferences, please contact Cumulus customer support to complete your request.
</p>
</div>
%%[
ELSE
]%%
<div class="pref-block-noborder form-wrapper-noborder">
<p class="slds-text-heading_small" style="font-size: 1.45rem">
You have been unsubscribed from all Marketing Communications from Cumulus Bank.  To modify your preferences, click the URL below to return to view your Preferences.
</p>
</div>
<form id="mainFormBody" action="%%=v(@preferenceCenterLink)=%%" method="post" enctype="application/x-www-form-urlencoded">
<div style="text-align: center; margin-bottom: 30px;">
<button class="form-button" id="submitBtn" type="submit">Preference Center</button>
</div>
</form>
%%[
ENDIF
]%%

Note

Check out the entire HTML for this page (UnsubscribeConfirmation.html) in our GitHub repo.

Code the Preference Center Page

With the unsubscribe page done, Terry moves on to the main page. In addition to adding in fields and reviewing the CSS code, AMPscript needs to be added to search for a user’s subscriber key and email address from the CloudPages URL. If not found, an error message is shown. If found, they are redirected to either the unsubscribe page or to the preference center confirmation page after submission.

%%[
SET @SubscriberKey = [_subscriberkey]
SET @EmailAddress = [emailaddr]
IF EMPTY(@SubscriberKey) OR EMPTY(@EmailAddress) THEN
SET @error = true
ELSE
SET @thankYouLink = CloudPagesURL(44375)
SET @unsubAll = CloudPagesURL(44609)

In order to preload existing customer data into the Cumulus Preference Center, the code searches the Cumulus Preference Center data extension to populate fields, if available. 

IF Length(@EmailAddress) > 0 THEN
SET @data = LookupRows("Cumulus Preference Center","EmailAddress", @EmailAddress, 'SubscriberKey', @SubscriberKey)
SET @rowCount = RowCount(@data)
IF @rowCount > 0 THEN
SET @row = Row(@data, 1)
SET @FirstName = Field(@row, "FirstName")
SET @LastName = Field(@row, "LastName")
SET @PhoneNumber = Field(@row, "PhoneNumber")
SET @StreetAddress = Field(@row, "StreetAddress")
SET @City = Field(@row, "City")
SET @State = Field(@row, "State")
SET @ZipCode = Field(@row, "ZipCode")
SET @WeeklyNews = Field(@row, "WeeklyNews")
SET @InvestmentRecs = Field(@row, "InvestmentRecs")
SET @CashBack = Field(@row, "CashBack")
SET @Savings = Field(@row, "Savings")
SET @Investments = Field(@row, "Investments")
SET @Retirement = Field(@row, "Retirement")
ELSE
SET @Error = true
ENDIF
ELSE
SET @Error = true
ENDIF
ENDIF
]%%

Code the Preference Center Confirmation Page

Finally, Terry needs to code the final processing page. They start with code that upserts new data to the Cumulus Preference Center data extension. Then the code checks to see the subscriber’s current Marketing Cloud Engagement status. If the status doesn’t match, the status is updated. 

SET @FirstName = RequestParameter('FirstName')
SET @LastName = RequestParameter('LastName')
SET @PhoneNumber = RequestParameter('PhoneNumber')
SET @StreetAddress = RequestParameter('StreetAddress')
SET @City = RequestParameter('City')
SET @State = RequestParameter('State')
SET @ZipCode = RequestParameter('ZipCode')
SET @preferenceCenterLink = CloudPagesURL(44594)
SET @Status = 'Active'
SET @WeeklyNews = IIF(EMPTY(RequestParameter('WeeklyNews')), 0, 1)
SET @InvestmentRecs = IIF(EMPTY(RequestParameter('InvestmentRecs')), 0, 1)
SET @CashBack = IIF(EMPTY(RequestParameter('CashBack')), 0, 1)
SET @Savings = IIF(EMPTY(RequestParameter('Savings')), 0, 1)
SET @Investments = IIF(EMPTY(RequestParameter('Investments')), 0, 1)
SET @Retirement = IIF(EMPTY(RequestParameter('Retirement')), 0, 1)
SET @results = UpsertData('Cumulus Preference Center', 2, 'EmailAddress', @EmailAddress, 'SubscriberKey', @SubscriberKey, 'FirstName', @FirstName, 'LastName', @LastName, 'PhoneNumber', @PhoneNumber, 'StreetAddress', @StreetAddress, 'City', @City, 'State', @State, 'ZipCode', @ZipCode, 'WeeklyNews', @WeeklyNews, 'InvestmentRecs', @InvestmentRecs, 'CashBack', @CashBack, 'Savings', @Savings, 'Investments', @Investments, 'Retirement', @Retirement, 'ModifiedDate',Now())
SET @rrObj = CreateObject("RetrieveRequest")
    SetObjectProperty(@rrObj, "ObjectType", "Subscriber")
    AddObjectArrayItem(@rrObj,"Properties","SubscriberKey")
    AddObjectArrayItem(@rrObj,"Properties","EmailAddress")
    AddObjectArrayItem(@rrObj,"Properties","Status")
SET @cObj = CreateObject("SimpleFilterPart")
    SetObjectProperty(@cObj, "Property", "SubscriberKey")
    SetObjectProperty(@cObj, "SimpleOperator", "equals")
    AddObjectArrayItem(@cObj, "Value",@SubscriberKey)
    SetObjectProperty(@rrObj, "Filter", @cObj)
SET @ResultSet = InvokeRetrieve(@rrObj)
IF Rowcount(@ResultSet) == 1 THEN
SET @row = ROW(@ResultSet,1)
IF Field(@row,"Status") != @Status THEN
SET @sub = CreateObject("Subscriber")
    SetObjectProperty(@sub,"EmailAddress", @EmailAddress)
    SetObjectProperty(@sub,"SubscriberKey", @SubscriberKey)
    SetObjectProperty(@sub,"Status",@Status)
SET @options = CreateObject("UpdateOptions")
SET @save = CreateObject("SaveOption")
    SetObjectProperty(@save,"SaveAction","UpdateAdd")
    SetObjectProperty(@save,"PropertyName","*")
    AddObjectArrayItem(@options,"SaveOptions", @save)
SET @update_sub = InvokeUpdate(@sub, @update_sub_status, @update_sub_errorcode, @options)
ENDIF
ENDIF
ENDIF
]%%

Note

Review the HTML for these pages (PreferenceCenter.html and PreferenceConfirmation.html) in our GitHub repo.

Next Up: Test Your Solution

Now that your pages are built and coded, it’s time to test your solution.

Resources

Compartilhe seu feedback do Trailhead usando a Ajuda do Salesforce.

Queremos saber sobre sua experiência com o Trailhead. Agora você pode acessar o novo formulário de feedback, a qualquer momento, no site Ajuda do Salesforce.

Saiba mais Continue compartilhando feedback