Live notifications¶
About¶
This is for developers who wish to integrate systems with OpenTrack - in particular, streaming companies wanting to build live results displays.
Our system can emit push notifications to help keep web pages and other downstream systems up to date. We've used this to build our TV Console (below), and to keep our race results and field events web pages up to date when new data arrives.
The TV console is a premium feature, requiring a special agreement with us.
Usage¶
The competition must have push notifications turned on (Manage | Push Notifications).
To subscribe to receive these, Read the docs on Pusher here. These docs are for JavaScript, but you can subscribe in other languages to update a local database.
You need a key to receive events. This is public information, but we might have to change it from time to time, so check this page each season. In development, you'll probably want to listen to our test server, so you can fake some results or field attempts and see throws coming through.
LIVE key: 2b94ba526eda8332e32a
TEST key: 62fbd6418ed94ae09473
APP_CLUSTER: eu
In brief your JavaScript page will be initialised like this:
<script src="https://js.pusher.com/7.0.3/pusher.min.js"></script>
var pusher = new Pusher("APP_KEY", {
cluster: "APP_CLUSTER",
});
Each competition has channels you can subscribe to. They are all prefixed with a slightly transformed
version of the competition's relative URL. Remove everything before x
, and replace slashes with underscores, because pusher channels are not allowed to contain slashes. The most important channel is the overview, which will receive competition level messages. This has the suffix -overview
added to the pchannel prefix
For example:
URL: https://data.opentrack.run/en-gb/x/2021/GBR/varsity-athletics/
Channel root: x-2021-GBR-varsity-athletics
Overview channel: x-2021-GBR-varsity-athletics-overview
https://data.opentrack.run/en-gb/x/2021/GBR/varsity-athletics/
, you would subscribe to x-2021-GBR-varsity-athletics-overview
like this:
var channel = pusher.subscribe("x-2021-GBR-varsity-athletics-overview");
Then, when results go up (e.g. a heat or race is saved, or someone jumps or throws and we are recording throw-by-throw), you will receive an instant message on the channel.
Available event types¶
So far we have only implemented two message types at overview level, because you can fetch almost everything else by making a GET request.
Results first published: results_arrived event¶
We emit the results_arrived message when the results_status of a unit progresses from being empty, seeded or in_progress to being in a provisional_results
or official_results
status. You will want
to bind a function to it like this after selecting the competition:
channel.bind("results_arrived", (data) => {
// Method to be dispatched on trigger.
});
Event: "results_arrived"
Example payload:
{
"event_id": "12",
"round_no": 1,
"heat_no": 1,
"heat_name": "12 800m - Men Blues",
"winner_performance": "1:52.60",
"winner_name": "Harry Cox"
}
This should be enough information to flash up the winner's detail on a web page. If you want more information, you can make a quick GET request to get the full details of the race, which is event 12 round 1 heat 1, like this:
GET https://data.opentrack.run/en-gb/x/2021/GBR/varsity-athletics/event/12/1/1/json/
Latest field event: latest_attempt event¶
Bind a function to the latest_attempt event to receive a callback whenever a throw or jump is recorded, with code like this:
channel.bind("latest_attempt", (data) => {
// Method to be dispatched on trigger.
});
event_code
value within the payload and check for HJ
or PV
and display as appropriate; these are the only two types of vertical events in normal athletics.
The first example shows an athlete taking the lead in round 6 of a Hammer competition, the second in a High Jump.
Be careful - round_no
identified the stage of competition, such as heats/semis/finals, and for field events is almost always 1; you will use this to get the URL of the specific unit for more information, in a generic way. round
is whether it's their first, second, or fifth throw and is specific to field events
Event: "latest_attempt"
Example payload for horizontal jumps and throws:
{
"event_id": "01",
"round_no": 1,
"heat_no": 1,
"heat_name": "01 Hammer - Men",
"event_code": "HT",
"bib": "205",
"round": 6,
"result": "48.67",
"athlete_name": "Robin Croft"
}
Example payload for high jump or pole vault:
{
"event_id": "14",
"round_no": 1,
"heat_no": 1,
"heat_name": "14 High Jump - Men",
"event_code": "HJ",
"bib": "112",
"height": "1.85",
"attempts_at_height": "xo",
"result": "o",
"athlete_name": "Maranga Mokaya"
}
The unit
event and Channel¶
Every unit within the competition has its own channel, which receives a complete copy of the unit's data every time it is saved. We've had this since 2017. It allows you to build a web page or display following that particular race or field event. This is how our own web pages work, automatically changing from Start List to Results when the times are input, and displaying new field events without the user needed to refresh the page.
If building a streaming application which displays brief popups, you generally won't need to subscribe to this one. The first two events will tell you when something is new, and you can then fetch the information with a GET request.
//subscribe to mens high jump in above match
var channel = pusher.subscribe("x-2021-GBR-varsity-athletics-overview-14-1-1");
channel.bind("unit", (data) => {
// Method to be dispatched on trigger.
});
This will give you the same JSON as a get request to https://data.opentrack.run/en-gb/x/2021/GBR/varsity-athletics/event/14/1/1/json/
Tips on testing¶
We'd like to know who is using this feature, and we can arrange to be online helping you with fake results
as you connect up. Please do contact us before working with this.
You will want to obtain competition director rights on a competition of your own. This could either be a demo event on the live server, or a real one on the test server where you manipulate results after a race.
You need to edit your event back into an in_progress
state, then manipulate results, to see events generated.