# ServiceNow Destination (Custom Webhook)

## Overview

With a simple Scripted Rest API configuration in the ServiceNow console, alerts fired from Panther can be mapped directly to new incidents. You can customize the content of alerts with [alert functions in Python detections](https://docs.panther.com/detections/rules/python#alert-functions-in-python-detections) and [dynamic alert keys in YAML detections](https://docs.panther.com/detections/rules/writing-simple-detections#dynamic-alert-keys-in-yaml-detections).

## How to configure ServiceNow to create tickets from Panther alerts

To configure ServiceNow to create tickets from Panther alerts, you will create a Scripted REST API in ServiceNow, then create a custom webhook alert destination in Panther, using your ServiceNow forwarding URL.

{% hint style="info" %}
Additional information on this process can be found in the ServiceNow documentation: [How to Integrate Webhooks Into ServiceNow](https://www.servicenow.com/community/in-other-news/how-to-integrate-webhooks-into-servicenow/ba-p/2271745).
{% endhint %}

### Prerequisites

* To complete [Step 1 of this process](#step-1-create-a-scripted-rest-api-in-servicenow), creating a Scripted REST API in Service Now, your ServiceNow user must have the `web_service_admin` role.

### Step 1: Create a Scripted REST API in ServiceNow

{% hint style="info" %}
Learn more about Scripted REST APIs in the ServiceNow documentation: [Scripted REST APIs](https://docs.servicenow.com/bundle/washingtondc-api-reference/page/integrate/custom-web-services/concept/c_CustomWebServices.html).
{% endhint %}

1. In the ServiceNow console, click the **All** tab in the upper left-hand corner.
2. Expand the **System Web Services** and **Scripted Web Services** navigations, then click on **Scripted REST APIs.**\ <img src="https://4011785613-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LgdiSWdyJcXPahGi9Rs-2910905616%2Fuploads%2Fgit-blob-b772e2e4c08ee247442f489a96a38e4bbdfc7d86%2Fimage.png?alt=media" alt="In the ServiceNow console, the &#x22;All&#x22; tab is selected at the top. In the navigation menu, System Web Services is expanded, and Scripted REST APIs is highlighted." data-size="original">
3. Click **New** in the upper right-hand corner.
4. Select a Name and an ID, for example, `Panther Incident Creation` and `panther_incident_creation`, respectively.\
   ![The image shows the form to create a new Scripted REST Service in ServiceNow. It contains fields for Name, API ID, Protection Policy, Application, and API namespace.](https://4011785613-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LgdiSWdyJcXPahGi9Rs-2910905616%2Fuploads%2Fgit-blob-8d5951c7fd637b1f36dea88f207a47eb9e3e8c92%2Fimage.png?alt=media)
5. Click **Submit**.
6. On the Scripted Rest API's page, search for the name you just created. Click the **hyperlinked name.**
7. Near the bottom of the page, click the **Resources tab.** Click the **New** button in the right-hand corner.
8. Fill out the **Scripted REST Resource Alert** page:
   * **Name:** Enter a descriptive name, e.g., `Panther_Alert`.\
     ![The image shows the Scripted REST Resource configuration page in Service Now. The "Name" field has a red circle around it, and it is filled in with "Panther\_Alert".](https://4011785613-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LgdiSWdyJcXPahGi9Rs-2910905616%2Fuploads%2Fgit-blob-f7d3990f6950dd1cc173a0c7e07172ac218b18da%2FScripted%20REST%20ss%20name%20field.png?alt=media)
   * **HTTP method:** Select POST.
   * **Script:** Paste in the schema code below:
     * ```
       (function process(/*RESTAPIRequest*/ request, /*RESTAPIResponse*/ response) {

       	// prep the different fields 
       	var data = request.body.data;
       	var title = data.title;
       	var alert = JSON.stringify(data);
       	var alertContext = JSON.stringify(data.alertContext);
       	var severity = data.severity;
       	var link = data.link;
       	var runbook = data.runbook;
       	var type = data.type;
       	var alertId = data.alertId;
       	
       	var grIncident = new GlideRecord('incident');

       	grIncident.initialize();
       	
       	grIncident.setValue('short_description', title);
       	grIncident.setValue('description', alert );
       	grIncident.setValue('category', type);
       	grIncident.setValue('subcategory', alertId);
       	
       	//Map urgency to Panther severity
       	if (severity == "CRITICAL" || severity == "HIGH") {
       		grIncident.setValue('urgency','1');
       		grIncident.setValue('impact','1');
       	} else if (severity == "LOW" || severity == "MEDIUM") {
       		grIncident.setValue('urgency','2');
       	} else {
       		grIncident.setValue('urgency','3');
       	}
       	
       	//grIncident.insert();
       	var recResponse = grIncident.insert(handleResponse);

       	function handleResponse(recResponse, answer) {
       	// Answer will be the sys_id of the created record or null
       	alert('Newly created sys_id is - ' + answer + ' exists');
       	}

       	var url = gs.getProperty('glide.servlet.uri');

               //building the response of the API, this example returns the incident ID that got created above.
       	var body = {};
       	body.sys_id = recResponse;
       	body.link = url + "task.do?sys_id=" + recResponse;
       	response.setBody(body);
       	
       	//example test event from Panther when creating and testing destination integration
       	//{"id":"Test.Alert","createdAt":"2022-04-26T03:17:32.099054303Z","severity":"INFO","type":"RULE","link":"https://domain.runpanther.net","title":"This is a Test Alert","name":"Test Alert","alertId":"Test.Alert","alertContext":{},"description":"This is a Test Alert","runbook":"Stuck? Check out our docs: https://docs.runpanther.io","tags":["test"],"version":"abcdefg"}

       })(request, response);
       ```
     * Under the **Security** tab, uncheck the box next to **Requires authentication**.\
       ![The Security tab is displayed in ServiceNow. The "Requires Authentication" box is circled, and the box next to it is not checked.](https://4011785613-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LgdiSWdyJcXPahGi9Rs-2910905616%2Fuploads%2Fgit-blob-8816165d140335a7f2416d634658bcad3d3c92c3%2Fservicenow%20authentication.png?alt=media)
9. Click **Submit**.

{% hint style="warning" %}
The schema provided above maps the alert payload from Panther to the relevant fields in the ServiceNow ticket. The [ServiceNow blog](https://community.servicenow.com/community?id=community_blog\&sys_id=886d2a29dbd0dbc01dcaf3231f9619b0) also provides a different example of receiving the POST payload. Each customer environment is different – select what works best for how the Alert payload is handled and parsed into your ServiceNow tickets.
{% endhint %}

### Step 2: Create a Custom Webhook integration in Panther

1. In the left-hand navigation bar of your Panther Console, click **Configure > Alert Destinations.**
2. Click **+Add your first Destination**.
   * If you have already created Destinations, click **Create New** in the upper right side of the page to add a new Destination.
3. Click the **Custom Webhook** tile.
4. On the **Configure Your Webhook Destination** page, fill out the form:
   * **Display Name:** Enter a descriptive name.
   * **Custom Webhook URL**: Enter your Custom Webhook forwarding URL.
     * Your webhook URL is in the following format: `https://<your_domain>.service-now.com/<base_api_path>`
     * This value can be created by combining the following values in your ServiceNow console:
       * The domain in your browser address bar
       * The value in the **Base API path** field

         <figure><img src="https://4011785613-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LgdiSWdyJcXPahGi9Rs-2910905616%2Fuploads%2Fgit-blob-2a4f8f3a5f837e4b8ed54412fc4c346980795f4f%2Fimage%20(13).png?alt=media" alt="The servicenow console is shown, with various fields visible, like Name and API ID. Two areas are highlighted: the domain in the URL address bar, and the Base API path field."><figcaption></figcaption></figure>
   * **Severity Levels**: Select the severity level of alerts to send to this destination.
   * **Default Alert Types**: Select the alert types to send to this destination.
   * **Log Types**: By default, we will send alerts from all log types. Specify log types here if you want to only send alerts from specific log types.
   * **Allow Manual Dispatch**: Set this toggle ON if you'd like to be able to [manually dispatch alerts](https://docs.panther.com/alerts#manual-alert-dispatch) to this destination.\
     ![In the Panther Console, the "Configure your Custom Webhook Destination" page is displayed. It contains fields for Display Name, Custom Webhook URL, Severity, Alert Types, and Log Types.](https://4011785613-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LgdiSWdyJcXPahGi9Rs-2910905616%2Fuploads%2Fgit-blob-83d745d8ee377464dc3e1e11d45c2db5ea11681e%2Fcustom%20webook%20destinations.png?alt=media)
5. Click **Add Destination**.
6. Click **Send Test Alert** to make sure everything works correctly.
   * A test event should now exist in your ServiceNow Incidents table.\
     ![The image shows the Incidents Table in ServiceNow. There is a test event highlighted in the list.](https://4011785613-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LgdiSWdyJcXPahGi9Rs-2910905616%2Fuploads%2Fgit-blob-d341b521d919be2fa10ddd4c997e4c0d8eace235%2Fimage%20\(5\)%20\(1\)%20\(2\)%20\(1\)%20\(1\)%20\(1\)%20\(1\)%20\(1\).png?alt=media)
7. Click **Finish Setup.**

### Example

Click the **Test Alert** button to generate an alert and send to ServiceNow; the payload of the alert is seen below:

```json
{"id":"Test.Alert","createdAt":"2022-04-26T03:17:32.099054303Z","severity":"INFO","type":"RULE","link":"https://domain.runpanther.net","title":"This is a Test Alert","name":"Test Alert","alertId":"Test.Alert","alertContext":{},"description":"This is a Test Alert","runbook":"Stuck? Check out our docs: https://docs.runpanther.io","tags":["test"],"version":"1"}
```

Once the alert is received by ServiceNow, an incident is created in ServiceNow Incident table:

<figure><img src="https://4011785613-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LgdiSWdyJcXPahGi9Rs-2910905616%2Fuploads%2Fgit-blob-f4c745a9b895c46e2f862a3796bff96fcbb84c60%2Fimage.png?alt=media" alt="The Incident Table in ServiceNow contains a test alert."><figcaption></figcaption></figure>
