How to use server-side JavaScript to work with Lists in Salesforce Marketing Cloud

How to use server-side JavaScript to work with Lists in Salesforce Marketing Cloud

This article explains how to use WSProxy for working with subscriber Lists in server-side JavaScript in Salesforce Marketing Cloud.

Table of contents

Lists, what are they?

Lists are the default method of storing subscriber’s data in the Email Studio.

In short, it’s a convenient out-of-the-box solution for the audience segmentation with a rather simple data model and a limited Subscriber count (500k).

There are 2 types of Email Studio lists: Publication list and Suppression list.

Publication lists control which emails your subscribers receive and the Suppression lists prevent your subscribers from receiving specific communications.

But there is also a third type of list that can be found in the Email Studio Admin panel: Auto-suppression list.

In a nutshell, they are similar to the regular Suppressions lists but work across an entire Marketing Cloud business unit for specific send classifications.

Now, let’s see how work with these different types of lists, using WSProxy in server-side JavaScript.

Before we start

Please consider that the examples of code presented in the next sections will need to be implemented in the following basic template:

<script runat="server">
	
    Platform.Load("core", "1");
	
    var api = new Script.Util.WSProxy();
	
	try {
	
		/////////////////////////////////////////////////
        ///// PASTE CODE HERE
        /////////////////////////////////////////////////

		Write(Stringify(res));
		
	} catch(error) {
		Write(Stringify(error));
	}
	
</script>

Basics


Create a List

Creating a new List is nice and easy when using WSProxy with the List API object.

var res = api.createItem("List", {
    ListName: "My NewList",
    Type: "Public",
    ListClassification: "PublicationList",
    Description: "Hello world"
});

Please note that the name attribute of the List is called ListName instead of the usual Name.

Type and ListClassification attributes each have a valid set of values:

Type attribute can only be equal to:

  • Public
  • Private
  • Salesforce
  • GlobalUnsubscribe
  • Master

As for the ListClassification attribute, it accepts exclusively the following values:

  • ExactTargetList
  • PublicationList
  • SuppressionList

Delete a List

Deleting a list is a matter of providing the List ID, which can be found in Email Studio UI, but the column is hidden by default, so please activate it.

var res = api.deleteItem("List", {
    ID: "12345"
});

Retrieve a List

In order to retrieve a List, we need to use the complex filters.

var res = api.retrieve("ListSubscriber", 
    ["SubscriberKey", "ListID", "Status"],
    {
        Property: "SubscriberKey",
        SimpleOperator: "equals",
        Value: "0x000000012345"
    }
);

Folders


Retrieve the folder

In the example below, we first need to fetch the Category ID of the List (called Category, instead of the usual CategoryId) and then use it to retrieve the name of the folder where the List is located.

var req = api.retrieve("List", ["ListName", "Category", "ID"], {
    Property: "ID",
    SimpleOperator: "equals",
    Value: "12345"
});

var catId = req.Results[0].Category;

var req = api.retrieve("DataFolder", ["Name"], {
    Property: "ID",
    SimpleOperator: "equals",
    Value: catId
});

var res = req.Results[0].Name;

Retrieve the folder path

Same here, but in order to retrieve the full path, we need to fetch the ID of the Parent Folder and then loop the process until the Parent Folder ID is equal to 0 (root level folder).

var req = api.retrieve("List", ["ListName", "Category", "ID"], {
    Property: "ID",
    SimpleOperator: "equals",
    Value: "12345"
});

var list = [req.Results[0].ListName];
var id = req.Results[0].Category;

while(id > 0) {

    var req = api.retrieve("DataFolder", ["Name","ParentFolder.ID"], { 
        Property: "ID", 
        SimpleOperator: "equals", 
        Value: id 
    });

    list.unshift(req.Results[0].Name);
    id = req.Results[0].ParentFolder.ID;
}

var res = list.join(" / ");

Managing subscribers


Add a subscriber to a List

The method of adding a new subscriber is a matter of updating or adding a new Subscriber API object and providing one or multiple List IDs to which the subscriber needs to be added.

/*
Statuses: Active, Bounced, Held, Unsubscribed, Deleted
*/

