> For the complete documentation index, see [llms.txt](https://algolytics-technologies.gitbook.io/algolytics/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://algolytics-technologies.gitbook.io/algolytics/scoring.one-platform/tutorials/sce-tracking-script.md).

# SCE Tracking Script

To start tracking users of a website or mobile app, you need to install a tracking script in one of the technologies mentioned below:

* iOS: <https://github.com/Algolytics/ios-tracking>
* Android: <https://github.com/Algolytics/android-tracking>
* WWW: see details below

## Installation on WWW <a href="#installation" id="installation"></a>

Fill places marked with comments and add our `script` to `<head>` tag of all of your views.

```javascript
<script>
  (function(baseUrl, apiKey, sid, options) {
    var options = options || { debug: false, attachEvents: [], ignoreTypeAttributes: [], ignoreNameAttributes: [] };
    window.sce = {
      CODES_V: "0.4",
      writeKey: apiKey,
      baseUrl: baseUrl,
      sid: sid,
      buffer: [],
      ignoreTypeAttributes: options.ignoreTypeAttributes,
      ignoreNameAttributes: options.ignoreNameAttributes,
      debug: options.debug,
      attachEvents: options.attachEvents,
      permissionCookieName: "accept",
      event: function(eventType, args) {
          if (sce.sendData) {
              sce.sendData(eventType, args, null, "SCENARIO_NAME");
          } else {
              sce.buffer.push([
                  1 * new Date(),
                  eventType,
                  args
              ]);
          }
      }
    };
    var sceScript = document.createElement("script");
    sceScript.type = "text/javascript";
    sceScript.async = true;
    sceScript.src = baseUrl + 'scripts/sendData.min.js';
    var otherScriptTag = document.getElementsByTagName("script")[0];
    otherScriptTag.parentNode.insertBefore(sceScript, otherScriptTag);
  })("APP_BASE_URL", "APP_TOKEN", "sid", { debug: false, attachEvents: [ "optionalEvent" ], ignoreTypeAttributes: ["password"], ignoreNameAttributes:["optionalIgnoredAttributeName"] }); // change url to sce url, add api key, customer id and options
</script>
```

#### Parameters <a href="#parameters" id="parameters"></a>

* SCENARIO\_NAME - name of scenario you want to use or empty if you want to use scenario www\_events
* APP\_BASE\_URL - application base url, e.g. <http://localhost:9002/>
* APP\_TOKEN - application authentication token

### Tracking permission <a href="#tracking-permission" id="tracking-permission"></a>

By default our script doesn't start working unless tracking permission is granted, e.g.:

```html
<button onclick="sce.grantTrackingPermission()" type="button">Accept tracking</button>
```

### Use <a href="#use" id="use"></a>

Our script gathers information about following events automatically:

* time spent on page (sent in intervals(0, 5, 30, 60, 300, 900(seconds)) and with every event
* page view,
* scroll value,
* mouse move (it sends cursor position with 0,5s interval) - optional (you can turn it on adding key/value pair - attachEvents: \[ "mousePosition" ] to options object in our script),
* click(on button or link),
* input values after every character provided,
* text pasted to input,
* select change,
* radio change,
* checkbox check,
* input characters count

To send your own event you can use `sce.event()` function:

```javascript
sce.event("eventCategory", {
  eventLabel: [eventLabel],
  eventValue: [eventValue]
});
```

First argument is the name of the table in which the information will be stored. That is why the object which is being sent should have the same properties for equal first arguments of function event. For example:

```javascript
sce.event("Input_click", {
  id: event.target.id,
  name: event.target.name,
  value: event.target.value
});
```

#### Variables <a href="#variables" id="variables"></a>

Computed variables to use in your app:

| Variable                   | Type    | Description                            | Example                         |
| -------------------------- | ------- | -------------------------------------- | ------------------------------- |
| sce.pageHeight             | integer | height of a page (in pixels)           | 1500                            |
| sce.maxScrollY             | integer | height of a page reached by user       | 890                             |
| sce.timeSpentOnPage        | integer | time spent on a page (in seconds)      | 30                              |
| sce.currentCursorPostition | object  | current position of a cursor (pixels)  | { x: 358, y: 781 }              |
| sce.inputCharacters        | object  | number of characters provided on input | { firstName : 5, lastName: 10 } |

### Ignoring attributes from being tracked <a href="#ignoring-attributes-from-being-tracked" id="ignoring-attributes-from-being-tracked"></a>

By default inputs with 'password' attribute type are not tracked.\
Other attribute types can also be ignored by specifying them in the script settings:

```
ignoreTypeAttributes: ["password", "text"]
```

Elements can also be ignored by their name:

```
ignoreNameAttributes:["optionalIgnoredAttributeName"]
```

### Examples of use <a href="#examples-of-use" id="examples-of-use"></a>

#### Input edition <a href="#input-edition" id="input-edition"></a>

Add event listener to send information about input after edition:

```html
<input 
    type="text"
    name="FirstName"
    onFocusOut="sce.event(
        'Inputs', {
            action: "input_edition",
            id: event.target.id,
            name: event.target.name,
            value: event.target.value,
            enteredCharacters: sce.inputCharacters[event.target.id]
        }
    )"
>
```

OR

```javascript
window.addEventListener("focusout", event => {
  if (event.target.tagName === "INPUT") {
    sce.event("input_edition", {
      id: event.target.id,
      name: event.target.name,
      value: event.target.value,
      enteredCharacters: sce.inputCharacters[event.target.id]
    });
  }
});
```

#### Clicks <a href="#clicks" id="clicks"></a>

Given:

```html
<a id="googleLink" href="http://google.com">Go to google!!!</a>
```

To send information about link that user clicked you can add `onClick` attribute to `<a>` tag:

```html
<a id="googleLink" href="http://google.com" onClick="sce.event("link_click", {
    linkId: event.target.id,
    linkName: event.target.innerHTML
    href: event.target.href
  });">
    Go to google!!!
</a>
```

OR Add event listener to your script:

```javascript
window.addEventListener("click", event => {
    if (event.target.tagName === "A") {
      sce.event("link_click", {
        linkId: event.target.id,
        linkName: event.target.innerHTML
        href: event.target.href
      });
    }
});
```

#### Time spent on page and page view <a href="#time-spent-on-page-and-page-view" id="time-spent-on-page-and-page-view"></a>

```javascript
let intervals = [0, 5000, 30000, 60000, 300000, 900000];
window.addEventListener("load", function() {
  intervals.forEach(function(interval) {
    const sendTime = setTimeout(
      () =>
        sce.event("time_spent_on_page", {
          value: sce.timeSpentOnPage
        }),
      interval
    );
  });
  sce.event("page_view", { value: window.location.href });
});
```

#### Scroll <a href="#scroll" id="scroll"></a>

```javascript
window.addEventListener("scroll", event => {
  window.clearTimeout(sendScrollEvent);
  sendScrollEvent = setTimeout(function() {
    sce.event("scroll", {
      scroll_position_Y: sce.maxScrollY,
      scroll_position_Y_max: sce.pageHeight
    });
  }, 1000);
});
```

## Processing evnts and storing in RDBMS

Events generated on a web page or a mobile app can be transmitted by an event queue system to a scenario, which further processes them and sends to a database. Here is an example code:

&#x20;

```groovy
import com.rabbitmq.client.*
import groovy.json.JsonOutput

boolean isCollection(object) {
  [Collection, Object[], LinkedHashMap.class].any {
    it.isAssignableFrom(object.getClass())
  }
}
data1 = [: ]
table_name = 'all_events'
//------------------------------------------
additional_prefix = "ext_"
additional_name = "__additional"
event_type_name = 'eventType'
timestamp_name = 'ext_received_dt'

data1.put(timestamp_name, new Date().getTime())

__variables.each {
  key,
  value ->

  if (key != additional_name) {
    if (isCollection(value)) {
      data1.put(key, JsonOutput.toJson(value))
    } else {
      data1.put(key, value)
    }
  }
}
if (__variables.__additional) {
  __variables.__additional.each {
    key,
    value ->
    if (isCollection(value)) {
      data1.put(additional_prefix + key, JsonOutput.toJson(value))
    } else {
      data1.put(additional_prefix + key, value)
    }
  }
}
//table_name - removing all non alphanumeric chars except _
if (__variables.containsKey(event_type_name)) {
  tmp_tbl_name = __variables.get(event_type_name)
  if (tmp_tbl_name != null && tmp_tbl_name != '') {
    tmp_tbl_name = tmp_tbl_name.replaceAll("[\\W]", "").toLowerCase().take(64)
    if (tmp_tbl_name != '') {
      table_name = tmp_tbl_name
    }
  }
}
//all events not present in the list of allowed event types are send to all_events table
//-------------------------------------------
chName = „xxx.tracking„ //channel defined by the administrator of the system

amqpManager.checkConnection()
if (!amqpManager.channelExists(chName)) {
  amqpManager.createChannel(chName)
}

def req = [table: table_name, schema: "tracking", data: data1]
amqpManager.publish(chName, JsonOutput.toJson(req))

```
