Example 1: Retrieving all incident records from an external source
Summarize
Summary of Example 1: Retrieving all incident records from an external source
This example demonstrates how ServiceNow customers can create a scripted integration to retrieve and cache all incident records from an external system using the Remote Table API. It shows how to use RESTMessageV2 to call an external REST service and the Transformer API to map and transform the external JSON data into the local remote table format.
Show less
Key Features
- RESTMessageV2 Integration: The script creates and executes a RESTMessageV2 call named "Remote Instance Incidents" with the function "All Incidents" to fetch incident data from an external REST endpoint.
- Error Handling: If the REST call fails or returns an error, the script captures and sets the error message on the query, aiding troubleshooting and ensuring visibility of issues during data retrieval.
- Data Transformation: The script uses the
sntfrm.TransformerAPI with a transformer definition to parse the JSON response, map fields, and extract individual incident records. - Field Mapping: The transformer definition explicitly maps external JSON fields (e.g., active, callerid, number, shortdescription, sysid, updates) to the remote table’s fields, ensuring proper data alignment.
- sysid Mapping: The external record’s sysid is mapped to the local sysid field to maintain record identity, which is critical for proper form functionality and data integrity.
Practical Use for ServiceNow Customers
This script enables customers to seamlessly integrate incident data from external systems into their ServiceNow instance as remote tables. By leveraging RESTMessageV2 and Transformer APIs, customers can automate data retrieval, handle errors effectively, and maintain consistent data structure through explicit field mapping. This approach supports real-time or scheduled synchronization of external incident records for reporting, analysis, or extended workflows within ServiceNow without manual data import.
Additional Notes
- Ensure the RESTMessageV2 is properly configured with the correct endpoint and HTTP methods named "Remote Instance Incidents" and "All Incidents."
- Mapping sysid is mandatory and must not exceed 32 characters to ensure record uniqueness and proper referencing in ServiceNow forms.
- Debugging tips include using
gs.debug()for visibility into REST call errors during development. - Further reference is available for RESTMessageV2 usage and Transformer API objects for scoped and global contexts.
These are examples of script definitions you might create for retrieval and caching of data from sources external to your current instance. In this first example, we create a script to load all incident records from an external source.
/**
* Using `v_query`, add the rows to `v_table`
*/
(function executeQuery(v_table, v_query) {
fetchAllIncidents(v_table, v_query);
/**
* fetch all incidents records from the remote instance
*/
function fetchAllIncidents(v_table, v_query) {
// Uses RestMessage with name 'Remote Instance Incidents' and function 'All Incidents'
// Create a RestMessage first which calls an external REST service
try {
var restMessage = new sn_ws.RESTMessageV2('Remote Instance Incidents', 'All Incidents');
var response = restMessage.execute();
var responseBody = response.getBody();
// if REST call ends up in an error, set the last error message which shows up
// at the bottom of the list view
if (response.haveError()) {
v_query.setLastErrorMessage(response.getErrorMessage());
// can use gs.error() or gs.addErrorMessage() while debugging
// gs.debug() messages visible in session debugger
// gs.debug(response.getErrorMessage());
return;
}
} catch (ex) {
v_query.setLastErrorMessage(ex.message);
// gs.debug(ex.message);
return;
}
var transformerDefinition = getTransformerDefinition();
var transformer = new sn_tfrm.Transformer(transformerDefinition, responseBody);
// transformer parses the responseBody and extracts rows
while (transformer.transform()) {
// row is field-value map e.g. { active:"true", number: "INC0000001"}
var row = transformer.getRow();
// you may do any additional transformations to the row like GlideDuration, GlideDataTime etc. For example,
// row.duration = new GlideDuration(row.duration);
// finally add the row to the remote table
v_table.addRow(row);
}
}
/**
* returns a sn_tfrm.TransformerDefinition, which defines the mapping of the table fields and elements in the response body
*/
function getTransformerDefinition() {
// create a rule list to map a field to its element path
var ruleList = new sn_tfrm.TransformerRuleList()
.fromJSON() // the response body is a JSON
// 'active' field maps to path '$.active'
.addRule("active", "$.active")
.addRule("caller_id", "$.caller_id.value")
.addRule("number", "$.number")
.addRule("short_description", "$.short_description")
.addRule("sys_id", "$.sys_id")
.addRule("updates", "$.sys_mod_count");
var recordPath = "$.result";
return new sn_tfrm.TransformerDefinition(ruleList, recordPath);
}
})(v_table, v_query);
These code snippets are of note in this script:
function fetchAllIncidents(v_table, v_query) {
// Uses RestMessage with name 'Remote Instance Incidents' and function 'All Incidents'
// Create a RestMessage first which calls an external REST service
try {
var restMessage = new sn_ws.RESTMessageV2('Remote Instance Incidents', 'All Incidents');
var response = restMessage.execute();
var responseBody = response.getBody();
// if REST call ends up in an error, set the last error message which shows up
// at the bottom of the list view
if (response.haveError()) {
v_query.setLastErrorMessage(response.getErrorMessage());
// can use gs.error() or gs.addErrorMessage() while debugging
// gs.debug() messages visible in session debugger
// gs.debug(response.getErrorMessage());
return;
}
} catch (ex) {
v_query.setLastErrorMessage(ex.message);
// gs.debug(ex.message);
return;
}
You can create a RestMessage and directly use it in the script. In this example, it
uses a RESTMessageV2 API with the name of Remote Instance
Incidents, and the function All Incidents, which gets all
incident data. Once a response is returned from the server, an error message appears
if problems are encountered in the data retrieval.
If no problems are encountered in the data retrieval, it gets the data body for the records.
var transformerDefinition = getTransformerDefinition();
var transformer = new sn_tfrm.Transformer(transformerDefinition, responseBody);
// transformer parses the responseBody and extracts rows
while (transformer.transform()) {
// row is field-value map e.g. { active:"true", number: "INC0000001"}
var row = transformer.getRow();
// you may do any additional transformations to the row like GlideDuration, GlideDataTime etc. For example,
// row.duration = new GlideDuration(row.duration);
// finally add the row to the remote table
v_table.addRow(row);
It then uses the Transformer API to perform any required data transformations, extracts rows, and then adds a row for each record to the remote table.
/**
* returns a sn_tfrm.TransformerDefinition, which defines the mapping of the table fields and elements in the response body
*/
function getTransformerDefinition() {
// create a rule list to map a field to its element path
var ruleList = new sn_tfrm.TransformerRuleList()
.fromJSON() // the response body is a JSON
// 'active' field maps to path '$.active'
.addRule("active", "$.active")
.addRule("caller_id", "$.caller_id.value")
.addRule("number", "$.number")
.addRule("short_description", "$.short_description")
.addRule("sys_id", "$.sys_id")
.addRule("updates", "$.sys_mod_count");
var recordPath = "$.result";
return new sn_tfrm.TransformerDefinition(ruleList, recordPath);
}
})(v_table, v_query);
getTransformerDefinition defines the schema of the record in the
external API response body. It maps each of the fields in the table script to an
element in the external record. Any external data elements outside of this mapping
are not supported or retrieved.