InvokeConfigure
→ stringInvokes the SOAP API Configure method on a fully configured API object. Used for configuration-type operations on SOAP objects.
Syntax
Platform.Function.InvokeConfigure(apiObject, action, status, options)
The official docs type the return value as an object, but at runtime the call returns the OverallStatus message as a string ("OK" / "Error"); status[0] receives the status message and status[1] a numeric error code. The valid signature is 4 arguments (apiObject, action, status, options).
Show test script — string return value, status array and 4-argument arity
<script runat="server">
Platform.Load("core", "1.1.5");
/*
* Callout: differs-from-docs — the return value and the status array.
*
* Proves:
* 1. DEVIATION — the call returns a STRING, not the "@returns {object}
* response object" the official docs promise. typeof is "string".
* 2. On success the returned string is the SOAP OverallStatus value "OK".
* 3. On failure the returned string is "Error" — the same call shape
* against an attribute that does not exist.
* 4. status[0] receives the status MESSAGE as a string ("Success" on a
* successful configure).
* 5. status[1] receives a NUMERIC error code — 0 on success, and a real
* non-zero code (67021, PropertyDefinitionNameNotFound) on failure.
* The docs describe this slot as a RequestID; at runtime it is a
* number, not a request identifier string.
* 6. The valid signature is exactly FOUR arguments
* (apiObject, action, status, options). Arity 0, 1, 2, 3 and 5 all
* throw — there is no reachable optional argument in either direction.
*
* DISCRIMINATING CONTROL for points 3 and 5: the failing call is not a
* malformed call — it is the SAME shape as the successful one, differing
* only in that the named attribute does not exist. That is what makes
* "Error" + a non-zero code attributable to the API result rather than to a
* broken invocation.
*
* SCOPE: CloudPage only (MCDEV_Training_QA business unit). The page also
* lists automation availability; the automation context was not exercised.
*
* EXPECTED OUTPUT: every line starts with PASS. A FAIL means the runtime no
* longer matches the documented claim and the page must be revised.
*/
function assert(id, actual, expected) {
Platform.Response.Write((actual === expected ? "PASS " : "FAIL ") + id + " -> [" + actual + "]\n");
}
function assertThrows(id, fn) {
var threw = false, msg = "";
try { fn(); } catch (ex) { threw = true; msg = ex.message; }
Platform.Response.Write((threw ? "PASS " : "FAIL ") + id + " -> " + (threw ? "threw: " + msg : "did NOT throw") + "\n");
}
/* Build a throwaway subscriber attribute definition. */
function newAttribute(attributeName) {
var attr = Platform.Function.CreateObject("PropertyDefinition");
Platform.Function.SetObjectProperty(attr, "Name", attributeName);
Platform.Function.SetObjectProperty(attr, "PropertyType", "string");
return attr;
}
var okName = "ssjsguide_cfg_dfd";
/* 1 + 2 + 4 + 5. The SUCCESS path. */
var okStatus = [0, 0];
var okResult = Platform.Function.InvokeConfigure(newAttribute(okName), "create", okStatus, null);
assert("DEV typeof InvokeConfigure(...) is string (docs: '@returns {object} response object')", String(typeof okResult), "string");
assert("DEV the return value is the OverallStatus string 'OK' (docs: a response object)", String(okResult), "OK");
assert("status[0] receives the status message on success", String(okStatus[0]), "Success");
assert("DEV status[1] receives a NUMBER, not a RequestID string (docs: 'status and RequestID')", String(typeof okStatus[1]), "number");
assert("status[1] is the error code 0 on success", okStatus[1], 0);
assert("the status array keeps its length", okStatus.length, 2);
/* 3 + 5. The FAILURE path — same call shape, attribute that does not exist. */
var errStatus = [0, 0];
var errResult = Platform.Function.InvokeConfigure(newAttribute("ssjsguide_cfg_never_existed"), "delete", errStatus, null);
assert("DEV the failure return value is the OverallStatus string 'Error' (docs: a response object)", String(errResult), "Error");
assert("status[0] receives the status message on failure", String(errStatus[0]), "PropertyDefinitionNameNotFound");
assert("status[1] is a numeric error code on failure", String(typeof errStatus[1]), "number");
assert("status[1] carries the real SOAP error code", errStatus[1], 67021);
/* 6. Exactly four arguments — no reachable optional argument. */
assertThrows("arity 0 throws (the valid arity is 4)", function () {
return Platform.Function.InvokeConfigure();
});
assertThrows("arity 1 throws (the valid arity is 4)", function () {
return Platform.Function.InvokeConfigure(newAttribute("ssjsguide_cfg_a1"));
});
assertThrows("arity 2 throws (the valid arity is 4)", function () {
return Platform.Function.InvokeConfigure(newAttribute("ssjsguide_cfg_a2"), "create");
});
assertThrows("arity 3 throws - options is NOT optional (the valid arity is 4)", function () {
var s = [0, 0];
return Platform.Function.InvokeConfigure(newAttribute("ssjsguide_cfg_a3"), "create", s);
});
assertThrows("arity 5 throws (the valid arity is 4)", function () {
var s = [0, 0];
return Platform.Function.InvokeConfigure(newAttribute("ssjsguide_cfg_a5"), "create", s, null, null);
});
/* Cleanup — remove the throwaway attribute created above. */
var cleanStatus = [0, 0];
assert("cleanup: deleting the created attribute returns 'OK'", String(Platform.Function.InvokeConfigure(newAttribute(okName), "delete", cleanStatus, null)), "OK");
assert("cleanup: status[0] reports success", String(cleanStatus[0]), "Success");
</script>
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
apiObject |
object | Yes | SOAP API object built with CreateObject and configured with SetObjectProperty |
action |
string | Yes | Configure action to perform on the object |
status |
array | Yes | Array that receives the status and request ID of the API call (e.g. [0, 0]) |
options |
object | Yes | Additional API options to include in the call. Can contain a null value. |
options may be null. status is an out parameter: the call writes the status
message into status[0] and a
numeric error code into status[1]. A null apiObject makes no SOAP call, returns
null, and leaves status untouched.
Show test script
<script runat="server">
Platform.Load("core", "1.1.5");
/*
* Chapter: Parameters —
* Platform.Function.InvokeConfigure(apiObject, action, status, options)
*
* Proves, one parameter at a time:
* 1. apiObject must be a SOAP API object built with CreateObject and
* populated with SetObjectProperty. Such an object is a .NET CLR host
* object (typeof "clr"), and a call built that way succeeds.
* 2. A plain JavaScript object or a string as apiObject throws — the
* parameter is not structurally typed, it must be an
* ExactTarget.Integration.WSDL type.
* 3. A null apiObject is the one non-object that does NOT throw: no SOAP
* call is made, the return value is a genuine null (not undefined, and
* not an OverallStatus string) and the status array is left untouched.
* 4. action is a string naming the Configure action; "create" and
* "delete" are both accepted and produce different, observable effects
* (see the examples chapter for the create/delete control).
* 5. status must be an array and is an OUT parameter: it is mutated in
* place by the call, so the caller reads status[0] / status[1] after
* the call returns. Passing a non-array throws.
* 6. options is REQUIRED but may be null — the page's "can contain a null
* value" wording. Omitting it entirely (arity 3) throws, which is what
* makes "required, may be null" different from "optional".
* 7. The member exists: a successful 4-argument invocation is the only
* reliable existence proof for a Platform.Function member (typeof
* reports "clrmethodinfo" for every name, real or not, so it proves
* nothing and is deliberately NOT asserted here).
*
* NOT ASSERTED: the values set on the apiObject cannot be read back from
* the object itself — it is a CLR host object and the engine blocks all
* introspection of it (see /platform-functions/createobject/). The values
* are proven indirectly by the API's own response, in the examples chapter.
*
* SCOPE: CloudPage only (MCDEV_Training_QA business unit).
*
* EXPECTED OUTPUT: every line starts with PASS.
*/
function assert(id, actual, expected) {
Platform.Response.Write((actual === expected ? "PASS " : "FAIL ") + id + " -> [" + actual + "]\n");
}
function assertThrows(id, fn) {
var threw = false, msg = "";
try { fn(); } catch (ex) { threw = true; msg = ex.message; }
Platform.Response.Write((threw ? "PASS " : "FAIL ") + id + " -> " + (threw ? "threw: " + msg : "did NOT throw") + "\n");
}
function assertNoThrow(id, fn) {
var ok = true, msg = "ok";
try { fn(); } catch (ex) { ok = false; msg = ex.message; }
Platform.Response.Write((ok ? "PASS " : "FAIL ") + id + " -> [" + msg + "]\n");
}
/* Build a throwaway subscriber attribute definition. */
function newAttribute(attributeName) {
var attr = Platform.Function.CreateObject("PropertyDefinition");
Platform.Function.SetObjectProperty(attr, "Name", attributeName);
Platform.Function.SetObjectProperty(attr, "PropertyType", "string");
return attr;
}
var attrName = "ssjsguide_cfg_params";
/* 1. apiObject is a CreateObject SOAP object — a CLR host object. */
var apiObject = Platform.Function.CreateObject("PropertyDefinition");
assert("typeof CreateObject('PropertyDefinition') is clr", String(typeof apiObject), "clr");
assertNoThrow("SetObjectProperty(apiObject, 'Name', ...) succeeds", function () {
Platform.Function.SetObjectProperty(apiObject, "Name", attrName);
});
assertNoThrow("SetObjectProperty(apiObject, 'PropertyType', 'string') succeeds", function () {
Platform.Function.SetObjectProperty(apiObject, "PropertyType", "string");
});
/* 4 + 5 + 6 + 7. The documented 4-argument call with options = null. */
var status = [0, 0];
assert("InvokeConfigure(apiObject, 'create', status, null) returns 'OK'", String(Platform.Function.InvokeConfigure(apiObject, "create", status, null)), "OK");
assert("status is an OUT parameter: status[0] was written by the call", String(status[0]), "Success");
assert("status is an OUT parameter: status[1] was written by the call", status[1], 0);
/* 2. apiObject must be a real SOAP object. */
assertThrows("a plain JavaScript object as apiObject throws", function () {
var s = [0, 0];
return Platform.Function.InvokeConfigure({}, "create", s, null);
});
assertThrows("a string as apiObject throws", function () {
var s = [0, 0];
return Platform.Function.InvokeConfigure("PropertyDefinition", "create", s, null);
});
/* 3. null apiObject: no SOAP call is made — genuine null back, status untouched. */
var nullStatus = [0, 0];
var nullResult = Platform.Function.InvokeConfigure(null, "create", nullStatus, null);
assert("a null apiObject does NOT throw", nullResult === null ? "true" : "false", "true");
assert("a null apiObject returns a genuine null, not the OverallStatus string", String(typeof nullResult), "object");
assert("a null apiObject is not undefined", nullResult === undefined ? "true" : "false", "false");
assert("a null apiObject leaves status[0] untouched (no SOAP call was made)", nullStatus[0], 0);
assert("a null apiObject leaves status[1] untouched (no SOAP call was made)", nullStatus[1], 0);
/* 5. status must be an array. */
assertThrows("a non-array status throws", function () {
return Platform.Function.InvokeConfigure(newAttribute("ssjsguide_cfg_p1"), "create", "notanarray", null);
});
/* 6. options is required — omitting it is NOT the same as passing null. */
assertThrows("omitting options (arity 3) throws - options is required, not optional", function () {
var s = [0, 0];
return Platform.Function.InvokeConfigure(newAttribute("ssjsguide_cfg_p2"), "create", s);
});
/* Cleanup — remove the throwaway attribute created above. */
var cleanStatus = [0, 0];
assert("cleanup: deleting the created attribute returns 'OK'", String(Platform.Function.InvokeConfigure(newAttribute(attrName), "delete", cleanStatus, null)), "OK");
assert("cleanup: status[0] reports success", String(cleanStatus[0]), "Success");
</script>
Examples
var configObj = Platform.Function.CreateObject("PropertyDefinition");
Platform.Function.SetObjectProperty(configObj, "Name", "MyAttribute");
Platform.Function.SetObjectProperty(configObj, "PropertyType", "string");
var StatusAndRequestID = [0, 0];
var result = Platform.Function.InvokeConfigure(configObj, "create", StatusAndRequestID, null);
// result === "OK", StatusAndRequestID[0] === "Success", StatusAndRequestID[1] === 0
var status = StatusAndRequestID[0];
var errorCode = StatusAndRequestID[1];
WSProxy is the recommended approach for most SOAP API interactions. Use InvokeConfigure only when the Configure SOAP verb is specifically required.
Show test script
<script runat="server">
Platform.Load("core", "1.1.5");
/*
* Chapter: Examples — the CreateObject / SetObjectProperty /
* InvokeConfigure build-and-configure pattern, end to end.
*
* This script runs the page's example against a real, throwaway subscriber
* attribute that it creates and deletes itself. The values set on the
* apiObject CANNOT be read back from the object (it is a CLR host object —
* see /platform-functions/createobject/), so the only way to prove they
* landed is to make the API answer for them.
*
* Proves:
* 1. The example's shape works: CreateObject("PropertyDefinition") +
* SetObjectProperty(Name / PropertyType) + InvokeConfigure with the
* "create" action returns "OK" and writes "Success" into status[0].
* 2. ROUND-TRIP PROOF that the create really took effect — the
* DISCRIMINATING CONTROL is a pair of otherwise identical "delete"
* calls:
* - deleting the attribute just created returns "OK" / "Success";
* - deleting a name that was never created returns "Error" /
* "PropertyDefinitionNameNotFound" with error code 67021.
* A create that had silently done nothing would make the first delete
* look like the second. It does not, so the attribute existed.
* 3. The status variables the example reads are exactly the two array
* slots: status[0] is the message string, status[1] the numeric code.
* 4. The example leaves nothing behind: after the round-trip delete, a
* second delete of the same name reports the not-found error.
*
* PAGE-EXAMPLE CORRECTION (recorded so it cannot silently regress): the
* example on this page previously configured a
* CreateObject("DataRetentionPolicyConfiguration") object. That SOAP type
* name does not resolve in this engine — CreateObject itself throws before
* InvokeConfigure is ever reached. That negative case is asserted below.
*
* SCOPE: CloudPage only (MCDEV_Training_QA business unit).
*
* EXPECTED OUTPUT: every line starts with PASS.
*/
function assert(id, actual, expected) {
Platform.Response.Write((actual === expected ? "PASS " : "FAIL ") + id + " -> [" + actual + "]\n");
}
function assertThrows(id, fn) {
var threw = false, msg = "";
try { fn(); } catch (ex) { threw = true; msg = ex.message; }
Platform.Response.Write((threw ? "PASS " : "FAIL ") + id + " -> " + (threw ? "threw: " + msg : "did NOT throw") + "\n");
}
function assertNoThrow(id, fn) {
var ok = true, msg = "ok";
try { fn(); } catch (ex) { ok = false; msg = ex.message; }
Platform.Response.Write((ok ? "PASS " : "FAIL ") + id + " -> [" + msg + "]\n");
}
/* NEGATIVE — the SOAP type the example previously used does not resolve. */
assertThrows("CreateObject('DataRetentionPolicyConfiguration') throws - that SOAP type does not resolve", function () {
return Platform.Function.CreateObject("DataRetentionPolicyConfiguration");
});
var attributeName = "ssjsguide_cfg_example";
var neverCreated = "ssjsguide_cfg_control";
/* 1. The page's example, verbatim in shape. */
var configObj = Platform.Function.CreateObject("PropertyDefinition");
assert("typeof CreateObject('PropertyDefinition') is clr", String(typeof configObj), "clr");
assertNoThrow("SetObjectProperty(configObj, 'Name', ...) succeeds", function () {
Platform.Function.SetObjectProperty(configObj, "Name", attributeName);
});
assertNoThrow("SetObjectProperty(configObj, 'PropertyType', 'string') succeeds", function () {
Platform.Function.SetObjectProperty(configObj, "PropertyType", "string");
});
var StatusAndRequestID = [0, 0];
var result = Platform.Function.InvokeConfigure(configObj, "create", StatusAndRequestID, null);
assert("InvokeConfigure(configObj, 'create', StatusAndRequestID, null) returns 'OK'", String(result), "OK");
/* 3. The two status slots the example reads. */
var status = StatusAndRequestID[0];
var errorCode = StatusAndRequestID[1];
assert("status = StatusAndRequestID[0] is the message string", String(status), "Success");
assert("errorCode = StatusAndRequestID[1] is the numeric code 0 on success", errorCode, 0);
/* 2. CONTROL — the delete that must FAIL, on a name never created. */
var controlObj = Platform.Function.CreateObject("PropertyDefinition");
Platform.Function.SetObjectProperty(controlObj, "Name", neverCreated);
var controlStatus = [0, 0];
assert("control: deleting an attribute that was never created returns 'Error'", String(Platform.Function.InvokeConfigure(controlObj, "delete", controlStatus, null)), "Error");
assert("control: status[0] reports the name was not found", String(controlStatus[0]), "PropertyDefinitionNameNotFound");
assert("control: status[1] carries error code 67021", controlStatus[1], 67021);
/* 2. ROUND-TRIP — the delete that must SUCCEED, on the attribute created above. */
var deleteObj = Platform.Function.CreateObject("PropertyDefinition");
Platform.Function.SetObjectProperty(deleteObj, "Name", attributeName);
var deleteStatus = [0, 0];
assert("round-trip: deleting the attribute just created returns 'OK'", String(Platform.Function.InvokeConfigure(deleteObj, "delete", deleteStatus, null)), "OK");
assert("round-trip: status[0] reports success", String(deleteStatus[0]), "Success");
assert("round-trip: status[1] is 0 on success", deleteStatus[1], 0);
/* 4. Cleanup is complete — the attribute is gone. */
var afterObj = Platform.Function.CreateObject("PropertyDefinition");
Platform.Function.SetObjectProperty(afterObj, "Name", attributeName);
var afterStatus = [0, 0];
assert("cleanup verified: deleting it again now reports 'Error'", String(Platform.Function.InvokeConfigure(afterObj, "delete", afterStatus, null)), "Error");
assert("cleanup verified: status[0] reports the name is gone", String(afterStatus[0]), "PropertyDefinitionNameNotFound");
</script>