I just want to create a replica of my data extension on a web page where my team can see the status of each subscriber. I've tried achieving this from this documentation but it's just pulling only one column.
-
2Depending how many subscribers you have this might be a completely bad idea. If you pull 1 Million Subscriber into a Page which is assessible to the public it is not a good idea (even though nobody would visit this page because search robots won't search for it). And... this page would be very very long and very laggy.– Johannes SchapdickCommented Aug 2, 2019 at 6:25
-
@mdabdulateeq can you paste your code here, co we can have a look?– zuzannamjCommented Aug 2, 2019 at 6:57
-
@JohannesSchapdick, it's not a million of records just for a few like 600 records where we are capturing the responses through an SMS so that the business can see their responses easily without getting into Marketing Cloud. Also, it's just for internal use without PII data.– Mo AteeqCommented Aug 13, 2019 at 5:22
1 Answer
Agreed with the comment from Johannes Schapdick above: Apply this with extreme caution. This is NOT a performant solution, it will lag or time out with bigger amounts of data. Also, a public page that exposes your PII like emails might not be a good idea either. Logins are there for a reason.
Still, sometimes this approach can help and serve as a starting point.
The following concepts are applied: Build a Retrieve using a filter that applies to all records. This only works if you can filter for a field that all records have in common:
So, build a field like field "include" with a defaultValue of 1 in the DE. This common "hack" enables you to retrieve "all records", with the following limitation:
You have to loop the retrieves as one iteration only gives you 2500 records, which you can circumvent using ContinueRequest / moredataavailable.
I am sure this works with leaner code (WSProxy) as well, but this "old school" code has served me well:
<script type="javascript" runat="server">
Platform.Load("Core", "1")
// get records from Data Extensions
var dataExtensionName = "myDE";
var fieldToReturn = "Email";
// a) you can add more variable + fields here
var rr = Platform.Function.CreateObject("RetrieveRequest");
Platform.Function.SetObjectProperty(rr, "ObjectType", "DataExtensionObject[" + dataExtensionName + "]");
Platform.Function.AddObjectArrayItem(rr, "Properties", fieldToReturn);
// copy the line above, changing the variable to the one defined at a)
/* filter condition */
var sfp1 = Platform.Function.CreateObject("SimpleFilterPart");
Platform.Function.SetObjectProperty(sfp1, "Property", "include");
Platform.Function.SetObjectProperty(sfp1, "SimpleOperator", "equals");
Platform.Function.AddObjectArrayItem(sfp1, "Value", "1");
/* assign filter to retrieverequest*/
Platform.Function.SetObjectProperty(rr, "Filter", sfp1);
var statusAndRequestId = [0, 0];
var status = statusAndRequestId[0];
var requestID = statusAndRequestId[1];
var numberOfRowsInDE = 0;
var allEmails = [];
// c) build a second array, or change to an object for more fields
/* perform retrieves until no more data is left (= do not stop at 2500 records )*/
do {
var results = [0,0];
var rows = Platform.Function.InvokeRetrieve(rr, results);
var runstatus = results[0];
var requestId = results[1];
if (rows != null) {
for (var i in rows) {
var rEmail = rows[i].Properties[0].Value;
/*d) more fields can go here by building another variable and
increasing Properties[0] to 1, 2 etc.
allEmails.push(rEmail);
// e)
}
}
rr.ContinueRequest = requestId;
numberOfRowsInDE = numberOfRowsInDE + rows;
} while (runstatus == "MoreDataAvailable")
/* end of retrieve. now you should have an array "allEmails", and the variable
"numberOfRowsInDE" holds the number of rows retrieved. */
/* write each email */
for (var i = 0; i < numberOfRowsInDE; i++) {
Write("Email: " + allEmails[i]);
}
</script>
Hope this helps.
-
I believe this works(not tested) but i am uncertain, if we should provide such solutions/answers when we know the use case is dangerous and can lead to problems regarding security and legislation. I wouldn't have posted the answer and instead would have tried to ask, if it really has to be a cloudpage. Maybe the persons that are demanding this website would also be satisfied when they become a daily update in form of a file (like csv, xlsx, txt or something) Commented Aug 2, 2019 at 9:41
-
I see your point, but since the question title is generic, I think a general answer is fine, with the disclaimer. Even a lookup can be dangerous to use on a cloudpage. It depends on the context. If you expose PII on a cloudpage, include authentication. Then you can make use of this code. For non-PII i see no issues except latency in high load scenarios. I found this quite a valuable code snippet to use in a variety of usecases. This code is actually coming from and working in a script activity (except "write"). Happy to remove the code, but the danger is in the context, not the code? Commented Aug 2, 2019 at 11:01
-
Yeah the danger is in the context not the code.But if beginner searches for this he/she might just execute the code and is not aware of it.Imagine someone that hosts this page and people refresh this page over and over again.It creates much (senseless) traffic. If people need to see subscriber data, they could better login into the marketing cloud and access the subscriber table rather than creating a cloudpage for it (cut/limit the rights of those people). There are a lot of options you should include in your answer to not cover a solution without risks. But the answer is ok. Commented Aug 2, 2019 at 11:11
-
I agree with your concerns guys but this is going to be a secure page protected with a password and for internal use only.– Mo AteeqCommented Aug 13, 2019 at 5:25
-
CloudPages do not work this way, they can hardly be protected in a secure manner (atleast that i know of). And if this is a site which is not hosted in SFMC you cannot use the answer that is presented here but need to switch to API calls (Rest / Soap) Commented Aug 13, 2019 at 5:37