Last active
July 15, 2024 21:56
-
-
Save VijayaSankarN/e34fcf2c13199971abad7082cb140377 to your computer and use it in GitHub Desktop.
Marketing Cloud - Custom Preference (Profile & Subscription) Center - Profile Center using SSJS and AMPScript. (Cloud Page Solution). For explanation: https://vijayasankarn.wordpress.com/2023/03/10/marketing-cloud-custom-profile-subscription-center/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0" /> | |
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> | |
<meta charset="utf-8" /> | |
<meta http-equiv="x-ua-compatible" content="ie=edge" /> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
<title>Custom Profile/Subscription Center</title> | |
</head> | |
<body> | |
%%[ | |
SET @subscriberKey = [_subscriberkey] | |
]%% | |
<script runat="server" language="JavaScript"> | |
Platform.Load("core","1.1.2"); | |
////////////////////////////// | |
// CUSTOMIZATION SECTION START | |
////////////////////////////// | |
// Needed Profile Attributes (Profile Management) | |
var profileInfo_needed = ["First Name", "Last Name"]; | |
// Needed Preferences (Preference Management) | |
var preferences_needed = ["Adventure", "Purchase"]; | |
// Needed Lists (My Lists) | |
var mylists_needed = ["HTML Email"]; | |
// Needed Lists (Publication Lists) | |
var publicationsList_needed = ["Monthly Newsletter", "Monthly Magazine"]; | |
////////////////////////////// | |
// CUSTOMIZATION SECTION END | |
////////////////////////////// | |
try { | |
var subscriberKey = Variable.GetValue("@subscriberKey"); | |
var attributes_needed = profileInfo_needed.concat(preferences_needed); | |
var lists_needed = mylists_needed.concat(publicationsList_needed); | |
var init_subscriber = Subscriber.Init(subscriberKey); | |
var init_subscriberAttributes = init_subscriber.Attributes.Retrieve(); | |
var init_subscriberList = init_subscriber.Lists.Retrieve(); | |
var init_list = List.Retrieve({Property: "ListName", SimpleOperator: "IN", Value: lists_needed}); | |
var profileInfo_keys = createKeys(profileInfo_needed, "profileInfo"); | |
var preferences_keys = createKeys(preferences_needed, "preference"); | |
var lists_keys = createKeys(lists_needed, "list"); | |
var profileInfo_values = []; | |
var preferences_values = []; | |
var lists_values = []; | |
var lists_ID = []; | |
// Get Subscriber Details | |
var subscriberDetails = Subscriber.Retrieve({ | |
Property: "SubscriberKey", | |
SimpleOperator: "equals", | |
Value: subscriberKey | |
}); | |
// Create Subscriber Object | |
var subscriberObject = { | |
"Subscriber Key" : subscriberKey, | |
"Email Address" : subscriberDetails[0].EmailAddress, | |
"Status" : (subscriberDetails[0].Status == "Active") | |
}; | |
// Generate Subscriber Object | |
for(s=0; s<init_subscriberAttributes.length; s++) { | |
for(n=0; n<attributes_needed.length; n++) { | |
if(attributes_needed[n].indexOf(init_subscriberAttributes[s].Name) > -1) { | |
subscriberObject[init_subscriberAttributes[s].Name] = init_subscriberAttributes[s].Value; | |
break; | |
} | |
} | |
} | |
for(n=0; n<profileInfo_needed.length; n++) { | |
profileInfo_values.push(subscriberObject[profileInfo_needed[n]]); | |
} | |
for(n=0; n<preferences_needed.length; n++) { | |
preferences_values.push(subscriberObject[preferences_needed[n]] == "True" ? "Checked" : ""); | |
} | |
/* | |
Match the Subscription details with the Pre-Subscribed publication lists | |
Note: When the subscriber is not subscribed to a publication list earlier, then it would end up | |
with failure - Key wouldn't be found in the init_subscriberList, so isFound is used to manage | |
empty initialization | |
*/ | |
for(n=0; n<lists_needed.length; n++) { | |
var isFound = false; | |
// Get Subscriber current Subscription Status | |
for(i=0; i<init_subscriberList.length; i++) { | |
if(init_subscriberList[i].List.Name == lists_needed[n]) { | |
if(init_subscriberList[i].Status == "Active" && !init_subscriberList[i].hasOwnProperty('UnsubscribedDate')) { | |
lists_values.push("Checked"); | |
isFound = true; | |
} | |
break; | |
} | |
} | |
if(!isFound) { | |
lists_values.push(''); | |
} | |
// Get Publication List's ID | |
for(j=0; j<init_list.length; j++) { | |
if(init_list[j].ListName == lists_needed[n]) { | |
lists_ID.push(init_list[j].ID); | |
break; | |
} | |
} | |
} | |
if(subscriberDetails[0].Status == "Active") { | |
Variable.SetValue("subscriptionStatus", true); | |
} else { | |
Variable.SetValue("subscriptionStatus", false); | |
} | |
// Form Submit Validation | |
var isFormSubmitted = Platform.Request.GetFormField('isFormSubmitted') || false; | |
// Unsubsubcribe from all | |
var unsubscribe = Platform.Request.GetFormField('unsubscribe') ? true : false; | |
if(isFormSubmitted) { | |
var emailAddress = Platform.Request.GetFormField('emailAddress') || ""; | |
var listsObj = []; | |
var subscriberData = { | |
"Attributes": {}, | |
"EmailAddress": emailAddress | |
}; | |
// Build Attributes to save | |
for(n=0; n<profileInfo_needed.length; n++) { | |
subscriberData.Attributes[profileInfo_needed[n]] = Platform.Request.GetFormField(profileInfo_keys[n] + "-profileInfo") || ""; | |
} | |
for(n=0; n<preferences_needed.length; n++) { | |
subscriberData.Attributes[preferences_needed[n]] = Platform.Request.GetFormField(preferences_keys[n] + "-preference") ? true : false; | |
} | |
for(n=0; n<lists_needed.length; n++) { | |
listsObj.push({ | |
ID: lists_ID[n], | |
Status: Platform.Request.GetFormField(lists_keys[n] + "") ? 'Active' : 'Unsubscribed' | |
}); | |
} | |
/* SUBSCRIPTION HANDLER | |
* Unsubscribes only if the user unsubscribes from the form | |
* If the user is already, unsubscribed, this will be ignored | |
*/ | |
var status_unsubscribe = "NA"; | |
var status_resubscribe = "NA"; | |
if(subscriberObject.Status == unsubscribe) { | |
if(unsubscribe) { | |
status_unsubscribe = init_subscriber.Unsubscribe(); | |
} else { | |
status_resubscribe = init_subscriber.Update({"Status" : "Active"}); | |
} | |
} | |
Variable.SetValue("status_unsubscribe", status_unsubscribe); | |
Variable.SetValue("status_resubscribe", status_resubscribe); | |
// Update the subscriber attributes | |
var status_subscriberAttribs = init_subscriber.Update(subscriberData); | |
Variable.SetValue("status_subscriberAttribs", status_subscriberAttribs); | |
// Update the lists | |
var prox = new Script.Util.WSProxy(); | |
var updateLists = { | |
SubscriberKey: subscriberKey, | |
EmailAddress: emailAddress, | |
Lists: listsObj | |
}; | |
var options = { | |
SaveOptions: [{ | |
PropertyName: "*", | |
SaveAction: "UpdateAdd" | |
}] | |
}; | |
var status_publicationList = prox.createItem("Subscriber", updateLists, options); | |
Variable.SetValue("status_publicationList", status_publicationList.Status); | |
Variable.SetValue("formSubmitted", true); | |
} else { | |
Variable.SetValue("formSubmitted", false); | |
} | |
// AMPSCRIPT VARIABLES FOR HTML | |
// Profile Information | |
Variable.SetValue("profileInfo_needed", profileInfo_needed); | |
Variable.SetValue("profileInfo_keys", profileInfo_keys); | |
Variable.SetValue("profileInfo_values", profileInfo_values); | |
// Preferences | |
Variable.SetValue("preferences_needed", preferences_needed); | |
Variable.SetValue("preferences_keys", preferences_keys); | |
Variable.SetValue("preferences_values", preferences_values); | |
// Lists | |
Variable.SetValue("lists_needed", lists_needed); | |
Variable.SetValue("lists_keys", lists_keys); | |
Variable.SetValue("lists_values", lists_values); | |
Variable.SetValue("emailAddress", subscriberObject['Email Address']); | |
Variable.SetValue("subscriberStatus", subscriberObject['Status'] ? '' : 'Checked'); | |
Variable.SetValue("isReadOnly", subscriberObject.Status ? '' : 'readonly'); | |
// Helper Functions | |
function createKeys(valueArr, suffix) { | |
var returnVar = []; | |
for(k=0;k<valueArr.length; k++) { | |
returnVar.push(valueArr[k].split(" ").join("") + (suffix ? "-" + suffix : "")); | |
} | |
return returnVar; | |
} | |
} catch(ex) { | |
Write(Stringify(ex)); | |
} | |
</script> | |
<form method="POST"> | |
<h2>PROFILE CENTER</h2> | |
<h3>My Personal Information</h3> | |
<label for="emailAddress">Email Address *: </label> | |
<input type="email" placeholder="" required name="emailAddress" id="emailAddress" value="%%=v(@emailAddress)=%%" %%=v(@isReadOnly)=%%><br/> | |
%%[FOR @i = 1 TO RowCount(@profileInfo_needed) DO]%% | |
<label for="%%=v(Row(@profileInfo_keys, @i))=%%">%%=v(Row(@profileInfo_needed, @i))=%%: </label> | |
<input type="text" name="%%=v(Row(@profileInfo_keys, @i))=%%" id="%%=v(Row(@profileInfo_keys, @i))=%%" minlength="0" maxlength="25" value="%%=v(Row(@profileInfo_values, @i))=%%" | |
%%=v(@isReadOnly)=%%><br/> | |
%%[NEXT @i]%% | |
<h3>My Preferences</h3> | |
%%[FOR @i = 1 TO RowCount(@preferences_needed) DO]%% | |
<input type="checkbox" name="%%=v(Row(@preferences_keys, @i))=%%" id="%%=v(Row(@preferences_keys, @i))=%%" value="true" %%=v(Row(@preferences_values, @i))=%% %%=v(@isReadOnly)=%%> | |
<label for="%%=v(Row(@preferences_keys, @i))=%%">%%=v(Row(@preferences_needed, @i))=%%</label><br/> | |
%%[NEXT @i]%% | |
<h2>SUBSCRIPTION CENTER</h2> | |
<h3>Available Publications</h3> | |
%%[FOR @i = 1 TO RowCount(@lists_needed) DO]%% | |
<input type="checkbox" name="%%=v(Row(@lists_keys, @i))=%%" id="%%=v(Row(@lists_keys, @i))=%%" value="true" %%=v(Row(@lists_values, @i))=%% %%=v(@isReadOnly)=%%> | |
<label for="%%=v(Row(@lists_keys, @i))=%%">%%=v(Row(@lists_needed, @i))=%%</label><br/> | |
%%[NEXT @i]%% | |
<h2>UNSUBSCRIBE FROM ALL</h2> | |
<p>If you wish to unsubscribe from ALL publications, check the box and click the update button below.<p> | |
<input id="unsubscribe" type="checkbox" name="unsubscribe" value="true" %%=v(@subscriberStatus)=%%> | |
<label for="unsubscribe">I no longer wish to receive any future publications.</label> | |
<br/><br/> | |
<input type="hidden" name="isFormSubmitted" value="true"> | |
<input type="submit" value="Update"> | |
</form> | |
<!-- Scripts --> | |
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/sweetalert2.all.min.js"></script> | |
%%[ IF @formSubmitted AND @status_subscriberAttribs == "OK" AND @status_publicationList == "OK" AND @status_unsubscribe == "NA" AND @status_resubscribe == "NA" THEN ]%% | |
<script> | |
Swal.fire("Updated!", "Your preferences are updated successfully", "success").then(() => { | |
location.href = location.href; | |
}); | |
</script> | |
%%[ ELSEIF @formSubmitted AND (@status_subscriberAttribs != "OK" OR @status_publicationList != "OK") AND @status_unsubscribe == "NA" AND @status_resubscribe == "NA" THEN ]%% | |
<script> | |
Swal.fire("Not Updated!", "Something went wrong while updating your preferences", "error").then(() => { | |
location.href = location.href; | |
}); | |
</script> | |
%%[ ELSEIF @formSubmitted AND @status_unsubscribe == "OK" AND @status_resubscribe == "NA" THEN ]%% | |
<script> | |
Swal.fire("Unsubscribed!", "Sorry to see you go away!", "info").then(() => { | |
location.href = location.href; | |
}); | |
</script> | |
%%[ ELSEIF @formSubmitted AND @status_unsubscribe == "NA" AND @status_resubscribe == "OK" THEN ]%% | |
<script> | |
Swal.fire("Subscribed!", "Happy to see you again!", "success").then(() => { | |
location.href = location.href; | |
}); | |
</script> | |
%%[ ELSE ]%% | |
%%[ ENDIF ]%% | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment