SFMC | Consent management

Marketing Automation, Salesforce Marketing Cloud
6 minutes read

Even after a couple of years working with Salesforce Marketing Cloud, I am still somewhat lost on how the consent management works. I’ve decided to tackle all the uncertainties I’ve been avoiding since I first started. Let’s dive into this topic and resolve all doubts once and for all.

As you might have noticed, there are two places where you can view contact details. First, you can navigate to Email Studio and search for a specific contact to see their consent details. Email studio uses subscriber key as unique contact identifier. This means that when you need to contact the same email address but with different subscriber keys, Marketing Cloud treats them as separate contacts. Contact Builder for same a contact key, which is equal to Email Studio’s subscriber key. Are you feeling confused already? Stay with me.

A good practice is to maintain consistency with the subscriber key/contact key across all studios and builders. Identify a unique identifier that will serve as your subscriber/contact key.

In cases where your data is sourced from external systems and passed to Marketing Cloud via MC Connect (such as Sales Cloud, Service Cloud, or CDP), it is considered a best practice to use the unique ID from that system if it is available.

It seems that the unsubscribe information is not visible in Contact Builder, and I am unable to manually unsubscribe contacts from there. I’ll put this on my todo list.

From salesforce help a subscriber has the option to unsubscribe from emails at four different levels:

  1. List-Level Unsubscribe: When a subscriber unsubscribes at the list level, they will no longer receive emails sent to that specific list or publication list. It’s important to note that unsubscribing at the list level differs from removing a subscriber from the list. If you remove a subscriber, you have the option to add them again in the future through an import. However, if you unsubscribe a subscriber, their status remains ‘Unsubscribed,’ even if you later import them again.
  2. Account-Level Unsubscribe or Universal Unsubscribe: Subscribers who unsubscribe at the account level are marked as ‘Unsubscribed’ on your All Subscribers list. This status applies to all current and future lists within your account.
  3. Global Unsubscribe: When a subscriber unsubscribes at the global level, their status is recorded in a dedicated table within the Marketing Cloud database. This action effectively unsubscribes them from all present and future lists across all Salesforce Marketing Cloud accounts

In Enterprise 2.0 account admin can choose following in subscribption settings:

  • Subscribers will be unsubscribed from all business units in the Enterprise
  • Subscribers will be unsubscribed from this business unit only

Read more on salesforce help on subscription settings topic.

Enterprise 2.0: A tenant is the top-level account and all associated business units. Read more about tenant types on salesforce help.

You can retrieve the Status via SOAP API or via query studio:

SELECT AddedBy,
       AddMethod,
       ListName,
       EmailAddress,
       Status,
       ListType
FROM   _listsubscribers
WHERE  subscriberkey = 'subscriber_key' AND ListName = 'list_name' 

Use ent. prefix before view _listsubscribers when you want to get data from the All subscribers list in case your account has multiple business unites

For retrieving subsciber status take a look at the salesforce marketing cloud postman SOAP library and look for Retrieve Subscriber. You will need to set up a filter to filter by subscriber key and by the list id. List id can be visible when browsing specific list parameters.

Where and how contact can unsubscribe?

In my experience, almost none of my clients have utilized the out-of-the-box (OOTB) one-click unsubscribe or the preference center offered by Salesforce Marketing Cloud. The primary reason behind this is the insufficiency of customization. Each time, the clients’ needs have exceeded what is currently provided by the marketing platform’s no-code unsubscribe solution.

Two-click unsubscribe

As we onboard subscribers to our publication lists, we follow the well-established “double opt-in” process. Additionally, to prevent accidental clicks on the opt-out link within our email communications, we often request that subscribers, upon landing on the unsubscribe page, confirm their intention to proceed with the unsubscription. This added step ensures that the unsubscribe action is deliberate and reduces the likelihood of unintended opt-outs.

Preference center

To effectively handle various subscriptions to different publication lists or collect additional user information, the solution is to create a custom Cloud Page. This enables us to tailor the user experience and gather the necessary data in a way that suits our specific requirements.

