API Reference

List of functions and variables exposed by the Stagecast object, the entry point to the MDK library.

Introduction

The Stagecast object is the entry point to the library and comes with some getter function that allows to access the context data. The context data is grouped in the general section, the network requests are in the connection object.

General Getters

Your HTML-based application will get its running context from the Moment. The moment is derived from a MomentClass which belongs to a specific Event.

getEventId(): string

const eventId = SDK.getEventId();
console.log(eventId); // prints "1234-5678-90123-4567"

Returns the current event id. The id is a UUIDv4.

getUserId(): string

const userEmail = SDK.getUserId();
console.log(userEmail); // prints "user@stagecast.io"

Returns the User identification which most of the times is the email.

getMomentId(): string

const momentId = SDK.getMomentId();
console.log(momentId); // prints "12345-45677-ABCDE-12345"

Returns the Moment id as a string. The id is a UUIDv4.

getMomentClassId(): string

const momentClassId = SDK.getMomentClassId();
console.log(momentClassId); // prints "12345-45677-ABCDE-12345"

Returns the MomentClass id. The id is a UUIDv4.

isActive(): boolean

Tells whether the Moment is active or not, ie. whether the moment has been stopped by the event organizer from the launchpad. It can be used to render different views, for example:

if (SDK.isActive()) {
renderMainPage();
} else {
renderOtherPage();
}

Often, this is used to display the moment results. An example could be a poll: as long as isActive() returns true the user can express a vote. When the moment stops and isActive() return false, the application could display the poll results or just the user vote.

getCoordinates(): [lat, long]

This function returns the user coordinates as an array of string where the first entry is the latitude and the second is the longitude. The coordinates can be used to activate some functionality depending on the user's location.

In case the wrapper mobile app, or the wrapper website can't get this values, the default ['0', '0'] is returned.

The connection object

The connection object groups all wrappers to the HTTP requests and Websocket connections. These functions allow to retrieve and manipulate the entities described in the Concepts section.

getMoment(): Promise<Moment>

Code
Return
Code
SDK
.connection
.getMoment()
.then(m => console.log(m))
.catch(err => console.error(err));
Return
{
"triggeredBy": "manual",
"owner": "user@email.com",
"name": "<moment_name>",
"eventOwner": "event-organizer@email.com",
"event": "<event_id>",
"created": 1558709687722,
"class": "<moment_class_id>",
"active": true,
"_id": "<moment_id>"
...
}

The _id and the event fields hold, respectively, the Moment id and the Event id. This two ids combined identify the communication channel the moment will use for messages.

