> For the complete documentation index, see [llms.txt](https://docs.onum.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.onum.com/listeners/listener-integrations/pull-data-from-http-endpoints/pull-data-from-the-servicenow-api.md).

# Pull data from the ServiceNow API

## Overview

Get a list of Salesforce query events through the [Salesforce API](https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/intro_rest.htm) using the **HTTP Pull** Listener.

## HTTP Pull Listener configuration

In Falcon Onum, go to the **Listeners** area and click **New Listener > HTTP Pull**. Give a name to your new Listener and enter the following data:

### Parameters

Add the following parameter:

* **Name** - `instanceUrl`
* **Value** - Enter your Salesforce instance URL.
* **Name** - `apiVersion`
* **Value** - Enter your Salesforce API version.

### Secrets

You must define these credentials in Onum:

* `clientId` will reference your Salesforce client ID.
* `clientSecret` will reference your Salesforce client secret.
* `username` will reference your Salesforce username.
* `password` will reference your Salesforce password.

To do it, click **Add element** and enter a **Name** for the secret (in this case, `clientId`). Then, click the **Value** field and select **New secret** to create a new one:

* Give the secret a **Name**.
* Turn off the **Expiration date** option.
* Click **Add new value** and paste the secret corresponding to the value.
* Click **Save**.

You can now select the secret you just created in the **Value** field list. Repeat the process for the rest of secrets.

{% hint style="info" %}
Learn more about secrets in Onum in [this article](/settings/organization-settings/secrets-management.md).
{% endhint %}

### Setup

After entering the required parameters and secrets, you can choose to manually enter the rest of configuration fields, or simply paste the given YAML:

{% tabs %}
{% tab title="Config as YAML" %}
Toggle **ON** the **Config as YAML** option to enable a free text field where you can paste the following YAML:

```yaml
withTemporalWindow: true
temporalWindow:
  duration: 5m
  offset: 5m
  tz: UTC
  format: RFC3339
withAuthentication: true
authentication:
  type: "token"
  token:
    request:
      method: "POST"
      url: "${parameters.instanceUrl}/services/oauth2/token"
      bodyType: "urlEncoded"
      bodyParams:
        - name: "grant_type"
          value: "password"
        - name: "client_id"
          value: "${secrets.clientId}"
        - name: "client_secret"
          value: "${secrets.clientSecret}"
        - name: "username"
          value: "${secrets.username}"
        - name: "password"
          value: "${secrets.password}"
      headers:
        - name: "Content-Type"
          value: "application/x-www-form-urlencoded"
    tokenPath: ".access_token"
    authInjection:
      in: "header"
      name: "Authorization"
      prefix: "Bearer "
withEnumerationPhase: true
enumerationPhase:
  paginationType: cursor
  cursorSelector: ".nextRecordsUrl"
  initialRequest:
    responseType: json
    method: GET
    url: ${parameters.instanceUrl}/services/data/${parameters.apiVersion}/query
    headers:
      - name: Accept
        value: application/json
      - name: Content-Type
        value: application/json
    queryParams:
      - name: "q"
        value: "SELECT Id, EventType, LogDate, CreatedDate FROM EventLogFile WHERE LogDate >= ${temporalWindow.from} AND LogDate < ${temporalWindow.to} ORDER BY LogDate"
  nextRequest:
    responseType: json
    method: GET
    url: ${parameters.instanceUrl}/services/data/${parameters.apiVersion}/query/${pagination.cursor}
    headers:
      - name: Accept
        value: application/json
      - name: Content-Type
        value: application/json
  output:
    select: ".records"
    filter: "."
    map: "."
    outputMode: element
collectionPhase:
  variables:
    - name: "eventLogFileId"
      source: "input"
      expression: ".Id"
    - name: "eventType"
      source: "input"
      expression: ".EventType"
    - name: "logDate"
      source: "input"
      expression: ".LogDate"
  paginationType: none
  request:
    method: "GET"
    url: "${parameters.instanceUrl}/services/data/${parameters.apiVersion}/sobjects/EventLogFile/${inputs.eventLogFileId}/LogFile"
    headers:
      - name: "Accept"
        value: "text/csv"
      - name: "Accept-Encoding"
        value: "gzip"
  output:
    select: "."
    map: "{\"SFDCLogId\": ${inputs.eventLogFileId}, \"SFDCLogType\": ${inputs.eventType}, \"SFDCLogDate\": ${inputs.logDate}, \"content\": .}"
    outputMode: "element"
```

{% endtab %}

{% tab title="Manually configure" %}
**Temporal Window**

Toggle **ON** to add a temporal window for events. This repeatedly shifts the time window over which data is collected.

* **Duration** - `5m`
* **Offset** - `5m`
* **Format** - `RFC3339`

**Authentication**

Toggle **ON** to configure the authentication phase.

* **Type** - `token`
* **Token Retrieve Based Authentication**
  * **Request**&#x20;
    * **Method** - `POST`
    * **URL** - `${parameters.instanceUrl}/services/oauth2/token`
    * **Headers**
      * **Name** - `Content-Type`
      * **Value** - `application/x-www-form-urlencoded`
    * **Body Type** - `urlEncoded`
    * **Body Params**
      * **Name** - `grant_type`
      * **Value** - `password`
      * **Name** - `client_id`
      * **Value** - `${secrets.clientId}`
      * **Name** - `client_secret`
      * **Value** - `${secrets.clientSecret}`
      * **Name** - `username`
      * **Value** - `${secrets.username}`
      * **Name** - `password`
      * **Value** - `${secrets.password}`
* **Token path** - `.access_token`
* **Auth injection**
  * **In** - `header`
  * **Name** - `Authorization`
  * **Prefix** - `'Bearer '`

**Enumeration Phase**

Toggle **ON** and configure the following:

* **Pagination Type** - `Cursor`
* **Cursor Selector** - `.nextRecordsUrl`
* **Initial Request**
  * **Response Type** - `JSON`
  * **Method** - `GET`
  * **URL** - `${parameters.instanceUrl}/services/data/${parameters.apiVersion}/query`
  * **Headers**
    * **Name** - `Accept`
    * **Value** - `application/json`
    * **Name** - `Content-Type`
    * **Value** - `application/json`
  * **Query Params**
    * **Name** - `q`
    * **Value** - `SELECT Id, EventType, LogDate, CreatedDate FROM EventLogFile WHERE LogDate >= ${temporalWindow.from} AND LogDate < ${temporalWindow.to} ORDER BY LogDate`
* **Next Request**
  * **Response Type** - `JSON`
  * **Method** - `GET`
  * **URL** - `${parameters.instanceUrl}/services/data/${parameters.apiVersion}/query/${pagination.cursor}`
  * **Headers**
    * **Name** - `Accept`
    * **Value** - `application/json`
    * **Name** - `Content-Type`
    * **Value** - `application/json`
* **Output**
  * **Select** - `.records`
  * **Filter** - `.`
  * **Map** - `.`
  * **Output Mode** - `element`

**Collection Phase**

* **Inputs**&#x20;
  * **Name** - `eventLogFileId`
  * **Expression** - `.Id`
  * **Name** - `eventType`
  * **Expression** - `.EventType`
  * **Name** - `logDate`
  * **Expression** - `.LogDate`
* **Pagination Type** - `None`
* **Request**&#x20;
  * **Response Type** - `JSON`
  * **Method** - `GET`
  * **URL** - `${parameters.instanceUrl}/services/data/${parameters.apiVersion}/sobjects/EventLogFile/${inputs.eventLogFileId}/LogFile`
* **Headers**
  * **Name** - `Accept`
  * **Value** - `text/csv`
  * **Name** - `Accept-Encoding`
  * **Value** - `gzip`
* **Output**&#x20;
  * **Select** - `.`
  * **Map** - `{"SFDCLogId": ${inputs.eventLogFileId}, "SFDCLogType": ${inputs.eventType}, "SFDCLogDate": ${inputs.logDate}, "content": .}`
  * **Output Mode** - `element`
    {% endtab %}
    {% endtabs %}

When you're done, click **Create labels** to move on to the next step and define the required [Labels](https://app.gitbook.com/o/9sm794iTBacZSmhxRER6/s/kxZeV4nlXcIAjMGZxzLI/the-workspace/listeners/labels) if needed.
