Links

Integrate embedded tracks on your website

You can take embedding one step further by deeply integrating embedded track on your website or third-party system like an LMS. This allows you to offer a more tailored, optimised learning experience.
  • Embed custom parameters Which enables you to send custom parameters to embedded tracks. For example, the learner's user id in an LMS.
  • Embed event callbacks Which enables you to receive event information from embedded tracks. For example, a track completed event to store the learner's progress in an LMS.
  • Learning Tools Interoperability (LTI) Which enables you to integrate embedded content using LTI.

Embed custom parameters

When you need to integrate an embedded track with a third-party system, it is essential to understand in what context certain events occur. Suppose a learner is playing a track embedded inside your LMS, and you need to match an Instruqt event to the learner inside your LMS. Such as notifying the learner that he skipped a challenge, which influences his scoring rate.
You can send custom parameters to an embedded track to achieve such integrations. Custom parameters are similar to UTM parameters in analytics tools. And they give extra contextual information about the current play. For example, the current user inside your LMS or the origin of this specific track play.
You pass custom parameters at the end of the URL for embedded tracks. Any parameters prefixed with icp_ will be stored with the learner's track play and propagated to webhook events related to that track play. The custom parameters are also reported for each play in the Plays report.
The following example sets the custom parameter called user_id to the value cool101:
https://play.instruqt.com/embed/TEAM/tracks/EXAMPLE?token=TOKEN&icp_user_id=cool101
Multiple parameters can be specified by separating them with an & symbol:
https://play.instruqt.com/embed/TEAM/tracks/EXAMPLE?token=TOKEN&icp_user_id=cool101&icp_campaign=campaignA

Check the custom parameters through webhooks events

Instruqt propagates custom parameters to Webhook events. Subsequently, this example propagates the user_id parameter. To check this out, elaborate on the Webhooks Zapier example:
Zapier
  1. 1.
    Open your Zap in Zapier.
  2. 2.
    Click Edit on your Catch Hook trigger.
  3. 3.
    To expand the Setup trigger, click the
    expander arrow.
  4. 4.
    Click Refresh fields.
  5. 5.
    To expand the Test trigger, click the
    expander arrow.
  6. 6.
    Select the latest request from the Request list. Click Load More if necessary. ↳ Zapier shows the lastest received event data, which contains: custom_parameters: ** `user_id:`**`USER_ID`\USER_ID will contain your user id.

Embed event callbacks

Instruqt sends back events to the parent web page when embedding a track. Instruqt uses the Window.postMessage() API to send these events. You can use these events to store a learner's progress or trigger other events or behaviors in your systems.

Events

Instruqt sends the following events for each track play:
Event Name
Description
track.started
A learner starts a track (clicks "Launch")
track.ready
The track's sandbox is ready to start (loading completed)
track.challenge_started
A learner starts a challenge
track.challenge_skipped
A learner skipped a challenge
track.challenge_completed
A learner or the platform stopped a track
track.completed
A learner completes a track

Event payload

The event data that Instruqt sends is formatted in JSON and called the payload. This is an example of the track.challenge_started event payload:
JSON
{
"event": "track.challenge_started",
"params": {
"track_slug": "getting-started-with-instruqt",
"challenge_slug": "your-first-challenge"
}
}
All event payloads contain the following parts:
  • the event name/value pair
  • the params object with:
    • the track_slug name/value pair
    • the optional challenge_slug name/value pair for all the track.challenge_* event payloads
    • the optional total_challenges name/value pair for the track.started, track.completed and track.challenge_completed events.
    • the optional team_name name/value pair for the track.sandbox_ready event.

Parsing embed event payloads

To receive events payloads, you will need to add an event listener to the web page that has the Instruqt embed. Here is a code snippet of how you might do this:
JavaScript
window.addEventListener("message", (event) => {
// Check the event is from Instruqt
if (event.origin !== "https://play.instruqt.com") {
return;
}
// Event payload is available in event.data
console.log(
"Received event:", event.data.event,
"with params:", event.data.params)
}, false);
This event listener writes received event data to the browser console.

Example: using embed events to notify users their track is ready to play

Waiting for a cold-started track to load can be a frustrating experience for your users, potentially leading them to drop off before fully engaging with your track. While the Hot Start feature can help alleviate this issue, it may not always be a feasible solution.
To keep users engaged when your track is loading, even after switching to another tab or window, browser notifications can be leveraged to inform them that their track is ready to play. In the below example, we will demonstrate how embed events can be used to effectively do this for embedded tracks (tracks shared through invite links already have this feature enabled).
See it in action
  1. 1.
    When the user launches an embedded track, notification permission is requested:
  2. 2.
    Once the track is done loading, a browser notification is sent, and the page title is prepended with 🟢 to indicate the lab is ready.
    Clicking the notification will return the user to the embedded track.
    Note: Focusing the lab will dismiss the notification and clear the status icon in the page title.
HTML/JavaScript
1
<!DOCTYPE html>
2
<html lang="en">
3
<body>
4
<iframe
5
width="840"
6
height="540"
7
sandbox="allow-forms allow-modals allow-popups allow-same-origin allow-scripts"
8
src="https://play.instruqt.com/embed/TEAMSLUG/tracks/TRACKSLUG?token=em_XXXXXXXXXX"
9
style="border: 0"
10
allowfullscreen
11
></iframe>
12
13
<script>
14
// This event listener triggers the request to allow notifications.
15
window.addEventListener("message", ({ data: { event }, origin }) => {
16
// List for track started, first check if the event is from Instruqt
17
// Request permissions 1 second after embedded track is launched by user
18
if (origin.includes("PLAY.instruqt.") && event == "track.started") {
19
window.setTimeout(() => Notification.requestPermission(), 1000);
20
}
21
});
22
23
// This event listener generates and dispatches the notification once the lab is ready to start, not in focus and permission has been granted.
24
window.addEventListener("message", ({ data: { event, params } }) => {
25
// Generate and dispatch notification once track is ready to start and not in focus
26
if (
27
!origin.includes("play.instruqt.com") ||
28
Notification.permission !== "granted" ||
29
document.hasFocus()
30
) {
31
return;
32
}
33
34
if (origin.includes("play.instruqt.com") && event == "track.ready") {
35
const { track_slug, team_name } = params;
36
37
const notification = new Notification(
38
`🟢 Your lab from ${team_name} is ready to start`,
39
{ body: "Click here to return" }
40
);
41
42
notification.addEventListener("click", () => {
43
window.parent.focus();
44
document.body
45
.querySelector(`iframe[src*="${track_slug}"]`)
46
?.scrollIntoView({ behavior: "smooth" });
47
48
notification.close();
49
});
50
51
window.addEventListener("focus", () => notification.close());
52
}
53
});
54
55
56
// This event listener updates the page title once the lab is ready to start and not in focus
57
window.addEventListener("message", ({ data: { event, params } }) => {
58
const notification = "🟢 ";
59
60
function updateTitle() {
61
document.title = notification + document.title;
62
}
63
64
function resetTitle() {
65
document.title = document.title.replace(notification, "");
66
}
67
68
if (
69
origin.includes("play.instruqt.com") &&
70
event === "track.ready" &&
71
!document.hasFocus()
72
) {
73
updateTitle();
74
}
75
76
window.addEventListener("focus", () => resetTitle());
77
});
78
</script>
79
</body>
80
</html>
⇨ Note: replace the embed <iframe/> snippet with an embed snippet for one of your tracks.