-
Notifications
You must be signed in to change notification settings - Fork 27
Headless (embedded) activity API
The idea of headless activities is to expose individual FROG activities to other systems, and enable a deep integration. The current implementation is a prototype, and will probably change (feedback is welcome).
Currently there is no support for API keys or secrets, and no usage limitations etc. This will be introduced later. All APIs use POST requests, with payload formatted as application/x-www-form-urlencoded
(the result of filling out an invisible form, and submitting it). This is similar to how LTI requests are made, in the future it would be interesting to explore if LTI extensions could cover the use cases below.
All the URLs, other than api/activityTypes (which returns JSON) should be loaded in an iFrame with a POST request. This can be done in pure javascript, otherwise there are libraries such as react-post which exports PostIFrame. See also the implementation in the frogapi-test
(described at the bottom).
<FROGURL>/api/activityTypes
generates a JSON list of activity types installed, and some metadata (description etc). This can be used to generate a menu of activity types. Example:
{
id: "ac-webrtc",
type: "react-component",
name: "WebRTC",
description: "Video Conference",
longDescription: "Video conference using WebRTC peer to peer configuration",
runner_url: "/api/activityType/ac-webrtc",
config_url: "/api/config/ac-webrtc"
}
If you want to embed the FROG activity chooser in an iFrame, you can use the URL <FROGURL>/api/chooseActivity
. This will use iFrame messages to signal when an activity has been chosen. Currently this embed does not support previews.
The following data can be sent as POST payload:
Settings:
-
showValidator (boolean)
: show the validator circle (green for valid, red for invalid) -
showLibrary (boolean)
: show the activity library (pre-configured activities from the cloud) -
showDelete (boolean)
: shows a delete button when configuring a specific activity, which throws away the config, and goes back to the activity chooser -
whiteList Array<string>
: only offer the activity types listed here (for example ['ac-chat', 'ac-brainstorm']
When an activity is chosen, a config message is issued, which is described in the next section.
If you already know which activity type should be configured, either as a result of using the embedded activity chooser, or querying the API and displaying a native selection menu, you can request the configuration for that specific activity with <FROGURL>/api/config/<AC-NAME>
.
The currently selected config, as well as whether it is valid or not, is constantly sent to the parent app. It is the parent apps responsibility to store this information - no state is retained by FROG. An activity should never be launched if the config was not marked as valid.
The following data can be sent as the POST payload:
Data:
-
config (object)
: An existing config object to initialize the form with
Settings:
-
showValidator (boolean)
: show the validator circle (green for valid, red for invalid) -
showDelete (boolean)
: shows a delete button when configuring a specific activity, which throws away the config, and goes back to the activity chooser -
whiteList Array<string>
: only offer the activity types listed here (for example ['ac-chat', 'ac-brainstorm'] -
showLibrary (boolean)
: show the activity library (pre-configured activities from the cloud) (if going back to the activity chooser)
Initially when the config loads (including from the activityChooser above), and at every change in the config, a new message is issues, which looks like this:
{
type: 'frog-config',
activityType: 'ac-single-li',
config: {},
errors: [],
valid: true
}
Here is another example, which both contains a config
in progress, as well as some errors.
{
type: 'frog-config',
activityType: 'ac-quiz',
config: { shuffle: 'none', guidelines: '<p>These are my guidelines</p>' },
errors: [
{
err: 'You must have at least one question',
id: '1',
nodeType: 'activity',
type: 'configValidateFn',
severity: 'error'
}
],
valid: false
}
You can either allow showValid
, which will show a visual indicator of errors, and allow the user to see the error messages when hovering over, or you should somehow indicate to the user when the config is faulty. You should never call an activity with a faulty config (one that has at least one error
), this will normally lead to a crash.
An activity is launched by a POST request to the following URL: <FROGURL>/api/activityType/<AC-NAME>
.
The POST request should be formatted as a form (application/x-www-form-urlencoded), for example using the react-post
library. The following fields are supported:
Identifying activity:
-
clientId:
API user -
activityId:
optional, important if you have multiple activities of the same type, which should not share data/config
Identifying user (all optional):
-
userId:
optional, just used for log messages -
userName:
optional, used for log messages, dashboards, etc.
Configuring activity:
-
config:
config object which should be the output of configuring the activity. This, together with the AC-TYPE in the URL, describes the activity to be launched
Specifying group:
-
instanceId:
optional, but should usually be supplied, see below
Supplying data:
-
activityData
: supplying activityData to be merged into activity -
rawData
: supplying rawData to be used for the activity
Settings:
-
readOnly:
no changes can be made to the data - useful for example for teacher viewing student contributions
All FROG activities are back by reactive data structures (powered by ShareDB). All the students in the same instance will see and edit the same data.
The actual (full) instanceId is concatenated from clientId
, activityType
, activityId
, and instanceId
. This means that you can have an instance (group1
) in two different quizzes, with different data, as long as you supply unique activityIds
for the two quizzes etc.
Reactive document initialisation is only done once for each full instanceId. The following fields should therefore be identical for all the launches of a single full instanceId (if you first initialise an instance with a certain reactive data, and then launch again with another configuration, the activity might crash).
config
activityData
rawData
activityData
is a data structure that is merged into the activity using a the activity type's merge function. rawData
is a snapshot of the underlying data, which is written directly to the ShareDB. If you are listening to the frog-data
over postMessage
, this is where you would send the data.
If you use both readOnly
and rawData
, it will simply use the activity type to display that data without loading any shareDB document etc. In that case, you still require config
, but none of the other parameters are required or have any impact.
While an activity is running, it emits log messages using iFrame communications. Currently these are in the internal FROG format, but in the future, we will probably use xAPI. These have the type frog-log
.
While activities are running, they also constantly update the state of the activity through iFrame messaging. Raw data is always sent, this has the type frog-data
. Some activities are also able to generate more meaningful state messages, which typically uses information from the config. These activities also emit frog-data-transformed
messages. And example is the ac-quiz
activity, the internal data format is meaningless without access to the config:
{
"justification": "",
"form": {"0": 0},
"coordinates": {"x": 0, "y": 0, "valid": false}
}
Therefore, the dataTransformed can be useful, it looks like this:
{
"questions": ["Laquelle de ces expressions est fausse?"],
"answers": [
"Pour une variable discrète, le nombre de valeurs possibles est dénombrable."
],
"answersIndex": [0],
"maxCorrect": 1,
"coordinates": {"x": 0, "y": 0, "valid": false}
}
Dashboards are unique to activities identified by clientId and activityId, but span all the user/instances.
To display the dashboards for an activity, use the following URL:
<FROGURL>/api/dashboard/<AC-NAME>
.
POST parameters:
-
clientId:
API user -
activityId:
optional, important if you have multiple activities of the same type, which should not share data/config -
config
: Required for some dashboards, such as ac-quiz Counts
In frogapi-test
, there is a demo application using create-react-app, which has no dependencies on FROG libraries. This implements both showing pre-configured FROG activities in an iFrame, and capturing log messages/activity state, but also configuring activities within the app.