Resolving INVALID_FUNCTION Errors in CXone Studio Snippets: Correct Syntax for GetRESTProxy()
What You Will Build
- This tutorial demonstrates how to correctly instantiate and configure the
GetRESTProxy()object in NICE CXone Studio Snippets to avoid theINVALID_FUNCTIONruntime error. - It uses the NICE CXone Studio Snippet execution environment (JavaScript/TypeScript based).
- The code examples are written in JavaScript, the primary language for CXone Studio Snippets.
Prerequisites
- Environment: NICE CXone Studio Designer.
- Component: Studio Snippet (JavaScript).
- Required Permissions: The user executing the snippet must have permissions to make outbound HTTP requests from the CXone platform (typically configured in the CXone Admin console under Security > API Access or similar network settings).
- Knowledge: Basic understanding of JavaScript asynchronous programming (
async/await) and JSON structure.
Authentication Setup
In CXone Studio Snippets, authentication for outbound REST calls is handled by the GetRESTProxy() object itself. You do not manually inject OAuth tokens into the header unless you are calling an external API that requires a specific bearer token not managed by CXone. For internal CXone APIs or external services that accept CXone’s default authentication context, the proxy handles the handshake.
If you are calling an external API that requires a pre-shared key or a static API key, you must configure the headers explicitly in the GetRESTProxy configuration object.
Critical Note: The INVALID_FUNCTION error often arises not from authentication failure, but from incorrect instantiation of the proxy object or passing invalid arguments to its methods.
Implementation
Step 1: Correctly Instantiating GetRESTProxy()
The INVALID_FUNCTION error typically occurs when developers attempt to call GetRESTProxy as a method on an undefined object, or when they pass parameters in the wrong order or format. The GetRESTProxy function is a global helper in the Studio Snippet context. It returns a promise or a proxy object depending on the specific SDK version, but in modern Studio Snippets, it is best treated as a factory function that returns a configured client.
The correct syntax requires passing a configuration object that defines the base URL, headers, and timeout.
// INCORRECT: This causes INVALID_FUNCTION
// let proxy = GetRESTProxy(url, headers); // Wrong argument structure
// let proxy = this.GetRESTProxy(); // 'this' is not the correct context for global helpers
// CORRECT: Instantiation with a configuration object
const restConfig = {
baseUrl: "https://api.niceincontact.com",
headers: {
"Content-Type": "application/json",
"Accept": "application/json"
// If calling external API with API Key:
// "Authorization": "Bearer YOUR_TOKEN"
},
timeout: 5000 // milliseconds
};
// GetRESTProxy is a global function in the Snippet context
let restProxy = GetRESTProxy(restConfig);
Step 2: Executing the HTTP Request
Once the proxy is instantiated, you must use the correct HTTP verb methods (get, post, put, delete). These methods return promises. A common mistake leading to INVALID_FUNCTION is attempting to use the proxy synchronously or chaining promises incorrectly.
Here is the correct pattern for a POST request to an internal CXone API endpoint (e.g., creating a note on a contact).
async function createContactNote(contactId, noteText) {
// Define the endpoint path relative to the baseUrl
const endpoint = `/v1/interactions/contacts/${contactId}/notes`;
// Define the payload
const payload = {
note: noteText,
createdDate: new Date().toISOString()
};
try {
// Execute the POST request
// restProxy.post(path, body, headersOverride)
const response = await restProxy.post(endpoint, JSON.stringify(payload));
// Check response status
if (response.statusCode >= 200 && response.statusCode < 300) {
console.log("Note created successfully");
return response.body;
} else {
console.error(`Failed to create note. Status: ${response.statusCode}`);
throw new Error(`HTTP Error: ${response.statusCode}`);
}
} catch (error) {
// Handle network errors or serialization errors
console.error("Error during REST call:", error);
throw error;
}
}
Step 3: Handling Dynamic Headers and Content Types
The INVALID_FUNCTION error can also be triggered if the GetRESTProxy configuration is malformed. For example, passing a null header object or an invalid baseUrl (missing protocol) will cause the underlying engine to fail initialization.
Ensure the baseUrl always includes https://.
// Dynamic Configuration Example
function getDynamicProxy(targetUrl) {
// Validation to prevent INVALID_FUNCTION due to malformed URL
if (!targetUrl || !targetUrl.startsWith("https://")) {
throw new Error("Invalid Base URL provided");
}
const config = {
baseUrl: targetUrl,
headers: {
"Content-Type": "application/json"
},
timeout: 10000
};
return GetRESTProxy(config);
}
// Usage
async function callExternalService() {
const proxy = getDynamicProxy("https://example.com/api");
try {
// GET Request
const result = await proxy.get("/data");
return result.body;
} catch (err) {
console.error("External call failed", err);
}
}
Complete Working Example
Below is a complete, copy-pasteable Studio Snippet script. This script retrieves contact details from the CXone API using GetRESTProxy. It includes proper error handling, type checking, and the correct instantiation pattern to avoid INVALID_FUNCTION.
/**
* Studio Snippet: Retrieve Contact Details via REST Proxy
*
* This snippet demonstrates the correct usage of GetRESTProxy()
* to fetch data from the CXone v1 API.
*/
// Global helper provided by CXone Studio Snippet runtime
// var GetRESTProxy;
/**
* Main entry point for the snippet
* @param {object} context - The snippet context containing contact info
*/
async function main(context) {
// 1. Extract Contact ID from context
// In Studio, context usually contains 'contact' or 'interaction' objects
const contactId = context.contact && context.contact.id;
if (!contactId) {
console.error("Contact ID is missing from context");
return { success: false, error: "Missing Contact ID" };
}
// 2. Configure the REST Proxy
// Critical: baseUrl must be a valid HTTPS URL
const restConfig = {
baseUrl: "https://api.niceincontact.com",
headers: {
"Content-Type": "application/json",
"Accept": "application/json"
},
timeout: 5000 // 5 seconds timeout
};
try {
// 3. Instantiate the Proxy
// This is the step where INVALID_FUNCTION often occurs if syntax is wrong
const restProxy = GetRESTProxy(restConfig);
// 4. Define the Endpoint
// Using v1 API for contact details
const endpoint = `/v1/interactions/contacts/${contactId}`;
// 5. Execute the GET Request
// The post/get/put/delete methods return a Promise
const response = await restProxy.get(endpoint);
// 6. Process the Response
if (response.statusCode === 200) {
const contactData = JSON.parse(response.body);
// Log the result to Studio Debug Console
console.log("Successfully retrieved contact: " + contactData.id);
// Return data for use in subsequent flows
return {
success: true,
data: contactData,
statusCode: response.statusCode
};
} else if (response.statusCode === 404) {
console.warn(`Contact ${contactId} not found`);
return {
success: false,
error: "Contact Not Found",
statusCode: response.statusCode
};
} else {
console.error(`Unexpected status code: ${response.statusCode}`);
return {
success: false,
error: `API Error: ${response.statusCode}`,
statusCode: response.statusCode
};
}
} catch (error) {
// Catch block for network errors, timeouts, or INVALID_FUNCTION
console.error("Exception in REST Call:", error.message);
// Check specifically for function instantiation errors
if (error.message.includes("INVALID_FUNCTION") || error.message.includes("GetRESTProxy")) {
console.error("Check GetRESTProxy syntax and configuration object");
}
return {
success: false,
error: error.message
};
}
}
// Execute the main function
main(context);
Common Errors & Debugging
Error: INVALID_FUNCTION
What causes it:
This error indicates that the JavaScript engine in the Studio Snippet runtime could not resolve the GetRESTProxy function or that the arguments passed to it did not match the expected signature.
How to fix it:
- Check for Typos: Ensure you are calling
GetRESTProxy(case-sensitive). Do not callGetRestProxyorgetRESTProxy. - Verify Context: Do not call
this.GetRESTProxy().GetRESTProxyis a global function in the snippet scope. - Validate Arguments: Ensure you are passing a single configuration object, not separate arguments.
- Bad:
GetRESTProxy("https://...", { headers: {} }) - Good:
GetRESTProxy({ baseUrl: "https://...", headers: {} })
- Bad:
- Check for Null Config: If the configuration object is
nullorundefined, the engine may throw this error. Ensure the object is fully constructed before passing it.
Error: Timeout or Network Failure
What causes it:
The baseUrl is unreachable, or the firewall between CXone and the target API is blocking the request.
How to fix it:
- Increase the
timeoutvalue in the configuration object. - Verify that the
baseUrlis publicly accessible or whitelisted in your CXone tenant’s network settings. - Check the
response.statusCode. If it is 0, it is likely a network connectivity issue rather than an HTTP error.
Error: JSON Parse Error
What causes it:
The response.body is not valid JSON, but you attempt to parse it or use it as an object.
How to fix it:
Always check the Content-Type of the response or wrap JSON.parse in a try-catch block.
let bodyData;
try {
bodyData = JSON.parse(response.body);
} catch (e) {
console.error("Response body is not valid JSON");
bodyData = response.body; // Fallback to string
}