The active field tells if the moment is live (it has the same function of isActive(). The created field is a simple timestamp and it's often used to display countdowns and sync multiple devices.

getMomentClass(): Promise<MomentClass>

This function returns a MomentClass object. This utility function allows to get the custom data model defined by the developer and customized by the event organizer in the web platform configuration page.

Code
Second Tab
Code
SDK
.connection
.getMomentClass()
.then(mc => console.log(mc))
.catch(err => console.error(err));
Second Tab
// Prints
{
"name": "<moment_name>",
"message": "",
"event": "<event_id>",
"description": "This is a nice description...",
"custom": {
"foo": 123,
"bar": {}
},
"created": 1556119417107,
"category": "cast",
"_id": "<moment_class_id>"
}

getMomentGlobalState(): Promise<any>

Call this function to fetch the moment global state. Calling this function when the state is not set returns either undefined or triggers a 404 - Not Found . The moments gets filled as the specific user start saving its state. The populated global state has the following structure.

Code
Response
Code
SDK
.connection
.getMomentGlobalState()
.then(state => console.log(state))
.catch(err => console.error(err));
Response
{
"user1@email.com": {
"foo": "value",
"bar": "value",
...
},
"user%20name@email.com": {
"foo": "value",
"bar": "value",
...
},
...
}

The global state is an object where each key is a different user email. The user email holds the specific user state. Please note that, for implementation reasons, some special characters in the email might be replaced with their percent code.

Depending on your implementation, the schema for the user state might differ form user to user. Neither the SDK nor the Backend API enforces any structure, so it's up to the developer to check if the saved state is compliant to the application requirements.

getMomentUserState(uId: string): Promise<any>

Fetches the state of a specific user. This function give you the opportunity to retrieve any user state, unless you specify some security mechanisms.

Code
Response: Example 1
Response: Example 2
Code
SDK
.connection
.getMomentUserState('user@stagecast.io')
.then(state => console.log(state))
.catch(err => console.error(err));
Response: Example 1
// returns any object or value you have specified as
// the user state.
// Voting Moment user state: the vote ids
['option1', 'option2']
Response: Example 2
// Quiz Moment example user state:
{
color: "linear-gradient(90deg, #59C59E 0%, #35BF7F 100%)"
id: "user@stagecast.com"
name: "Tester User"
questionAnswers: [-1, -1, -1]
questionScores: [0, 0, 0]
startTime: 1574844204458
}

If the state is not set yet, the function returns undefined or null or triggers a 404 - Not Found error. Until a patch is published, all of these cases must be verified.

If you don't specify the user id, by default, the function will return the state corresponding to the SDK.getUserId()

There is always a user for each Moment. By joining a Moment via join.stagecast.se, even if you don't insert an email, the backend created an anonymous user.

setMomentUserState(state): Promise<any>

// assuming a generic questionnaire on books
const userState = {
name: 'Alice Tester',
favouriteNumber: 25,
favouriteBooks: [
'Alice in Wonderland',
'A Song Of Ice And Fire',
'The Circle'
],
gender: 'female',
likesToRead: true
}
SDK
.connection
.setMomentUserState(userState)
.then(res => console.log(res))
.catch(err => console.error(err));

Sets the state of the user using authenticated to your HTML-based application. The state can be any javascript object. The MDK serializes the object automatically to JSON.

getUserInfo(): Promise<UserInfo>

Gets the user display information.

Code
Returns
Code
SDK
.connection
.getUserInfo()
.then(info => console.log(info))
.catch(err => console.error(err));
Returns
{
"profile_pic": "AC23305D-E967-4E7C-850F-7F6EC874E066",
"name": "Test User",
"_id": "user@stagecast.io"
}

getUserPicture(): Promise<Blob>

Downloads the content corresponding to the user profile picture in the form of a base64 blob.

Code
Code
SDK
.connection
.getUserProfile()
.then(res => res.toBlob())
.then(content => console.log(content))
.catch(err => console.error(err));

NOTE:

If the user is guest to the event, the profile_pic might not be defined.

getContent(contentId: string, thumb: boolean): Promise<Blob>

Params

  • contentId: the id of the content to be fetched;

  • thumb: if the content should be compressed or full size.

Code
Code
SDK
.connection
.getContent('1234-5678-9012-3456', true)
.then(res => res.toBlob())
.then(content => console.log(content))
.catch(err => console.error(err));

Like getUserPicture(), downloads the content by its id. The returned file is a base64 blob.

fetchContent(contentId: string, thumb: boolean): Promise<Blob>

Params

  • contentId: the id of the content to be fetched;

  • thumb: if the content should be compressed or full size.

Code
Code
SDK
.connection
.fetchContent('1234-5678-9012-3456', false)
.then(res => res.data)
.then(img => {
// this is one approach to display the image in the DOM
let urlCreator = window.URL || window.webkitURL;
// crate a blob image url to be added to an img src attribute
let imageUrl = urlCreator.createObjectURL(res);
});

The returned file is an HttpResponse object bearing a base64 blob.

Notes:

  • The default for thumb is true, therefore the content will be rather small thumbnail. Although sometimes the thumbnail is just enough, png images will present a black background, in that case we suggest to fetch the full-size image.

uploadContent(content: Content): Promise<any>

Params

  • content: the content to be uploaded;

    • file: File

    • type: the content type (eg. image/png)

    • tags: a list of tags to be added to the content

Code
Code
// picture is an image or a document as blob file.
function uploadContent(picture) {
const content = {
file: new File([picture], picture.name),
type: 'image/jpeg',
tags: ['everyone'] // everyone is a special tag that allows the content to be seen by anyone
};
SDK.connection.uploadContent(content)
.then(res => console.log(res)))
.catch(err => console.error(err));
}

The returned file is a base64 blob.

getContentCdnLocation(contentId: string): string

Returns the current CDN content folder location in the following form: https://<host>/api/content

const location = SDK.connection.getContentCdnLocation('1234-5678');
console.log(location);
// prints:
// https://d2cb7i0wbc0znj.cloudfront.net/api/content/1234-5678

NOTE

Please use this function instead of the link printed in the example. The CDN location can change at runtime depending on the environment, or some backend set up.

getCdnHost(): string

Returns the current CDN host in the following form: https://<host>

const location = SDK.connection.getContentCdnHost();
console.log(location);
// prints:
// https://d2cb7i0wbc0znj.cloudfront.net

getHost(): string

Returns the current host in the following form: <host>

const location = SDK.connection.getHost();
console.log(location);
// prints:
// stagecast.se

wsConnect(): Websocket Connection and Messaging

This method is @deprecated and it will be removed in later releases. We recommend using the ws object instead. Old moments that use this method will still function correctly.

wsConnect() creates a websocket connection that can be either authenticated or not. The connection can be seen as a channel that is unique to the Moment and accessible by all the users of that Moment to send/receive messages and sync on topics.

Thanks to the websocket, the developer could, for example, implement Moments based on distributed logics and chats.

Params:

  • onMessage: the message handler function;

  • onError: the error handler function;

  • additional: WsEventHandlers: (optional) additional event handlers:

    • onOpen?: the on connection open callback;

    • onAuth?: the authentication callback;

    • onClose?: the on close connection callback;

  • authenticate: authenticates the user to the websocket (default true).

const onMessage = (data) => console.log(data);
const onError = (err) => console.error(err.message || err);
const onOpen = (data) => console.log('The connection was opened');
const onAuth = (data) => console.log('The user has authenticated');
const onClose = (data) => console.log('Connection closed');
const add = {
onOpen: onOpen.bind(this),
onAuth: onAuth.bind(this),
onClose: onClose.bind(this)
}
const authenticate = true;
SDK.connection.wsConnect(
onMessage.bind(this),
onError.bind(this),
add,
authenticate
);

IMPORTANT NOTES

  • The websocket connection is unique. In the future we might enable more websocket connections at the same time.

  • If one Moment (ie. a user) creates multiple authenticated connection in parallel from the same instance, only the last one will be authenticated. The user can only be authenticated in one single session.

  • If the user needs to receive direct messages, it must be authenticated (set the flag to true)

sendMessageTo(recipient: string, message: any)

This method is @deprecated and it will be removed in later releases. We recommend using the ws object instead. Old moments that use this method will still function correctly.

Params:

  • recipient: a user id (its email)

  • message: any javascript object. (it will be serialized to JSON by the MDK).

This function allows to send a message to an authenticated user over the websocket. Both users must be authenticated. If a uses logs on multiple sessions, only the last one will be valid. This means that if the same user logs into the Mobile page and the Result page at the same time only one will be authenticated.

SDK.connection.sendMessageTo('friend@stagecast.se', {
message: 'Hello Friend, let\'s meet at the bar!'
});

NOTES:

  1. The user must be authenticated to the websocket (ie. have set the authentication param as true in wsConnect())

  2. For now, the function is synchronous, meaning that the MDK doesn't take a callback as an argument. The MDK is being actively developed and future implementations will include this functionality.

send(message: any): boolean

This method is @deprecated and it will be removed in later releases. We recommend using the ws object instead. Old moments that use this method will still function correctly.

This function allows to broadcast a message to all the users connected to the Moment. If you wish to send a private message to a specific user, or to the Result page see sendMessageTo().

SDK.connection.send({
message: [
'Hello Everybody! ',
'Let\'s meet at the bar. ',
'I\'ll offer the first round!'
].join();
});

Params:

  • message: any javascript object. (it will be serialized to JSON by the MDK).

NOTE

For now, the function is synchronous, meaning that the MDK doesn't take a callback as an argument. The MDK is being actively developed and future implementations will include this functionality.

close(): boolean

This method is @deprecated and it will be removed in later releases. We recommend using the ws object instead. Old moments that use this method will still function correctly.

Used to close the websocket connection.

try {
const res = SDK.connection.close();
} catch (err) {
console.error(err.message || err);
}

The bannerInjector object

injectAdvertisementBanner(selectors: string[])

The function injects the credits text and the sponsor logos specified in the Moment Class configuration window in the organizer dashboard.

If your moment doesn't support branding, you will have to specify that in the MANIFEST.json.

Params:

  1. selectors: list of CSS3 selectors in which the advertisement images will be injected.

index.html
main.js
rendered index.html
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Test</title>
</head>
<body>
<div id="sponsorsAnchor1"></div>
</body>
<!-- Js Scripts Import -->
<script src="https://stagecast.se/media/lib/mdk/stagecast.min.js"></script>
<script src="./main.js"></stript>
</html>
main.js
const SDK = new Stagecast();
SDK.onConfigReceived(renderAds.bind(this));
renderAds() {
const res = SDK
.bannerInjector
.injectAdvertisementBanner([
'#sponsorsAnchor1'
]);
console.log(res); // prints: true
}
rendered index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Test</title>
</head>
<body>
<div id="sponsorsAnchor1">
<div class="scSponsorsBanner">
<h3 class="scSponsorsCredits">The moment is presented by:</h3>
<div class="scSponsorsList">
<img src="link/to/content/1" />
<img src="link/to/content/2" />
...
</div>
</div>
</div>
</body>
<!-- Js Scripts Import -->
<script src="https://stagecast.se/media/lib/mdk/stagecast.min.js"></script>
<script src="./main.js"></stript>
</html>

The ws object

joinMomentChannel(): Websocket Connection and Messaging

joinMomentChannel() creates a websocket connection that can be either authenticated or not. The connection can be seen as a channel that is unique to the Moment and accessible by all the users of that Moment to send/receive messages and sync on topics.

Thanks to the websocket, the developer could, for example, implement Moments based on distributed logics and chats.