To manage the unsubscription process in Salesforce Marketing Cloud, it is essential to design your process around the LogUnsubEvent function. This function provides a convenient and flexible approach to handling unsubscribes when constructing a custom-tailored unsubscribe process.This function enables you to execute two essential actions: unsubscribing a subscriber and recording an UnsubEvent linked to a particular email campaign (Job). This logging plays a critical role in tracking the email that triggered the subscriber’s decision to unsubscribe and allows you to monitor these results through your tracking dashboard. You have the flexibility to configure this function to unsubscribe a subscriber from a specific list, publication list, or all emails, effectively blocking them from receiving any future email communications.

%%[

set @unsubscribeAll = QueryParameter("ua")
set  @reason =  QueryParameter("reason")
set @jid = AttributeValue("jobid")
set @listId = AttributeValue("listid")
set @batchId = AttributeValue("_JobSubscriberBatchID")
set @email = AttributeValue("emailaddr")
set @subscriberKey = AttributeValue("_subscriberkey")

/* if we know the subscriber */
if not empty(@subscriberkey) then
  
  /* if unsubscribing from all, then set the job, batch and listids to blank, effectively doing a global unsub */
  if @unsubscribeAll == "1" then
   set @jid = ""
   set @listId = ""
   set @batchId = ""
  endif

  /* create a request to inject an unsub event into the LogUnsubEvent platform table */
  set @lue = CreateObject("ExecuteRequest")
  SetObjectProperty(@lue,"Name","LogUnsubEvent")

  /*
  In order to invoke the request, we need to associate the following information with it to define the subscriber context and the job context:

  1. Subscriber Key
  2. JobId associated with the email send
  3. ListID the email was sent to
  4. BatchID the email was sent to
  5. Reason for the unsub
  */

  /* 1. define and associate Subscriber Key to the request */
  set @lue_prop = CreateObject("APIProperty")
  SetObjectProperty(@lue_prop, "Name", "SubscriberKey")
  SetObjectProperty(@lue_prop, "Value", @subscriberKey)
  AddObjectArrayItem(@lue, "Parameters", @lue_prop)

  /* 2. define and associate JobID to the request */
  if not empty(@jid) then
    set @lue_prop = CreateObject("APIProperty")
    SetObjectProperty(@lue_prop, "Name", "JobID")
    SetObjectProperty(@lue_prop, "Value", @jid)
    AddObjectArrayItem(@lue, "Parameters", @lue_prop)
  endif

  /* 3. define and associate ListID to the request */
  if not empty(@listid) then
     set @lue_prop = CreateObject("APIProperty")
     SetObjectProperty(@lue_prop, "Name", "ListID")
     SetObjectProperty(@lue_prop, "Value", @listId)
     AddObjectArrayItem(@lue, "Parameters", @lue_prop)
  endif

  /* 4. define and associate BatchID to the request */
  if not empty(@batchid) then
    set @lue_prop = CreateObject("APIProperty")
    SetObjectProperty(@lue_prop, "Name", "BatchID")
    SetObjectProperty(@lue_prop, "Value", @batchId)
    AddObjectArrayItem(@lue, "Parameters", @lue_prop)
  endif

  /* 5. define and associate unsub reason to the request */
  set @lue_prop = CreateObject("APIProperty")
  SetObjectProperty(@lue_prop, "Name", "Reason")
  SetObjectProperty(@lue_prop, "Value", @reason)
  AddObjectArrayItem(@lue, "Parameters", @lue_prop)

  /* finally, you invoke the request */
  set @lue_statusCode = InvokeExecute(@lue, @overallStatus, @requestId)

  /* extract messages from the response */
  set @Response = Row(@lue_statusCode, 1)
  set @Status = Field(@Response,"StatusMessage")
  set @Error = Field(@Response,"ErrorCode")


]%%

Browse the source code

Feedback loop

A feedback loop is a mechanism where an Internet service provider (ISP) shares complaints about spam and opt-out requests from its users with the senders of the problematic messages. In cases where ISPs utilize this feedback loop to relay complaints to Marketing Cloud, the subscriber who made the complaint is automatically unsubscribed at the account level.

Reply Mail Management feature

If you’ve set up the reply mail management feature and a subscriber responds with one of the unsubscribe keywords either in the subject line or the body of the email, the system will take care of the unsubscribe process automatically, unsubscribing the subscriber at the account level.

