As an email marketer, I'm no stranger to random unsubscribe requests with nothing but an email address. Sometimes it's from customer service after someone called/emailed asking... sometimes it's from the legal/privacy team with a customer wanting their data deleted and all communications stopped... sometimes it's a random employee whose family member or neighbor says we send too many emails.
Or, as explained in my previous article, sometimes it's because one of the planet's largest email platforms decided to expire all historical links, so now your unsubscribe page doesn't work and you needed to create an emergency page to capture opt-out requests.
Read more:
https://ampscript-ninja.hashnode.dev/how-to-manage-expired-links-in-sfmc
Whatever your use case is, following are some easy options for manually processing unsubscribes.
Emergency Opt-Out Page
Hot on the heels of SFMC's link expiration issues, let's talk about how to capture opt-out requests, and having your link expiration page have a link to a basic CloudPage is a great solution for this.
First, you could do a Smart Capture form, which is their drag-and-drop form option that loads to a data extension and optionally triggers an email out of Journey Builder.
Salesforce Help:
https://help.salesforce.com/s/articleView?id=mktg.mc_cp_create_a_smart_capture_form_in_cloudpages.htm&type=5
Second, you build your own basic HTML form and use the AMPscript InsertData() function to record submissions to a data extension.
Tim Ziter with Hands On SFMC outlines it well here:
https://handsonsfmc.com/building-a-basic-form-in-a-cloud-page/
For my own page, I went with the second option - a basic custom form asking for only an email address and posting it to a data extension. I already had a custom unsubscribe page hosted in CloudPages, with error logging to a data extension for page loads without all of the required information (subscriber key, email address, Publication List ID, Job ID, etc.), so it was relatively easy to add a fallback version where if the page loads with no information, it asks for email address and records it to my existing data extension.
Whichever approach you take, here are some guidelines when setting up your data extension - these settings are important later on for my Subscription Center solution.
Create a subscriber_key field that is optional/nullable since your page won't populate it, but you'll add it later (this is important)
Create an email field for the page to write to
Mark your data extension as Used For Sending: Yes and Used For Testing: Yes
Managing Unsubscribes
Once you have a basic CloudPage recording email address to a data extension for manual follow-up, you have several options to process them. Let's walk through those options, starting with the simplest.
Low Complexity: Manage Directly In All Subscribers
Open your data extension in Contact Builder - this allows you to edit records if you need to add information, or delete once you've successfully processed the request.
In a second tab, open Email Studio > Subscribers > All Subscribers and click Search.
This will show the subscriber key(s) associated with that email address. Selecting one, clicking View Properties, and going to the Lists tab will show that subscriber's Publication Lists.
Selecting a list, clicking Details, and then clicking Unsubscribe will change the subscriber's status on that list to unsubscribed, preventing future sends of emails with that publication list selected.
My Opinion: This is the easiest option, but not the best. I won't say authoritatively that unsubscribes with this method aren't shared, but in my own personal testing, unsubscribes did not consistently, reliably appear in the Unsubs tracking extract. If you're sharing unsubscribes with CRM or another system with tracking extracts, then I don't recommend this option.
Low Complexity: Use The Existing Subscription Center
If you're already using SFMC's default Subscription Center links in your emails, you can use that to manage Publication Lists for a specific subscriber.
Like before, open your data extension in Contact Builder in one tab and All Subscribers in another.
Search the email address in All Subscribers to get the subscriber key. Copy the subscriber key, select the data extension record in Contact Builder, click Edit, paste the subscriber key in the appropriate field (remember from above? you already set that up as an optional field), and Save.
Now that your data extension has both subscriber key and email address, you can use it to preview an email. Open Content Builder in a third tab. You can use any existing email with the default Subscription Center link, but to avoid manual unsubscribes from being attributed to a real email in reporting, I recommend you create a separate email template specifically for managing unsubscribes.
All you need is to set your subscriber key and email address, and add the Subscription Center link.
%%[
/* STARTING INFO FROM DATA EXTENSION */
set @subscriber_key = subscriber_key
set @email = email
]%%
Open the <a href="%%subscription_center_url%%" target="_blank">Subscription Center</a>
Preview your email using the record in your data extension, and click the Subscription Center link... but wait, you can't do that from a preview inside the email platform! You'll see a link that just says:
javascript:void(0)Not to worry, we can get around this with a test send. Before you fire your test send, make sure the very last checkbox, Enable System Generated Links, is checked. This will generate SFMC system links, including the one to Subscription Center. Send your test email.
Go to your inbox, open your email, and click the Subscription Center link - you're now seeing it as that subscriber, exactly as if they'd clicked the link themselves. You can now remove them from Publication Lists or Unsubscribe From All as needed.
My Opinion: This is the easiest, most reliable option that doesn't require a custom AMPscript development.
Medium Complexity: Link To Your Custom Unsubscribe Page
If you already have a custom unsubscribe page or preference center, you're probably linking to that page with the AMPscript CloudPagesURL() function to pass subscriber info (subscriber key and email address), publication info (Publication List ID, maybe a brand or content type), and probably email info (Job ID, Batch ID). That page likely uses AMPscript or another method to call the Salesforce SOAP API and post a Log Unsub Event.
Instead of creating a way into the Subscription Center for the specified subscriber, you'll create the necessary link(s) into your existing page(s) instead.
The first few steps are the same - get the email address from the data extension, search it in All Subscribers to get the subscriber key, and enter the subscriber key in the data extension so it can be used to preview an email.
If you have an all-in-one custom preference center, then your email template just needs to have a fully constructed CloudPagesURL() function to your preference center page. When you preview as the subscriber in your data extension, you should be able to click into the preference center and make changes exactly as that subscriber would.
If you have a simpler unsubscribe page that only processes unsubscribes from a single Publication List, then your email template can have multiple links.
In your custom email, you'll use an AMPscript data extension lookup against the _ListSubscribers data view to see all Publication Lists by status.
In a
forloop, go through each Publication List, and add the necessary information you need to generate a link to your custom unsubscribe page.
That might look something like this:
%%[
/* Lookup all Publication Lists from the _ListSubscribers data view, ordered by 'ListName', matching on 'SubscriberKey'. */
set @publication_lists_rows = LookupOrderedRows('_ListSubscribers',0,'ListName asc','SubscriberKey',@subscriber_key)
/* If there are results, show them below. */
if RowCount(@publication_lists_rows) >= 1 then
set @show_lists_results = true
endif
]%%
%%[if @show_lists_results == true then]%%
<tr>
<td width="600" align="left">
<table align="left" cellspacing="0" cellpadding="0" border="0"">
<tr>
<td>
<strong>Publication List </strong>
</td>
<td>
<strong>ID </strong>
</td>
<td>
<strong>Status </strong>
</td>
<td>
<strong>Link</strong>
</td>
</tr>
%%[
/* Loop through the Publication Lists to get the list ID, name, and status. */
for @l = 1 to RowCount(@publication_lists_rows) do
set @publication_list_match = Row(@publication_lists_rows,@l)
set @l_list_id = Field(@publication_list_match,'ListID')
set @l_list_name = Field(@publication_list_match,'ListName')
set @l_list_status = Propercase(Field(@publication_list_match,'Status'))
set @l_email = Field(@publication_list_match,'EmailAddress')
/* Based on the Publication List name, set additional variables as needed to be able to construct the unsubscribe URL. */
set @l_brand = ''
set @unsub_link = ''
if IndexOf(@l_list_name,'Example') != 0 then
set @l_brand = 'EXA'
set @unsub_page_id = '1000'
elseif IndexOf(@l_list_name,'Sample') != 0 then
set @l_brand = 'SAM'
set @unsub_page_id = '2000'
endif
/* Construct the unsubscribe link. */
if @l_list_status == 'Active' and not Empty(@l_brand) then
set @job_id = 0
set @batch_id = 0
set @unsub_brand = @l_brand
set @unsub_link = CloudPagesURL(@unsub_page_id,'subscriber_key',@subscriber_key,'email',@l_email,'job_id',@job_id,'batch_id',@batch_id,'unsub_brand',@unsub_brand)
endif
]%%
<tr>
<td>
%%=v(@l_list_name)=%%
</td>
<td>
%%=v(@l_list_id)=%%
</td>
<td>
%%=v(@l_list_status)=%%
</td>
<td>
%%[if not Empty(@unsub_link) then]%%<a class="link link-ext" href="%%=RedirectTo(@unsub_link)=%%" target="_blank">Unsubscribe</a>%%[endif]%%
</td>
</tr>
%%[next @l]%%
</table>
</td>
</tr>
%%[endif]%%
This should result in a list of Publication Lists, with status, and if the status is Active, a link out to the appropriate unsubscribe page for that subscriber.
Highest Complexity: Fully Custom One-Click Solution
If you're looking for an all-in-one solution that eliminates all manual work, the only limit with AMPscript is your imagination. Here is an outline of my current custom solution.
I have a secure CloudPage that only select users can access.
A form page searches an email address, and uses this solution by Shashi Prasad to search all Subscriber Keys associated with an email address, preventing the need to search in All Subscribers.
For each subscriber key returned, I use the AMPscript above to search all Publication Lists and generate all the unsubscribe URLs.
Net result: I have one page with all list statuses and all unsubscribe links, in one place, from a single email address copy/paste.
Of course, that can still be a fair amount of clicking to process all those unsubscribes, so I'd like to enhance this further someday:
The first page would use a data extension look up to list all email addresses currently in the data extension for follow-up. Clicking an email address would open the current page in a new tab, which would eliminate the copy/paste step.
Following all of the lists-by-subscribers results, an Unsubscribe From All button would reload the page, fire a LogUnsubEvent for every active Publication List for each subscriber key, and save and display all the results on screen.
If you wanted to get crazy, you could eliminate the human step altogether and have a custom unsubscribe page do all of this automatically as soon as someone enters an email address. That would be extremely efficient. Personally, I prefer the human review element for something like this to protect against abuse or fraud, but I'd like the human steps to be as fast and as few clicks as possible.
Ultimately, the best solution for each team is the solution they can efficiently execute themselves. I hope this post provided some easy options (or thought starters on complex options) to get you started, and I'd love to hear additional ideas for making the process as efficient as possible.
Top comments (0)