var res = api.updateItem("Subscriber", {
    SubscriberKey: "0x000000012345",
    EmailAddress: "jon.snow@crowmail.com",
    Status: "Active",
    EmailTypePreference: "HTML",
    Attributes: [
        {
            Name: "FirstName",
            Value: "Jon"
        },
        {
            Name: "LastName",
            Value: "Snow"
        }
    ],
    Lists: [
        {
            ID: "12345"
        }
    ]
}, 
{
    SaveOptions: [
        {
            PropertyName: '*',
            SaveAction: 'UpdateAdd'
        }
    ]
});

Note that each of the specific subscriber’s attribute needs to be provided as a separate object with a Name/Value pair.

Status and EmailTypePreference attributes each have a list of valid values.

Status only accepts the following values:

  • Active
  • Bounced
  • Held
  • Unsubscribed
  • Deleted

EmailTypePreference on the other hand can only accept:

  • HTML
  • Text

Change subscriber’s status in a List

Changing the status of the subscriber is done in the same manner.

/*
Statuses: Active, Bounced, Held, Unsubscribed, Deleted
*/

var res = api.updateItem("Subscriber", {
    SubscriberKey: "0x000000012345",
    EmailAddress: "jon.snow@crowmail.com",
    Status: "Unsubscribed",
    Lists: [
        {
            ID: "12345"
        }
    ]
}, 
{
    SaveOptions: [
        {
            PropertyName: '*',
            SaveAction: 'UpdateAdd'
        }
    ]
});

Retrieve all subscribers from a List

Retrieving all the subscribers from a List if a matter of querying the ListSubscriber object.

var res = api.retrieve("ListSubscriber", 
    [
        "ObjectID", 
        "SubscriberKey", 
        "CreatedDate",
        "ModifiedDate",
        "Client.ID",
        "Client.PartnerClientKey",
        "ListID",
        "Status"
    ],
    {
        Property: "ListID",
        SimpleOperator: "equals",
        Value: "12345"
    }
);

Remove a subscriber from a Suppression List

For some reason, the List ID of a Suppression List cannot be found in the Email Studio UI. We therefore need to retrieve the List ID based on the name of the List and only then update the Subscriber object’s Lists array.

var req = api.retrieve("List", 
    ["ListName", "ID"],
    {
        Property: "ListName",
        SimpleOperator: "equals",
        Value: "My New Suppression List"
    }
);

var listId = req.Results[0].ID;

var res = api.updateItem("Subscriber", {
    SubscriberKey: "0x000000012345",
    EmailAddress: "jon.snow@crowmail.com",
    Lists: [
        {
            ID: listId,
            Action: "delete"
        }
    ]
});

Note that removing a subscriber from a regular or Publication List is not possible with code. The subscriber remains in the List with the status Unsubscribed.

Interacting with Auto-Suppression Lists


Create an Auto-Suppression List for a Send Classification

In order to create a proper Auto-Suppression List, we need to provide the Client ID in the Contexts array attribute, which is a fancy name for a Business Unit number (or mid).

var res = api.createItem("SuppressionListDefinition", {
    Name: "My New Sup List Def",
    Category: 0,
    Description: "Hello world",
    Contexts: [
        {
            Client: {
                ID: Platform.Recipient.GetAttributeValue("memberid")
            },
            Context: "BusinessUnit",
            SendClassificationType: "Marketing",
            AppliesToAllSends: false
        }
    ]
});

Create an Auto-Suppression List for a Sender Profile

Same here, but we also need to provide the ObjectID of the Sender Profile we count on using.

var req = api.retrieve("SenderProfile", ["Name", "ObjectID"], {
    Property: "CustomerKey",
    SimpleOperator: "equals",
    Value: "1134"
});

var objId = req.Results[0].ObjectID;

var res = api.createItem("SuppressionListDefinition", {
    Name: "My New Sup List Def 2",
    Category: 0,
    Description: "Hello world",
    Contexts: [
        {
            Client: {
                ID: Platform.Recipient.GetAttributeValue("memberid")
            },
            Context: "SenderProfile",
            SenderProfile: {
                ObjectID: objId
            },
            AppliesToAllSends: false
        }
    ]
});

