Introduction
Let’s say you need to review or document all the conditions 1 used in UI Policies, SLAs, or other records. You open the table, and there it is: the conditions
field—stored as an encoded query like this:
active=true^priority=1
This format is totally fine for developers or tech-savvy admins. But try sharing it with a stakeholder or process owner, and it might raise more questions than it answers.
Unfortunately, there’s no out-of-the-box way in ServiceNow to turn these encoded queries into something readable. Functions like getDisplayValue()
or getValue()
aremt’ helpful: they just return the same encoded string.
Solution
To make this more human-friendly and readable, you can use the script below. It converts encoded queries into nice sentences like:
Active is true AND Priority is High
It’s handy when you need to make sense of a bunch of conditions—whether for documentation, audits, or just to talk about them clearly.
It calls a (not officially documented) internal ServiceNow REST API that the UI uses to parse condition queries.
Here’s what happens under the hood:
- The script builds a URL to call the API:
/api/now/ui/query_parse/{table}/map?sysparm_query=...
- It executes the request using
sn_ws.RESTMessageV2
2 - The response comes back as a JSON object with a ‘predicates’ that represent each part of the condition.
- The script then recursively parses these predicates into a readable string
Authentication Setup
You will need to set up a user with enough rights to access the table you’re querying (e.g. ui_policy
, contract_sla
, etc.), and then create a basic auth record3. This credential will be used in the REST call to authenticate the request.
Once that’s done, you can pass the sys_id
of the credential in the script below.
Example Script
Here is the script. It is meant to be a one-time or punctual task, so it is best run in a background script. Of course, if you need it more often, you can adapt it in a Script Include and/or build a Flow Action that does just that.
To use it, copy-paste all of this in the background script and adapt the call:
let authProfileId = "xxx"; // your credential sys_id
let uiPolicyGr = new GlideRecord('ui_policy'); // Adapt the table...
uiPolicyGr.addEncodedQuery('nameSTARTSWITHsomething'); //... and the query
uiPolicyGr.query();
while (uiPolicyGr.next()) {
let conditionText = getUserFriendlyCondition(uiPolicyGr.getTableName(), uiPolicyGr.conditions);
gs.info(`${uiPolicyGr.getDisplayValue()},${conditionText}`); // For example, output a comma-delimited list so you can copy it into Excel or another tool.
}
/**
* Retrieves a user-friendly representation of a condition from a ServiceNow table.
*
* @param {string} table - The name of the table to query.
* @param {string} condition - The encoded query condition string.
* @param {string} authProfileId - The authentication profile ID for REST API access. Default is provided if not supplied.
* @returns {string} A human-readable representation of the condition.
*/
function getUserFriendlyCondition(table, condition, authProfileId) {
const instance = gs.getProperty("instance_name");
condition = encodeURIComponent(condition);
let r = new sn_ws.RESTMessageV2();
r.setHttpMethod("GET");
r.setEndpoint(`https://${instance}.service-now.com/api/now/ui/query_parse/${table}/map?sysparm_query=${condition}`);
authProfileId = authProfileId || "xxx"; // Replace with your credential. This will be used if no value is passed to the function.
r.setAuthenticationProfile("basic", authProfileId);
let response = r.execute();
let responseBody = response.getBody();
let httpStatus = response.getStatusCode();
if (httpStatus == 200) {
let responseObj = JSON.parse(responseBody);
if (responseObj?.result?.predicates) {
return parsePredicates(responseObj.result.predicates);
}
}
return null;
}
function parsePredicates(predicates) {
function processPredicate(predicate) {
if (predicate.column_type === 'element') {
return predicate.term_label;
} else if (predicate.compound_type === 'or') {
return predicate.subpredicates.map(processPredicate).join(' OR ');
} else if (predicate.compound_type === 'and') {
return predicate.subpredicates.map(processPredicate).join(' AND ');
}
return '';
}
return predicates.map(processPredicate).join(' AND ');
}
Multi-language Support
If you need to output the condition in a different language, you can simply set the Preferred language of the user used by the REST call to the desired value. The output will then be in this language.
Final Notes
This script uses an internal ServiceNow REST API (
/api/now/ui/query_parse
) that isn’t officially documented (or at least not publicly). It’s safe for internal tools and scripting, but use it with care and test thoroughly.Just keep in mind that because the API is not documented, it might change or break in future versions.