Welcome to the ACC JS SDK. This post introduces a series of posts around Campaign API and the SDK.
Here are a couple of ideas about how you can use the SDK
Start with the concepts behind Campaign and the SDK.
Here's an advanced example which illustrates how to create a REST API for Campaign using the SDK. This code is expected to run inside an express server, or even inside a lambda function.
See the advanced topic of Dynamic Invocation to understand how SOAP calls can be dynamically constructed from HTTP requests
const sdk = require('@adobe/acc-js-sdk'); // ... perform authentication and get connection parameters here const client = await sdk.init(connectionParameters); // It is useful to log the IP address of the server where the SDK // runs so that it can be whitelisted in the Campaign configuration const ip = await sdk.ip(); console.log(`Outbound IP address is '${JSON.stringify(ip)}'`); // Log on to Campaign await client.logon(); // Decode path which must be <namespace>/<schema-id>/<method>. // Here we consider we're running inside an Adobe Runtime function // which exposes the URL path as <args.__ow_path> var path = args.__ow_path; if (path[0] == '/') path = path.substring(1); const pathElements = path.split("/"); // Support for /ping endpoint if (pathElements.length >= 1 && pathElements[0] === "ping") { return sdk.getSDKVersion(); } const namespace = pathElements[0].trim(); const schemaId = pathElements[1].trim(); const methodName = pathElements[2].trim(); // The scopeName is the name of the property of the NLWS object which corresponds // to the schema being called. For instance xtk:session => NLWS.xtkSession const scopeName = `${namespace}${schemaId[0].toUpperCase()}${schemaId.substring(1)}`; const scope = NLWS[scopeName]; const method = scope[methodName]; // Dynamically call SOAP method console.log(`About to call method '${methodName}' of scope '${scopeName}'`); // Call the method with a hook to decode parameters. The hook will extract the method // parameters values from the action arguments and pass them as an array, as expected // by the SDK. It will also set the "this" object for non static methods and fill the // "outName" array will be filled with the names of the output parameters of the method const outNames = []; const result = await method.call(scope, (method, callContext) => { // Non-static methods require a "this" parameter. This parameter can be passed as // a "this" property of the action parameters, or, if this propery is not set, as // the action parameters directly (this is just to simplify the REST API callls by // allowing to omit the "this" property if the call is non-static with no arguments) const isStatic = DomUtil.getAttributeAsBoolean(method, "static"); if (!isStatic) { const object = args["this"] || args; callContext.object = object; } // Compute parameters array by extracting each parameter by name // from the action arguments const parameters = []; const params = DomUtil.getFirstChildElement(method, "parameters"); if (params) { var param = DomUtil.getFirstChildElement(params, "param"); while (param) { const inout = DomUtil.getAttributeAsString(param, "inout"); const paramName = DomUtil.getAttributeAsString(param, "name"); if (!inout || inout=="in") { parameters.push(args[paramName]); } else { outNames.push(paramName); } param = DomUtil.getNextSiblingElement(param, "param"); } } return parameters; }); // Process result. Again this is to simplify the API and return a valid JSON var returnedValue = {}; if (outNames.length == 0) { returnedValue = undefined; } // If the API returns one parameter which is an object, the return it directly. // If not (return value is a literal), then use a JSON with the return parameter name else if (outNames.length == 1) { if (result && typeof result == "object") returnedValue = result; else returnedValue[outNames[0]] = result; } // If the API returns multiple values, then build a JSON which each return value else { for (var i=0; i<outNames.length; i++) { const name = outNames[i]; returnedValue[name] = result[i]; } } return returnedValue;