Skip to main content

Plugin Overview

All Watching That plugins consist of a few core libraries built to gather data from the environment and send that data to our ingesting endpoint (the collector). Most of the data is gathered by listening to player events but some of the data may also be retrieved directly from the browser environment where needed. For some players no other 3rd party plugins are needed (Brightcove and JW players), for others we might need extra plugins to help forward ad events on the player (VideoJS).

Get Started

Briefly, the steps to get a plugin running are:

  1. load the plugin from our cdn. Typically, you do this with a <script src="..."></script> tag somewhere in your html code but, of course, any other way of loading a remote script is fine. Note that for the Brightcove player this step is not needed as it pre-bundles it with the player.
  2. start the plugin. You do this by calling the wtAdTracer function with some options detailed below.

Consult the individual plugin pages for specific setup details.

Configuration Options

Whenever you call the wtAdTracer function to start the plugin, you must pass it some options. At the very least you must pass apiKey which identifies your plugin in our system. You can retrieve the api key from the Watching That app > My Account > Settings > Player plugin setup page or from your Watching That rep.

OptionRequiredDescription
apiKeyyesRequired identifier for your plugin
debugSet to true to enable debug logs for everyone. Set this just in testing environments where you want to test your custom fields/events. Also, see below for a browser-by-browser alternative.
sendAllCustomSet to true to send your custom data with every event. By default, when this is not set, static fields are sent only with the init event while function fields are sent with all.
sendDebugSet to true to send debug information to our servers. Normally you should only set this option when instructed to do so by Watching That and only for brief periods of time. Debug info can be quite verbose and it will generate a lot of traffic with our servers which might badly affect the user experience

If you want to enable debug logs just for your browser, so you can test your custom fields without affecting anyone else then a better alternative to setting the debug option above is to enter localStorage.setItem('wtDebug', 1) in the browser's devtools console and refresh the page. To stop debug logs for showing enter localStorage.removeItem('wtDebug').

Example start with all options:

  wtAdTracer({
apiKey: '12345',
debug: true,
sendAllCustom: true,
sendDebug: true
})

Custom Events and Data

Our plugins are configured to send a set list of fields and player events to our collector. We review and update this list on a regular basis but in case you want to send some data we don't currently support then you have a great way of doing this yourself.

All our plugins check for the presence of a special object defined on the window: window.wtatCustom.

The general structure of this object is

<script>
window.wtatCustom = {
fields: {
field1: value1,
field2: value2,
...
},
events: {
event1: eventData1,
event2: eventData2,
...
},
ignoredEvents: [...]
};
</script>
note

It is important for this object to be defined before the player is ready, otherwise our plugin might not see it and it might not send your custom data with some early events.

Data Fields

The window.wtatCustom.fields object allows you to send custom data together with the data our plugins send by default. For example, to send a field userCity, you'd do:

window.wtatCustom = {
fields: {
userCity: 'London',
},
};

You can send any number of fields this way:

window.wtatCustom = {
fields: {
userCity: 'London',
source: 'direct',
preferredColor: 'blue',
isHappy: true,
},
};

Apart from static fields like above, you can also define a field as a function:

window.wtatCustom = {
fields: {
mySite: () => {
return document.location.host;
},
},
};

In the example above mySite would be set to the value of document.location.host.

caution

Make sure you always return a value from your functions otherwise the field will not be sent.

Functions are run everytime new data is prepared to be sent to our servers so heavy functions might badly affect the user experience on your page. Make sure you cache this sort of functions or replace them with static fields where possible. The above example can be rewritten in a more efficient way like this:

const host = document.location.host;

window.wtatCustom = {
fields: {
mySite: host,
},
};

Functions receive a parameter consisting of all the data prepared to be sent so far, including the "official" data collected by us.

window.wtatCustom = {
fields: {
mySite: (dataSoFar) => {
if (dataSoFar.type === 'init') {
return document.location.host;
}
},
},
};

In the example above the mySite field is sent only when the event type is init.

To avoid sending the same data multiple times to our servers, static fields are only being sent with the first event of a session (init). Function fields, on the other hand, are evaluated and sent with all events. We assume that, being a function, its output might change over time or based on the parameters it receives. As noted above, if you're always sending the same data, it's better to send it as a static field.

If you want to send all your custom fields with all events you can set the sendAllCustom plugin option to true when you initialise the plugin. For the exact setup see the individual plugin documentation.

caution

Please let us know the exact list of custom fields you're capturing so that we can expose these fields in our application UI.

Events

Apart from custom data fields you can also send other player events we're not already capturing. Consult your player documentation for the list of events it exposes.

The easiest way to send extra events is to set the window.wtatCustom.events object like this:

window.wtatCustom = {
events: {
play: true,
loadedmetadata: true,
},
};

This will listen for the play and loadedmetadata events on the player and send them to our collector endpoint along with the required data and your custom fields every time the player triggers these 2 events.

If, for some reason, you don't want to send the type as the event name then you can do

window.wtatCustom = {
events: {
play: { type: 'jw:play' },
loadedmetadata: { type: 'my-custom-event' },
},
};

The type field is mandatory as it identifies the event type in our data. Failing to set it will prevent the event from being sent to our collector.

window.wtatCustom = {
events: {
play: { type: 'jw:play' }, // ✅ correct
loadedmetadata: { someOtherField: 'bar' }, // ❌ incorrect, will not be sent
},
};

Finally, if you need to calculate some fields or decide whether to send the event or not with a more complex logic, then you can use a function for the value of the event. The function must return an object with at least the type field set. Note that functions receive the player event as a parameter:

window.wtatCustom = {
events: {
time: (e) => {
if (e.position % 5 === 0) {
return { type: 'keepalive', custom: { position: e.position } };
}
},
},
};

This will send the time event every 5 seconds for the duration of the video along with the position of the player.

caution

It is important you send extra fields as part of the custom field as in the example above, otherwise your field might not be included in the sent data.

Ignored Events

The plugin captures and sends all the relevant events it receives. However, in rare situations you might not want certain events to be captured. window.wtatCustom.ignoredEvents offers you a way to do this.

In contrast to the other keys of the wtatCustom object, ignoredEvents is an array. Every item in the array must be an object with field names as keys and possible values for those fields as values.

For example, if you want to ignore (discard, really) all INVALID_ASSET_CUSTOM_ID error events you can do so:

window.wtatCustom = {
ignoredEvents: [
{ type: 'error', err: 'INVALID_ASSET_CUSTOM_ID' }
]
}

This will run a filter against the events and whenever it finds one having type set to error and err set to INVALID_ASSET_CUSTOM_ID it simply ignores it as if it was never triggered.

To specify several events to be ignored, each with its own filtering criteria, you can add multiple items to the array:

window.wtatCustom = {
ignoredEvents: [
{ type: 'error', err: 'INVALID_ASSET_CUSTOM_ID' },
{ playerId: 'foo', idx: 1, per: 50 },
...
]
}

You can also ignore events based on the custom fields you set. For this you need to prefix your custom field with custom. (so if you have a custom field named foo then you'd match it with custom.foo):

window.wtatCustom = {
ignoredEvents: [
{ type: 'error', 'custom.foo': 'some value' },
]
}
caution

Take great care not to ignore important events by setting your filtering criteria too broad. ignoredEvents lets you ignore any event, even the ones that are crucial for the correct functioning of our application.