Skip to content

Instantly share code, notes, and snippets.

@VijayaSankarN
Last active March 13, 2023 12:22
Show Gist options
  • Save VijayaSankarN/e34fcf2c13199971abad7082cb140377 to your computer and use it in GitHub Desktop.
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/
<!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/sweetalert2@10.3.5/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