Configure the ServiceNow Webhook Integration
By integrating ServiceNow with Forescout Cloud, you can more seamlessly synchronize your data between both systems bi-directionally. This means that case statuses and comments can be synchronized between both systems, streamlining your case management workflows.
With a webhook integration, you can configure one business rule in ServiceNow that sends updates to your Forescout Cloud endpoint.
Prerequisites
Before you can configure the ServiceNow webhook, you must have:
- Administrator-level access to your ServiceNow instance.
- The Forescout Account ID and API Key from the Administration >
Integrations tab. See Generate an API key for more
information.Important: Keep your API key information safe. Do not share or paste it in public spaces.
Configuration steps
To configure the ServiceNow webhook for Forescout Cloud:
- Sign in to ServiceNow as an admin-capable user.
- Go to System Definition > Business Rules.
- Click New to create a new business rule.
- Provide a name for the new Forescout Cloud webhook, and then select Incident (incident) for the Table.
- Select the Active check box.
- In the When to Run tab, select or specify the
following:
- When: After.
- Order: 100, or place this rule after your other ServiceNow business rules.
- Update and Query: Select these check boxes.
- Insert and Delete: Clear these check boxes.
- In the Filter Conditions section, add OR
condition clauses so that the rule runs when any of the
following fields change:
- State
- Assigned To
- Priority
- Severity
- Short Description
- Additional CommentsNote: You can adjust these fields as needed for your organization, but Forescout recommends State and Additional Comments as starting points.
- In the Advanced tab, enable the Script option.
- Paste the script that builds a JSON body and sends it to your Forescout
endpoint. Be sure to replace the following placeholders in the script:
- {{accountID}}: Replace with your Forescout account ID.
- {{API Token}}: Replace with your Forescout API Key. Use the format your environment expects (ex: Authorization: ApiKey <token>).
Copy
var gr = new GlideRecord('incident');
gr.addQuery('number', current.getValue('number'));
gr.query();
if (gr.next()) {
var caseId = "";
var caseIdRegex = /Case ID=(\d+)/;
var commentsArray = [];
// Get all comments for the incident, latest being the first here
var jf = new GlideRecord('sys_journal_field');
jf.addQuery('element_id', gr.getValue('sys_id'));
jf.orderByDesc('sys_created_on');
jf.query();
while (jf.next()) {
var commentObj = {
sys_id: jf.getValue('sys_id'),
sys_created_on: jf.getValue('sys_created_on').replace('T', ' ').substring(0, 19),
name: jf.getValue('name'),
element_id: jf.getValue('element_id'),
sys_tags: jf.getValue('sys_tags'),
value: jf.getValue('value'),
sys_created_by: jf.getValue('sys_created_by'),
element: jf.getValue('element')
};
commentsArray.push(commentObj);
// Find caseId from the latest comment with pattern
if (!caseId && commentObj.value) {
var match = commentObj.value.match(caseIdRegex);
if (match && match[1]) {
caseId = match[1];
}
}
}
var payload = {
case_id: caseId,
sys_id: gr.getValue("sys_id"),
number: gr.getValue("number"),
state: gr.getDisplayValue("state"),
severity: gr.getDisplayValue("severity"),
priority: gr.getDisplayValue("priority"),
sys_created_by: gr.getValue("sys_created_by"),
sys_created_on: gr.getValue("sys_created_on"),
sys_updated_by: gr.getValue("sys_updated_by"),
sys_updated_on: gr.getValue("sys_updated_on"),
close_code: gr.getDisplayValue("close_code"),
close_notes: gr.getValue("close_notes"),
resolved_by: gr.resolved_by.getDisplayValue(),
resolved_at: gr.getValue("resolved_at"),
assigned_to: gr.assigned_to.getDisplayValue(),
comments: commentsArray, // Now array of objects
opened_by: gr.opened_by.getDisplayValue(),
opened_at: gr.getValue("opened_at")
};
var client = new sn_ws.RESTMessageV2();
client.setHttpMethod('POST');
client.setEndpoint('https://app.cloud.forescout.com/api/public/v1/accounts/{{accountID}}/update-snow-incident');
client.setRequestHeader("Authorization", "{{API Token}}");
client.setRequestHeader("Content-Type", "application/json");
client.setRequestBody(JSON.stringify(payload));
try {
var response = client.execute();
var responseBody = response.getBody();
var httpStatus = response.getStatusCode();
if (httpStatus == 200) {
gs.info('Successfully sent incident: ' + gr.getValue('number'));
} else {
gs.error('Failed to send: ' + responseBody);
}
} catch (e) {
gs.error('Error sending incident: ' + e.message);
}
}
For more information about ServiceNow business rules, refer to the ServiceNow documentation.
minute read