Using AMPscript/SSJS to unsubscribe from a parent business unit on a CloudPage from a child business unit?

If you click ‘Unsubscribe from All’ on the Subscriber in the Subscriber Properties modal in the parent business unit’s context or when you perform an SSJS subscriber.Unsubscribe(); on a CloudPage on the parent business unit the result is the subscriber is unsubscribed from all child business units too. I’ve attached a picture that should help:

enter image description here

Can you perform that same process on the Parent Business Unit if the CloudPage belongs to the Child Business Unit?

I’ve tried a couple of solutions and it doesn’t seem possible

If you run the code below on a CloudPage that belongs to a Child Business Unit, it will perform a Master Unsubscribe the user from Child Business Unit that the CloudPage belongs to.

<script runat="server">
  Platform.Load("Core","1.1.1");

  var subscriberKey = Request.GetQueryStringParameter("skey");
  var subscriber = Subscriber.Init(subscriberKey);
  var status = subscriber.Unsubscribe();
</script>

I’ve also tried a suggestion from a similar answer I received for a different question:

<script runat="server">
  var subscriberKey = Request.GetQueryStringParameter("skey");
  var businessUnitId = Request.GetQueryStringParameter("clientId");
  var prox = new Script.Util.WSProxy();
  prox.setClientId({ "ID": businessUnitId }); //Proxy impersonates the parent BU
  var props = [
    { Name: "SubscriberKey", Value: subscriberKey },
  ];
  var data = prox.execute(props, "LogUnsubEvent");
</script>

However, I received the below error, presumably because you cannot impersonate a parent business unit from a child business unit:

{
  "Status": "Error",
  "RequestID": "<<request-id>>",
  "Results": [
    {
      "StatusCode": "Error",
      "StatusMessage": "RequestID: <<request-id>> Message: MemberID 123456789 does not have access to ClientID: ID[012345678] PartnerClientKey[] UserID[] PartnerUserKey[] supplied in the request",
      "OrdinalID": 0,
      "Results": null,
      "ErrorCode": 0
    }
  ]
}

Maybe there is a means of granting access?

Answer

Following script from Adam Spriggs works like a charm:
https://sprignaturemoves.com/one-click-unsubscribe-with-ampscript/

%%[

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

]%%

Attribution
Source : Link , Question Author : Rick Locke , Answer Author : zuzannamj

Leave a Comment