Params:

  • onMessage: the message handler function;

  • onError: the error handler function;

  • additional: WsEventHandlers: (optional) additional event handlers:

    • onOpen?: the on connection open callback;

    • onAuth?: the authentication callback;

    • onClose?: the on close connection callback;

  • authenticate: authenticates the user to the websocket (default true).

const onMessage = (data) => console.log(data);
const onError = (err) => console.error(err.message || err);
const onOpen = (data) => console.log('The connection was opened');
const onAuth = (data) => console.log('The user has authenticated');
const onClose = (data) => console.log('Connection closed');
const add = {
onOpen: onOpen.bind(this),
onAuth: onAuth.bind(this),
onClose: onClose.bind(this)
}
const authenticate = true;
SDK.ws.joinMomentChannel(
onMessage.bind(this),
onError.bind(this),
add,
authenticate
);

IMPORTANT NOTES

  • The websocket connection is unique. In the future we might enable more websocket connections at the same time.

  • If one Moment (ie. a user) creates multiple authenticated connection in parallel from the same instance, only the last one will be authenticated. The user can only be authenticated in one single session.

  • If the user needs to receive direct messages, it must be authenticated (set the authenticate flag to true)

sendMessageTo(recipient: string, message: any)

Params:

  • recipient: a user id (its email)

  • message: any javascript object. (it will be serialized to JSON by the MDK).

This function allows to send a message to an authenticated user over the websocket. Both users must be authenticated. If a uses logs on multiple sessions, only the last one will be valid. This means that if the same user logs into the Mobile page and the Result page at the same time only one will be authenticated.

SDK.ws.sendMessageTo('friend@stagecast.se', {
message: 'Hello Friend, let\'s meet at the bar!'
});

NOTES:

  1. The user must be authenticated to the websocket (ie. have set the authentication param as true in wsConnect())

  2. For now, the function is synchronous, meaning that the MDK doesn't take a callback as an argument. The MDK is being actively developed and future implementations will include this functionality.

broadcastMessage(message: any): boolean

This function allows to broadcast a message to all the users connected to the Moment. If you wish to send a private message to a specific user, or to the Result page see sendMessageTo().

SDK.ws.broadcastMessage({
message: [
'Hello Everybody! ',
'Let\'s meet at the bar. ',
'I\'ll offer the first round!'
].join();
});

Params:

  • message: any javascript object. (it will be serialized to JSON by the MDK).

NOTE

For now, the function is synchronous, meaning that the MDK doesn't take a callback as an argument. The MDK is being actively developed and future implementations will include this functionality.

leaveMomentChannel(): boolean

Used to close the websocket connection.

try {
const res = SDK.ws.leaveMomentChannel();
} catch (err) {
console.error(err.message || err);
}

getUserUpdates(): boolean

It is also possible to subscribe to user updates: whenever a user updates its state, the backend broadcast the new state over a special ws channel. You can subscribe to the channel by calling this method.

This usually comes handy when the developer wants to implement dashboard or shared screen that the mobile clients can send messages to. Examples of such screens are the Voting Moment or Collage result pages.

const onMessage = (data) => console.log(data);
const onError = (err) => console.error(err.message || err);
const onOpen = (data) => console.log('The connection was opened');
const onAuth = (data) => console.log('The user has authenticated');
const onClose = (data) => console.log('Connection closed');
const add = {
onOpen: onOpen.bind(this),
onAuth: onAuth.bind(this),
onClose: onClose.bind(this)
}
const authenticate = true;
SDK.ws.getUserUpdates(
onMessage.bind(this),
onError.bind(this),
add,
authenticate
);
  • This channel is readonly: you can only receive messages.

  • If you are planning on creating a Moment for a large crowd use this method carefully. In fact, every client will notified whenever another client updates its state: this usually generate a huge traffic and puts a lot of pressure on the clients.

stopUserUpdates(): boolean

Used to stop getting user updates. This function closes the ws connection opened by getUserUpdates() and handles the teardown logic.

try {
const res = SDK.ws.stopUserUp();
} catch (err) {
console.error(err.message || err);
}

Disconnection Listener

Sometimes the moment could lose the connection (when the phone it's locked, the app is put in background etc.). The ws objects allows you register an event listener for the disconnection. You can register your event listener on the window object. The event to listen to is ws-offline

window.addEventListener('ws-offline',
(() => console.log('WS disconnected')).bind(this)
);

More on that here: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener

The analytics object

track(): void

Used to track activities.

Params:

  • action: any string that describes the action (no spaces)

  • options

    • category: the event category

    • value: a numeric value representing the event

    • label: a string describing the action

document.querySelector("#testButton").onclick = function(event) {
const action = 'test_button_click';
let options = {
category: 'generic_click_event',
value: 1,
label: 'Test Button clicked'
};
SDK.analytics.track(action, options);
}