However, if you haven’t configured reply mail management for your account, you’ll need to handle leave requests manually when you receive them.

Salesforce Marketing Cloud Tips
Marketing Automation, Salesforce Marketing Cloud, SFMC Tips & Tricks

SFMC TIP | Add html variation to proof subejct

1 minute read

Issues arise when an email’s HTML contains personalization that includes multiple different variants, that is altering the appearance of the personalized email. Quality assurance (QA) of such proofs can become exceptionally challenging, particularly in cases where there are minor changes across variants or a substantial number of variants present. You can devide your variants by … Read more

Continue reading
Salesforce Marketing Cloud Tips
Marketing Automation, Salesforce Marketing Cloud, SFMC Tips & Tricks

SFMC TIP | Troubleshooting Data Extensions

1 minute read

There are other aspects that I find rather unknown; while there is likely a rational explanation, the platform doesn’t provide straightforward answers. Here are some learnings of mine while working with data extensions: Importing in Contact Builder throws a validation error on the date field. The same file has been successfully imported via Email Studio.

Continue reading
Salesforce Marketing Cloud Tips
Marketing Automation, Salesforce Marketing Cloud, SFMC Tips & Tricks

SFMC TIP | Change data extension settings

less than a minute read

Sometimes, it can happen that you want to modify field properties, such as adding a primary key or changing the length of certain fields. However, even in these situations, you might encounter some unusual behaviors that you should be prepared for. To modify attributes, like changing from nullable to non-nullable or setting a different primary … Read more

Continue reading
Queries in SSJS and AMPScript
Marketing Automation, Salesforce Marketing Cloud

SFMC | Query data extension in SSJS and AMPScript

1 minute read

There’s another topic for which official documentation often lacks sufficient information, but it can be incredibly useful when needed. It’s important to note that in AMPScript, we use the data extension name to reference the table for any query. On the other hand, in SSJS, we utilize the data extension’s external key to reference the … Read more

Continue reading
Adobe Campaign Classic tips
ACC Tips & Tricks, Adobe Campaign, Marketing Automation

ACC TIP | How to copy query conditions

1 minute read

Perhaps you’ve encountered an unusual occurrence while attempting to copy complex query conditions to your clipboard. In some instances, only a portion of the content was copied, while in others, nothing was copied at all. I’ve personally faced similar situations over the years but never delved deeper into the matter. However, one day, I reached … Read more

Continue reading
Salesforce Marketing Cloud Tips
Marketing Automation, Salesforce Marketing Cloud, SFMC Tips & Tricks

SFMC TIP | Journey validation fails for no reason

less than a minute read

There is an error with starting the journey, specifically related to the email template, but it gives you no explanation whatsoever. I’m sure there can be many problems with the template that prevent the journey from being started. One of the problems I have experienced most recently is that the template has not been approved. … Read more

Continue reading
Salesforce Marketing Cloud Tips
Marketing Automation, Salesforce Marketing Cloud, SFMC Tips & Tricks

SFMC TIP | Track links in AMPScript variables

1 minute read

When you save links as part of an HTML code in an AMPScript variable, such as a paragraph containing a link to a page, you may face challenges in tracking these links. Salesforce offers a great feature that allows tracking of such links using the “httpgetwrap” inserted right before the URL protocol. When dealing with … Read more

Continue reading
how to publish cloud page immediatelly
Marketing Automation, Salesforce Marketing Cloud, SFMC Tips & Tricks

SFMC TIP | How to publish cloud page immediately

2 minutes read

You know the struggle when developing a cloud page application and trying to debug some issues or make changes. You publish the cloud page and wait and wait. Sometimes it takes ages, and other times it is right away. Why does this happen? How can we make it work immediately? Why we have to endure … Read more

Continue reading
Adobe Campaign Classic tips
ACC Tips & Tricks, Adobe Campaign, Marketing Automation

ACC TIP | Troubleshooting web applications

1 minute read

When building any web application (webapp), you may have experienced a syntax error on, for example, line 200. This can be perplexing, especially when your custom JavaScript code does not even have 200 lines. Why is that? The reason for this discrepancy is that the web applications you create in the visual editor are compiled … Read more

Continue reading