0

I am not an expert in SSJS. But after going through various posts I come up with the below code. I trying to create code in which I am reading data from DE and adding subscribers into Publication List.

Below SSJS code is running successfully but no record is adding. Any help here on fix?

<script runat="server">    
    Platform.Load("core","1.1.1");
    
    var data = DataExtension.Init("publist");

    var prox = new Script.Util.WSProxy();

if(data){ 
          for (var i = 0; i < data.length; i++){ 

    var sub = {
        EmailAddress: data[i]["EmailAddress"],
        SubscriberKey: data[i]["SubscriberKey"],
        Lists: [{
            ID: '2146',
            Status: 'Active'
        }]
    };
    var options = { 
        SaveOptions: [{
          PropertyName: "*",
          SaveAction: "UpdateAdd"
        }]
    };

    var resp = prox.createItem("Subscriber", sub, options);
    
    Write("Response: " + Stringify(resp));
}
}

</script>
  • Any help??????? – Sohail Sep 24 at 1:21
  • Is there a reason why you're using WSProxy (counts towards API quota) as opposed to Core functions that don't? – Macca Sep 24 at 4:18
3

You're not retrieving any rows from the Data Extension you've initialized, so there's nothing to loop around. See the top of the SSJS Core code below for an example of getting "data" from your Data Extension that you could iterate through.

If this is part of something you're doing regularly, although you can do this with WSProxy, I'd recommend using Core SSJS functions to do this. Although Salesforce doesn't monitor API usage actively, there's no reason to assume that they won't see this as an area that could be monetized in the future.

To do what you're attempting to do with WSProxy using standard Core functions, you could do something similar to this:

<script runat="server">    
    Platform.Load("core","1");
    
    var de = DataExtension.Init("publist");
    var data = de.Rows.Retrieve();

    if(data){ 
          for (var i = 0; i < data.length; i++){ 
              var sub = {
                  "EmailAddress": data[i]["EmailAddress"],
                  "SubscriberKey": data[i]["SubscriberKey"],
                  "Lists": [{
                      "Status": "Active",
                      "ID": 2146,
                      "Action": "Upsert"
                  }]
              };

              var subObj = Subscriber.Init(sub.SubscriberKey);
              var status = subObj.Upsert(sub);
          } //data.length
    } //if(data)
</script>

If you're dealing with a very large number of records (more than a few), SSJS just isn't the way to do this at all. It won't scale to any reasonable volume, even with WSProxy's ability to page through batches of 2.5K records (not implemented in your example). The way to go is SQL and Automation Studio:

  1. Create a new scheduled Automation

  2. Create a Data Extension to hold the results of the query below

  3. Create a Query Activity with similar code to get the records from your Data Extension:

     SELECT
         SubscriberKey AS [Subscriber Key],
         EmailAddress AS [Email Address],
         'Active' AS [Status]
     FROM
         publistDE
    
  4. Create a Data Extension Extract Activity to export the contents of your results DE

  5. Create a File Transfer Activity to move the extracted data to the Enhanced FTP

  6. Create an Import File Activity to import the file in the Enhanced FTP to your Publication List

  7. Save and Run Once the Automation

| improve this answer | |
  • Pretty good answer @Macca. I just wan to add that WSProxy works fine in Script Activity up to around 100k records. If processing time is not an issue you could also implement something like this: gortonington.com/setting-a-time-limit-inside-ssjs-activity – shd.lux Sep 24 at 8:42
  • Thank you Macca. I am using SSJS because the number of records are less than 100 and top of that I have 10 different publication lists, where I need to upsert the subscribers. So using file drop method will require lot of work (as I have to manually create 30 activities, each list 3 activities) and as we don't have many records so I feel SSJS should be simple and quick way to do it. – Sohail Sep 24 at 11:50
  • Fair enough, @Sohail. I realise you're going to distill down your problem... That's good and really helpful. The answer's going to attempt at being generic. I hope you're on your way? – Macca Sep 24 at 14:33
  • @shd.lux Gortonington was talking about how to avoid timeout errors and make SSJS "more scalable". He was trying to address its weaknesses. It's a good article, but if you ask him, "SSJS or SQL?", it's a daft one! You can process 15K records with each script instance in 15 mins, but do 45m in 5 mins with SQL. Just ponder. – Macca Sep 24 at 14:51
  • @Macca - agree that SQL is a better approach on large data sets. However, there are cases where TSQL is not able to handle certain scenarios but SSJS would. time is a real concern but if time is not of an essence than SSJS is still a good option :) – shd.lux Sep 24 at 22:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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