Add a subscriber to an Auto-Suppression List

Adding a new subscriber is done differently for an Auto-Suppression List. The method is the same as adding a new record in a Data Extension.

var req = api.retrieve("SuppressionListDefinition", 
    [
        "ObjectID",
        "CustomerKey",
        "Name",
        "Description",
        "Client.CreatedBy",
        "CreatedDate",
        "Client.ModifiedBy",
        "ModifiedDate",
        "Category",
        "Client.ID",
        "Client.EnterpriseID",
        "SubscriberCount"
    ],
    {
        Property: "Name",
        SimpleOperator: "equals",
        Value: "My New Sup List Def "
    }
);

var customerKey = req.Results[0].CustomerKey;

var res = api.updateItem("DataExtensionObject", {
    CustomerKey: customerKey,
    Properties: [
        {
            Name: "Email Address",
            Value: "jon.snow@crowmail.com"
        }
    ]
}, 
{
    SaveOptions: [
        {
            PropertyName: '*',
            SaveAction: 'UpdateAdd'
        }
    ]
});

Retrieve all Auto-Suppression Lists

An Auto-Suppression List is basically a SuppressionListDefinition object and has the same structure as a regular Data Extension, except for the SubscriberCount attribute.

var res = api.retrieve("SuppressionListDefinition", 
    [
        "ObjectID",
        "CustomerKey",
        "Name",
        "Description",
        "Client.CreatedBy",
        "CreatedDate",
        "Client.ModifiedBy",
        "ModifiedDate",
        "Category",
        "Client.ID",
        "Client.EnterpriseID",
        "SubscriberCount"
    ]
);

Retrieve Contexts for an Auto-Suppression List

The SuppressionListContext object defines a context that an Auto-Suppression List can be associated with.

var res = api.retrieve("SuppressionListContext", 
    [
        "ObjectID",
        "Definition.ObjectID",
        "Definition.Name",
        "Definition.CustomerKey",
        "Definition.Category",
        "Definition.Description",
        "Context",
        "SendClassification.ObjectID",
        "Send.ID",
        "SenderProfile.ObjectID",
        "SendClassificationType",
        "Client.CreatedBy",
        "CreatedDate",
        "Client.ModifiedBy",
        "ModifiedDate",
        "Client.ID",
        "Client.EnterpriseID",
        "AppliesToAllSends"
    ]
);

Conclusion

Lists are far from a perfect system but knowing how to manage them with code can be a powerful tool in our Marketing Cloud projects.

Have I missed anything?

Please poke me with a sharp comment below or use the contact form.

  1. Hi, Ivan, first of all, congratulations on the content,
    I would like to know if it’s possible to move data from a data extension to a suppression list using SSJS?

    Thanks you very much

  2. Hi, Ivan, I would like to know how could I move data from a list to a Data Extension using SSJS, it’s possible? Thanks Ivan

  3. Sure, why not. Just keep in mind that you are going to be able to process around 100-150k records at a time, since Script Activities have a 30 min time-out period.

  4. Hi Ivan, can I retrieve more than just 2500 subscribers from a list? When I see my recovered subscribers on the web page, it appears for me
    “HasMoreRows”:true, how can I retrieve all subscribers at once? Thanks in advance

  5. Alright! I’m trying to recover a list so when you say here,
    ” if (reqID == null) {
    data = prox.retrieve(“DataExtensionObject[” + config.name + “]”, config.cols, config.filter);
    } else {
    data = prox.getNextBatch(“DataExtensionObject[” + config.name + “]”, reqID);
    }”

    In the place of “DataExtensionObject[” what should I put?

  6. You can read it above in this article under the title « Retrieve a List ».

  7. If you still can’t put 2 and 2 together, don’t try to make it work without having a proper JavaScript training. If you don’t know the basics, you’ll have a really hard time understanding any of this.

Leave a Reply

Your email address will not be published.

server-side Javascript
Up Next:

How to loop through the REST API GET requests in server-side JavaScript

How to loop through the REST API GET requests in server-side JavaScript