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:
- 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. - 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.
Option | Required | Description |
---|---|---|
apiKey | yes | Required identifier for your plugin |
debug | Set 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. | |
sendAllCustom | Set 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. | |
sendDebug | Set 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>
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
.
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.
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.
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' },
]
}
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.