1

What I would like to achieve is an email unsubscribe process that is secure, performant and on an external page with the ability to update the internal system table (dataview) _Unsubscribe.

How I imagined this to work is like this:

  1. Create an AMPScript variable inside a newsletter that stores the values that are needed for the _Unsubscribe dataview separated by a special character
  2. Encrypt the variable with AES
  3. Create an Unsubscribe Link in the e-mail with a typical a href to our external page and and concat with encrypted variable on it as a parameter value. First three points shown here?
  4. Decrypt the url-parameter with the backend of our external shopengine and store it in different variables (RegEx on special sign)
  5. Use the client-id and secret from a package created in the marketing cloud
  6. Retrieve the access token
  7. Do the last two steps with Java Axis 1.4 or something else
  8. Create a SOAP-API Call and insert the values into it
  9. Send this data to the right endpoint (which is?) when the user clicks the unsubscribe button in the website

Here my Questions:

  • Is this the right way to do it?
  • Is there a simpler way when you are using an external page and not cloudpages?
  • Is the point 2 secure, what do i have to make sure that point 2 is secure?
  • Are there any documents you know that can help me with this task?

Kind regards for reading

  • Is this a one click unsub or would this be a click that takes them to a form to unsub? – Gortonington Dec 4 '18 at 14:31
  • 1
    Salesforce does not support 3rd party encryption, and support has told me that their encryption methods include a private salt that is unique to each stack, which means using traditional means to encrypt/decrypt AES/DES will fail. I've attempted this and found that to be the case, at least on S1. I was thinking about a workaround to this recently, and here's my thoughts: You'd need to AES Encrypt the SubscriberKey in Salesforce and then post the encrypted value to a data extension which you then retrieve by asking it to decrypt that field in the API call on the Marketing Cloud side – Matthew Wash Dec 4 '18 at 18:48
7

Logging an unsub event is the way to get unsubscribes logged properly (and ultimately in the _Unsubscribe data view). You can't insert into directly into any of the data views.

You'd need jobID, listID, _JobSubscriberBatchID and an encrypted or obfuscated _subscriberkey to replicate what's done on a one-click unsubscribe page. You may be able to pass and use SubscriberID to get around the encryption part, but I haven't tested the API call with that value.

Here's the code in AMPscript. The SOAP call would use these same objects and methods:

%%[

var @debug
var @jid
var @listid
var @batchid
var @email
var @skey
var @reason
var @unsubscribeAll

set @debug = 0
set @jid = AttributeValue("jobid")
set @listid = AttributeValue("listid")
set @batchid = AttributeValue("_JobSubscriberBatchID")
set @email = AttributeValue("emailaddr")
set @skey = AttributeValue("_subscriberkey")
set @reason = "One-Click Unsubscribe"
set @unsubscribeAll = RequestParameter("ua")

/* if we know the subscriber */
if not empty(@skey) then

   var @lue
   var @lue_prop
   var @lue_statusCode
   var @overallStatus
   var @requestId
   var @Response
   var @Status
   var @Error

   /* 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", @skey)
   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")

endif

if @debug == 1 then
  output(concat("<br>jid: ", @jid))
  output(concat("<br>listid: ", @listid))
  output(concat("<br>batchid: ", @batchid))
  output(concat("<br>email: ", @email))
  output(concat("<br>skey: ", @skey))
  output(concat("<br>reason: ", @reason))
  output(concat("<br>unsubscribeAll: ", @unsubscribeAll))
  output(concat("<br>overallStatus: ", @overallStatus))
  output(concat("<br>requestId: ", @requestId))
  output(concat("<br>Response: ", @Response))
  output(concat("<br>Status: ", @Status))
  output(concat("<br>Error: ", @Error))
endif

]%%

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.