# ServiceNow Destination (Custom Webhook)

## Overview&#x20;

With a simple Scripted Rest API configuration in the ServiceNow console, alerts fired from Panther can be mapped directly to new incidents. Leveraging Python detections and [our auxiliary functions](https://docs.panther.com/writing-detections/detection-auxiliary-functions) allows customers to dynamically create alerts with custom webhooks.

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

### Prerequisites

ServiceNow permissions to create a Scripted Rest API require a user with the **web\_service\_admin** role. The below ServiceNow references provide context on setting up these initial Scripted Rest API requirements:

* [How to Integrate Webhooks Into ServiceNow - Blog - ServiceNow Community](https://community.servicenow.com/community?id=community_blog\&sys_id=886d2a29dbd0dbc01dcaf3231f9619b0)
* [Scripted Rest APIs - ServiceNow Documentation](https://docs.servicenow.com/en-US/bundle/sandiego-application-development/page/integrate/custom-web-services/task/t_CreateAScriptedRESTService.html)

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

1. In the ServiceNow console, click the **All** tab in the upper left-hand corner.&#x20;
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%2Ff9R8KZxaAxt91H1uC8Cr%2Fimage.png?alt=media&#x26;token=99a1a98c-1fb3-4176-99d6-f617ef972a1f" 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.&#x20;
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%2FJGB2StgfJKFFGqE0agGA%2Fimage.png?alt=media\&token=9018007f-a91e-4542-9a68-e22132fe2a65)
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%2FyReSN1SPjhCIc3nS2Sd8%2FScripted%20REST%20ss%20name%20field.png?alt=media\&token=2fb5d442-aeb2-4241-bfa7-a86d3dfc5f48)
   * **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%2Fwj71HS3SgmHcqxbUpMkG%2Fservicenow%20authentication.png?alt=media\&token=bf1bfc7c-1790-41c2-ac20-83ab97c6ca3b)
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 Panther Console, navigate to **Configure > Alert Destinations.**
2. Click **+Add your first Destination**.&#x20;
   * If you have already created Destinations, click **Create New** in the upper right side of the page to add a new Destination.
3. 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://yourdomain.service-now.com/<base_api_path>`&#x20;
     * This domain is shown in the "Rest API" section of your ServiceNow console.
   * **Severity**: Select the severity level of alerts to send to this Destination.&#x20;
   * **Alert Types**: Select the alert types to send to this Destination.&#x20;
   * **Log Type**: 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.\
     ![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%2FmD01HuNpwcnbnQXpyVps%2Fcustom%20webook%20destinations.png?alt=media\&token=b7ee3c3f-d44c-4f4c-955f-2ba50c31dbd0)
4. Click **Add Destination**.
5. Click **Send Test Alert** to make sure everything works correctly.
   * A test event should now exist in your ServiceNow Incidents table.\
     &#x20;![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%2FkqOIh6zxph47PU9lKVjZ%2Ftest%20event%20in%20ServiceNow.png?alt=media\&token=d21fb45f-abd6-4d39-a917-c379de8ab7e0)
6. 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%2FCCsuuq6nUnoem41BZ8Tl%2Fimage.png?alt=media&#x26;token=ede9720d-c561-465c-a4ae-a04b6596c9b9" alt="The Incident Table in ServiceNow contains a test alert."><figcaption></figcaption></figure>
