WS-Proxy via SSJS: Documentation
Introduction:
Server-Side JavaScript (SSJS) is a powerful technology that allows developers to execute JavaScript code on the server-side, enabling them to build dynamic and scalable applications. The WSProxy object is native to the platform and simpler to use than the SSJS methods. The object reduces overhead and increases speed of your API calls. The object’s usage syntax is much more JavaScript-like when compared to the existing platform functions.In this blog post, we will explore how to leverage WS-Proxy, a Salesforce feature, to work with SOAP APIs using SSJS. We'll dive into the details of WS-Proxy and demonstrate how it can simplify and streamline SOAP API integrations.
Quote
"The legacy methods for accessing SOAP object data, including what is used in the SSJS Core Library, are primarily wrappers around AMPScript functions. Using legacy SSJS methods adds overhead to the processing of the calls as the code translates the data between the different language runtimes."
Unquote
What is WS-Proxy?
WS-Proxy is a server-side JavaScript utility provided by Salesforce that acts as a proxy for making SOAP API calls. It abstracts the complexity of SOAP requests and responses, providing a simplified interface for developers to interact with SOAP APIs. WS-Proxy is built on top of the AJAX toolkit, making it compatible with JavaScript Remoting, JavaScript buttons, and other client-side and server-side JavaScript contexts.
Benefits of WS-Proxy:
- Simplified Integration: WS-Proxy simplifies the integration process by abstracting the complexities of SOAP API calls. Developers don't need to worry about constructing SOAP envelopes, handling SOAP headers, or parsing SOAP responses. WS-Proxy takes care of these details, allowing developers to focus on the business logic.
- Security and Compliance: WS-Proxy ensures that the SOAP API calls are made securely, handling authentication and encryption behind the scenes. It adheres to Salesforce's security policies and ensures compliance with the organization's security settings.
- Performance Optimization: WS-Proxy optimizes the SOAP API calls by reducing the network overhead. It batches multiple API requests into a single network call, reducing latency and improving overall performance. This feature is particularly useful when working with bulk operations or when making multiple API calls in a single transaction.
Using WS-Proxy with SOAP API:
Let's dive into the practical implementation of WS-Proxy with a SOAP API integration. In this example, we'll demonstrate how to retrieve information from an external system using a SOAP API.
Step 1: Enabling WS-Proxy
To use WS-Proxy, you need to enable the "Allow server-side scripting for the service" option.
<script runat="server">
</script>
Step 2: Creating a WS-Proxy Script
Write a server-side JavaScript function that utilizes the WSProxy object provided by Salesforce. This object acts as a proxy for making SOAP API calls.
var api = new Script.Util.WSProxy();
Step 3: Making SOAP API Calls
In Salesforce Marketing Cloud, the ws-proxy
or Web Services Proxy is a JavaScript library
that allows you to invoke SOAP (Simple Object Access Protocol) web service methods, such as
CreateItem
and CreateBatch
, from the client-side (browser) within the
context of a Marketing Cloud CloudPage or other custom applications.
Step 4: Processing the Response
Once the SOAP response is received, you can process the data as needed. WS-Proxy handles the parsing of SOAP envelopes, making it easy to extract the relevant information from the response.
For example, the response contain three properties from the SOAP CreateResult object: “Status”, “RequestID”, and “Results”.
{
"Status": "OK",
"RequestID": "fb768ddc-6670-4183-8b9d-4f0d5518bb2e",
"Results": [...]
}
Impersonation with WSProxy:
WSProxy introduces impersonation capabilities that allow developers to execute API requests on behalf of other users. This is accomplished by specifying the impersonated user's credentials within the WSProxy configuration. When a request is made using impersonation, the server treats the request as if it were made by the impersonated user, inheriting their privileges and access rights.
To impersonate another user, or switch contexts, use the setClientId method on the WSProxy object.You can add multiple credentials to a single WSProxy, but most actions use only the first one set as they accept only a single ClientId object.
api.setClientId({ "ID": 1234, "UserID": 1234 });
OR
api.setClientId({ "ID": 1234 });
OR
api.setClientId({ "ID": Platform.Function.AuthenticatedMemberID() });
OR
api.setClientId({ "UserID": 1234 });
You can retrieve User ID from AccountUser
object as ID
property.
var accountUser = AccountUser.Retrieve({Property:"CustomerKey",SimpleOperator:"equals",Value:"MyAccount"});
Impersonation only works with Top Down Approach, validate your Business Unit hierarchy when you are switching context between different operations.
To clear all set ClientId objects, use the resetClientIds() method. After using this method, the request goes back to using the default credentials determined by the execution context.
api.resetClientIds();
Methods:
Create via WSProxy
- createItem
- createBatch
var res = api.createItem(soapObject,jsonObject,prop);
var res = api.createBatch(soapObject,jsonArray,prop);
- For the first parameter, both functions take the object type to perform the action on. For example, Email or DataExtension.
- The second parameter is a JS object which represents the fields and values to set on the object when created. For batch operations, the second parameter is passed in as an Array of objects instead of a single item.
- The third parameter is optional and includes any properties to be set using the SOAP CreateOptions object.
Update via WSProxy
- updateItem
- updateBatch
var res = api.updateItem(soapObject,jsonObject,prop);
var res = api.updateBatch(soapObject,jsonArray,prop);
- For the first parameter, both functions take the object type to perform the action on. For example, Email or DataExtension.
- The second parameter is a JS object which represents the fields and values to set on the object when created. For batch operations, the second parameter is passed in as an Array of objects instead of a single item.
- The optional third parameter includes any properties to be set using the SOAP UpdateOptions object.
Delete via WSProxy
- deleteItem
- deleteBatch
var res = api.deleteItem(soapObject,jsonObject,prop);
var res = api.deleteBatch(soapObject,jsonArray,prop);
- For the first parameter, both functions take the object type to perform the action on. For example, Email or DataExtension.
- The second parameter is a JS object which represents the fields and values to set on the object when created. For batch operations, the second parameter is passed in as an Array of objects instead of a single item.
- The optional third parameter includes any properties to be set using the SOAP DeleteOptions object.
Describe via WSProxy
To return information on the structure of SOAP API objects, use the describe call. The function takes either a string representing the object type to describe, or an array of strings for multiple object types.
Example :
<script runat="server">
Platform.Load("core", "1");
try {
var soapObjects=[
"Account"
,"AccountUser"
,"Authentication"
,"Automation"
,"BounceEvent"
,"BusinessUnit"
,"ClickEvent"
,"ContentArea"
,"DataExtension"
,"DataFolder"
,"Email"
,"Send"
,"SendClassification"
]
var response=DescribeSoapObject(soapObjects[12]);
Write(Stringify(response));
}
catch (ex) {
Write(ex.message + '\n');
Write(ex.description + '\n');
Write(ex.jintException + '\n');
}
function DescribeSoapObject(soapObjectname)
{
var api = new Script.Util.WSProxy();
var response = api.describe(soapObjectname);
return response;
}
</script>
Basic Retrieves via WSProxy
The WSProxy() object offers several retrieve options, depending on the level of complexity you need. The simplest option takes the type of object as the first parameter, and an array of object property names to retrieve.
Example :
<script runat="server">
Platform.Load("core", "1");
try {
var soapObjects=[
"Account"
,"AccountUser"
,"Authentication"
,"Automation"
,"BounceEvent"
,"BusinessUnit"
,"ClickEvent"
,"ContentArea"
,"DataExtension"
,"DataFolder"
,"Email"
,"Send"
,"SendClassification"
]
var cols = [ "Name", "CustomerKey"];
var response=RetrieveSoapObject(soapObjects[0],cols);
Write(Stringify(response));
}
catch (ex) {
Write(ex.message + '\n');
Write(ex.description + '\n');
Write(ex.jintException + '\n');
}
function RetrieveSoapObject(soapObjectname,cols )
{
var api = new Script.Util.WSProxy();
var response = api.retrieve(soapObjectname,cols);
return response;
}
</script>
Example : Retrieve with Filter
<script runat="server">
Platform.Load("core", "1");
try {
var soapObjects=[
"Account"
,"AccountUser"
,"Authentication"
,"Automation"
,"BounceEvent"
,"BusinessUnit"
,"ClickEvent"
,"ContentArea"
,"DataExtension"
,"DataFolder"
,"Email"
,"Send"
,"SendClassification"
]
var cols = [ "Name", "CustomerKey"];
var filter=ApplyFilter("CustomerKey","equals","Shashi")
var response=RetrieveSoapObject(soapObjects[0],cols,filter);
Write(Stringify(response));
}
catch (ex) {
Write(ex.message + '\n');
Write(ex.description + '\n');
Write(ex.jintException + '\n');
}
function RetrieveSoapObject(soapObjectname,cols,filter)
{
var api = new Script.Util.WSProxy();
var response = api.retrieve(soapObjectname,cols,filter);
return response;
}
function ApplyFilter(prop,operator,value)
{
return {
Property: prop,
SimpleOperator: operator,
Value: value
};
}
</script>
Example : Retrieve with Complex Filter
<script runat="server">
Platform.Load("core", "1");
try {
var soapObjects=[
"Account"
,"AccountUser"
,"Authentication"
,"Automation"
,"BounceEvent"
,"BusinessUnit"
,"ClickEvent"
,"ContentArea"
,"DataExtension"
,"DataFolder"
,"Email"
,"Send"
,"SendClassification"
]
var cols = [ "Name", "CustomerKey"];
var leftOperand=ApplyFilter("CustomerKey","equals","Shashi");
var rightOperand=ApplyFilter("Name","equals","Shashi");
var filter=ComplexFilter(leftOperand,"OR",rightOperand)
var response=RetrieveSoapObject(soapObjects[0],cols,filter);
Write(Stringify(response));
}
catch (ex) {
Write(ex.message + '\n');
Write(ex.description + '\n');
Write(ex.jintException + '\n');
}
function RetrieveSoapObject(soapObjectname,cols,filter)
{
var api = new Script.Util.WSProxy();
var response = api.retrieve(soapObjectname,cols,filter);
return response;
}
function ApplyFilter(prop,operator,value)
{
return {
Property: prop,
SimpleOperator: operator,
Value: value
};
}
function ComplexFilter(leftOperand,logicalOperator,rightOperand)
{
return {
LeftOperand: leftOperand,
LogicalOperator:logicalOperator,
RightOperand: rightOperand
};
}
</script>
Example : Retrieve Data Extension from all Business Unit
This example uses a parameter called queryAllAccounts to retrieve data extension from all BUs, where
CustomerKey
OR Name
is "Shashi"
<script runat="server">
Platform.Load("core", "1");
try {
var soapObjects=[
"Account"
,"AccountUser"
,"Authentication"
,"Automation"
,"BounceEvent"
,"BusinessUnit"
,"ClickEvent"
,"ContentArea"
,"DataExtension"
,"DataFolder"
,"Email"
,"Send"
,"SendClassification"
]
var cols = [ "Name", "CustomerKey"];
var leftOperand=ApplyFilter("CustomerKey","equals","Shashi");
var rightOperand=ApplyFilter("Name","equals","Shashi");
var filter=ComplexFilter(leftOperand,"OR",rightOperand);
var queryAllAccounts = true;
var response=RetrieveSoapObject(soapObjects[8],cols,filter,queryAllAccounts);
Write(Stringify(response));
}
catch (ex) {
Write(ex.message + '\n');
Write(ex.description + '\n');
Write(ex.jintException + '\n');
}
function RetrieveSoapObject(soapObjectname,cols,filter,queryAllAccounts)
{
var api = new Script.Util.WSProxy();
var response = api.retrieve(soapObjectname,cols,filter,queryAllAccounts);
return response;
}
function ApplyFilter(prop,operator,value)
{
return {
Property: prop,
SimpleOperator: operator,
Value: value
};
}
function ComplexFilter(leftOperand,logicalOperator,rightOperand)
{
return {
LeftOperand: leftOperand,
LogicalOperator:logicalOperator,
RightOperand: rightOperand
};
}
</script>
Conclusion:
WS-Proxy provides an efficient and streamlined way to work with SOAP APIs using Server-Side JavaScript. By abstracting the complexities of SOAP requests and responses, developers can focus on building robust integrations without worrying about low-level SOAP details. The simplicity, security, and performance optimizations offered by WS-Proxy make it an excellent choice for integrating Salesforce with external systems using SOAP APIs. So, the next time you need to work with SOAP APIs in your Server-Side JavaScript applications, consider leveraging the power of WS-Proxy to simplify your integration process.
Comments
Post a Comment