Guides

Versioning

Basics

Collection Integration API is using SemVer approach.

Url to the version 2.0 is https://codesdwncdn.realeyesit.com/IntegrationAPI/2.0/Realeyesit.IntegrationAPI.Client.js or (https://codesdwncdn.realeyesit.com/IntegrationAPI/2.0/Realeyesit.IntegrationAPI.Client.min.js) Only major and minor version numbers can be used in the url. It makes possible get last patches/fixes for the API without any url updates. When we release a new major version, we freeze previous versions, meaning that we no longer update it with regular bug fixes. However, we may occasionally apply some fixes/patches, for example if there is a critical bug or some another legal reason for doing so. Frozen versions will be avialable at least during 6 months after that. For example if we release version 2.0 we will support all 1.x versions during next 6 months, and by default all last fixes and patches will be applied only to newly released version 2.0.

Also it’s possible to use word latest in the url instead version number: https://codesdwncdn.realeyesit.com/IntegrationAPI/latest/Realeyesit.IntegrationAPI.Client.js In that case the latest version of API will be used.

Tip: To check via JavaScript which version is used Realeyesit.Version object can be used. Also full number of used version will be displayed in browser console during script initialization process.

Best practices

Below we provide recommended best practices for version usage.

For high stability/availability/traffic applications

Wanting be sure in high stability and availability of the product

We recomend to explicitly specify current release version number of Integration API in the url. To make sure that there are no issues arising from version rollover (for example: https://codesdwncdn.realeyesit.com/IntegrationAPI/2.0/Realeyesit.IntegrationAPI.Client.js). Also it’s important to be subscribed to the page to be notified if the version will be obsolete/frozen. And start version updating process as soon as your version marked as obsolete/frozen.

For cutting-edge applications

Wanting early access to the latest features

We recomend to use the link https://codesdwncdn.realeyesit.com/IntegrationAPI/latest/Realeyesit.IntegrationAPI.Client.js (to latest API) only if your application is not required consistent avialability and stability and if you want to get latesst features as soon as possible. NOTE: With permanent link to latest API version there is a risk to use incompatible version of API with your application after release of new major version of API.

Authorization

To get started with programmatic API you need to create yourself an API key by which we’d identify all the data that’s being collected. Follow these steps below to get started:

  1. Log into the delivery site at http://delivery.realeyesit.com with a user that has admin rights
  2. Go to Account from the main menu
  3. Go to API Keys from the sub-menu
  4. Pick the account you want to create API keys to
  5. Under the “Rest API Keys” click create. Be careful and take notes from generated credentials, because of you can’t see it again!

You can manage your API keys anytime here: https://delivery.realeyesit.com/ApiKey The apiKey is restricted by Account. It means all action which you can perform will affect data which belong only to the Account. If you already have apiKey then you can start using our API. See Collection set-up to understand how to use the apiKey

Collection set-up

Note that in case of using programmatic collection setup then you need to take care of properly encoding and distributing the media for playback on your own. When you manually setup collections, Realeyes encodes videos to multiple sizes for optimal playback automatically and distributes them across Amazon Cloudfront CDN, but that’s not the case when using the programmatic api.

To use the api you can pass a configuration to the init method as shown below:

var config = {
    apiKey:"3c2819e2026d6168",
    key:"myFirstCollection",
    name:"Test Collection via config",
    displayLang:"1043",
    translations:[{key:"dc_allow_webcam_instruction",value:"my new <b>overriden</b> instruction"}],
    startOptions: {qualityFeedbackType: 1, externalCssUrl: 'http://localhost:8080/public/assets/css/test.css'},
    skinName:"v2",
    alternativeFlashCNAME:"adjustedCname",
    elements:[
        {key:"video1" ,url:"https://mysite/myvideo1.mp4"}]
    };
Realeyesit.IntegrationAPI.Client.init('iframeContainer', config);

Where config object has next attributes:

  • apiKey - key to identify the account under which all the collected data would belong to, the same key used with all other server side API calls as well
  • key - unique external key identifying the test or the project. IMPORTANT: each porject should have 1 unique key. There are shouldn’t be 2 and more projects with same key and one project shouldn’t have different keys!
  • name (optional) - a friendly name of the test or project to be used when reporting the results, the key will be used if the name is empty
  • participantId (optional) - unuque Id of survey participant
  • isReviewer (optional) - sessions marked as isReviewer=’true’ will not be counted.
  • displayLang (optional) - the language of all the user interfaces and everything else. Default would be English
  • translations (optional) - the array of ue messages which should be overriden with new text.
    • key - key of ui message. The kye can be retrived from ui. It placed to data-ui-message-key attribute of html element
    • value - new ui message which will be applied
  • startOptions (optional) - start options for UI
    • qualityFeedbackType - type of of quality feedback screen (1 - auto, 2 - manual, 3 - skip, any other - default)
    • externalCssUrl - css file which should be applied to the UI skin
  • ignoreTrackingErrors (optional) - the playback of video will be continued and any tracking errors/exception will be ignored
  • skinName (optional) - name of skin which will be applied for all visible pages of Realeyes emotion measurement component. If the parameter is skipped the default skin will be used. Possible values: ‘original’, ‘IPSOSConnectV7’, ‘IPSOSConnectV8’
  • alternativeFlashCNAME (optional) - if Realeyesit company adjested for you CNAME then plese put alias to the filed if you want to show access permission dialog with adjusted domain url
  • elements - array of media elements configurations:
    • key - unique external key identifying the media. IMPORTANT: each media should have 1 unique key. There are shouldn’t be 2 and more videos with same key and one video shouldn’t have different keys!
    • url - The URL of the media that would be played back. We support mp4 and flv. NOTE: Only full preload of the media from given URL is supported now. Media needs to be in the appropriate size for serving (API’s do not apply any conversions on video files for playback, so files should be appropriately presized). Be aware that proper crossdomain.xml file should be present at the url domain location for our flash player to download the media. See next section for details.
    • name (optional) - a friendly name of the media to be used in reporting, the key will be used if the name is empty
    • randomization (optional) - object with attributes ‘elementsGroup’ and ‘randomisationGroup’. The object will be used to define randomisation rules for the playback.
    • skipRecording (optional) - if empty, media will be measured and billed, if set to true, then the media will be considered as clutter and will just be shown, but not measured and billed
    • testElementKey (optional) - unique external key identifying the exact element
  • metadata(optional) - dictianary from with custom data which should be passed to RealeyesitAPI. Supported values
    • privacyLink(optional) - the link will replace privacy link on Realeyesit UI
    • faqLink(optional) - the link will replace link to FAQ on Realeyesit UI
    • supportLink(optional)- the link will replace link to Support on Realeyesit UI
    • progressValue(optional) - defines progress of whole survey (value from 0 to 100). Provide it if your skin contains progress bar and the progress bar should display global progress.
  • customAllowScreenEnabled(optional) - defines if custom (not system) allow webcam screen should be displayed if webcam was alowed for this domain before (will affect only browsers suported webrtc recording: Chrome, Firefox)
  • reallowScreenDisabled(optional) - defines if re-allow webcam screen should be displayed if webcam was forbiden for this domain before(will affect only browsers suported webrtc recording: Chrome, Firefox)

NOTE: the following predefined classes can be used to create the configuration:

  • Realeyesit.IntegrationAPI.Configuration
  • Realeyesit.IntegrationAPI.ConfigurationElement
  • Realeyesit.IntegrationAPI.RandomisationDescription

Example:

       var frame=window.document.getElementById('dataCollectionIframe');
       var config = new Realeyesit.IntegrationAPI.Configuration();
       config.displayLang = "1043";
       config.apiKey = "3c2819e2026d6168";
       config.key = "testColl1";
       config.name = "Test Collection via config";

       // optional
       config.metadata = { privacyLink: '//yoursite.com/privacy', faqLink: '//yoursite.com/faq', supportLink: '//yoursite.com/support', progressValue: 73 };

       var el1 = new Realeyesit.IntegrationAPI.ConfigurationElement();
       el1.key = "videoUniqueKey1";
       el1.name = "insurance via config";
       el1.url = "https://devsourcedatabucket.s3-eu-west-1.amazonaws.com/somevideo1.mp4";
       el1.testElementKey ="elementkey1";

       var el2 = new Realeyesit.IntegrationAPI.ConfigurationElement();
       el2.key = "videoUniqueKey2";
       el2.url = "https://devsourcedatabucket.s3-eu-west-1.amazonaws.com/somevideo2.mp4";

       var el3 = new Realeyesit.IntegrationAPI.ConfigurationElement();
       el3.key = "videoUniqueKey1";
       el3.url = "https://devsourcedatabucket.s3-eu-west-1.amazonaws.com/somevideo1.mp4";
       el3.testElementKey ="elementkey1";

       config.elements = [el1,el2,el3];

       Realeyesit.IntegrationAPI.Client.init(frame, config);

IMPORTANT: There are couple examples to understand the project’s key and media’s key handling:

Example 1: We have started our project with name “Project 1” and key “project1”

       ...
       var config = new Realeyesit.IntegrationAPI.Configuration();
       config.key = "project1";
       config.name = "Project 1";     
       ...  
      

After couple days (or even in same time) we have started our second project with name “Project 2” and same key “project1”. WARNING: These are examples for typical user errors!

       ...
       var config = new Realeyesit.IntegrationAPI.Configuration();
       config.key = "project1";
       config.name = "Project 2";     
       ...        

In the result all data will be collected under “Project 1” and project with name “Project 2” won’t be created in the system because we are handling it by project’s key and it was same as before.

Example 2: We have started our project with name “Project 1” and key “project1”

       ...
       var config = new Realeyesit.IntegrationAPI.Configuration();
       config.key = "project1";
       config.name = "Project 1";     
       ...  
      

After couple days (or even in same time) we have desided to chande key for the project to “project2”

       ...
       var config = new Realeyesit.IntegrationAPI.Configuration();
       config.key = "project2";
       config.name = "Project 1";     
       ...        

In the result data will be collected under 2 different project but with same name “Project 1”.

NOTE: A playlist with media can be passed during initialization process however it is not mandatory - it can be passed later with separate command setPlaylist but it should be before preloadMedia or play stages

Randomisation settings

When showing multiple stimuli to viewers, it’s important to try to minimize or eliminate any bias that might come from a specific ordered sequence of presenting the stimuli. This is where Randomization comes in. A test consists of a sequence of stimuli which might be media or instructions. Each stimulus in a sequence can belong to a group. A group is a collection of stimuli which one wants to treat as a single entity from the perspective of randomization. For example you might have an instruction that specifically refers to an ad, like “Watch this ad about lions” and then you have the ad that follows it which is about lions - you need these two to go together. Or if you have 2 ads among many other ads that always need to be shown in a specific order. The order of stimuli inside a group is always maintained. Each of the groups of stimuli can in turn be assigned to randomization groups. The order of each stimulus group inside the randomization group will be randomized. We always record the randomization rules and actual outcome for each session separately in the database. The randomization rules will give us the likelihoods of seeing each combination and it’s easy to verify if the randomization works by comparing the observed frequencies of combinations to the expected ones coming from the rules.

As you can see each media has randomization configuration element with 2 attributes:

  • elementsGroup
  • randomisationGroup

see examples to understand how the randomization configuration works:

Example 1: Let’s assume I have 4 media and I want to each of them to be in random position with every test, the configuration would be following

       var el1 = new Realeyesit.IntegrationAPI.ConfigurationElement();
       el1.key = "video1";
       el1.url = "https://mysite/video1.mp4";
       el1.randomisation = {elementsGroup:'1'};

       var el2 = new Realeyesit.IntegrationAPI.ConfigurationElement();
       el2.key = "video2";
       el2.url = "https://mysite/video2.flv";
       el1.randomisation = {elementsGroup:'2'};

       var el3 = new Realeyesit.IntegrationAPI.ConfigurationElement();
       el3.key = "video3";
       el3.url = "https://mysite/video3.mp4";
       el1.randomisation = {elementsGroup:'3'};

       var el4 = new Realeyesit.IntegrationAPI.ConfigurationElement();
       el4.key = "video4";
       el4.url = "https://mysite/video4.flv";
       el1.randomisation = {elementsGroup:'4'};

       config.elements = [el1,el2,el3,el4];

Example 2: Let’s assume we have 4 media, but we want the media 1 and 2 to be always one after the other and media 3 and 4 also one after the other, but the groups themselves would be in a different position each time.

       var el1 = new Realeyesit.IntegrationAPI.ConfigurationElement();
       el1.key = "video1";
       el1.url = "https://mysite/video1.mp4";
       el1.randomisation = {elementsGroup:'1'};

       var el2 = new Realeyesit.IntegrationAPI.ConfigurationElement();
       el2.key = "video2";
       el2.url = "https://mysite/video2.flv";
       el1.randomisation = {elementsGroup:'1'};

       var el3 = new Realeyesit.IntegrationAPI.ConfigurationElement();
       el3.key = "video3";
       el3.url = "https://mysite/video3.mp4";
       el1.randomisation = {elementsGroup:'2'};

       var el4 = new Realeyesit.IntegrationAPI.ConfigurationElement();
       el4.key = "video4";
       el4.url = "https://mysite/video4.flv";
       el1.randomisation = {elementsGroup:'2'};

       config.elements = [el1,el2,el3,el4];

Example 3: Let’s assume we have 4 media, but we want the media 1 and 2 to be always one after the other and the rest to be randomized individually.

       var el1 = new Realeyesit.IntegrationAPI.ConfigurationElement();
       el1.key = "video1";
       el1.url = "https://mysite/video1.mp4";
       el1.randomisation = {elementsGroup:'1'};

       var el2 = new Realeyesit.IntegrationAPI.ConfigurationElement();
       el2.key = "video2";
       el2.url = "https://mysite/video2.flv";
       el1.randomisation = {elementsGroup:'1'};

       var el3 = new Realeyesit.IntegrationAPI.ConfigurationElement();
       el3.key = "video3";
       el3.url = "https://mysite/video3.mp4";
       el1.randomisation = {elementsGroup:'2'};

       var el4 = new Realeyesit.IntegrationAPI.ConfigurationElement();
       el4.key = "video4";
       el4.url = "https://mysite/video4.flv";
       el1.randomisation = {elementsGroup:'3'};

       config.elements = [el1,el2,el3,el4];

Example 4: Let’s assume we have 4 media, but we want the media 3 to always stay where it is, but others to move around it randomly.

       var el1 = new Realeyesit.IntegrationAPI.ConfigurationElement();
       el1.key = "video1";
       el1.url = "https://mysite/video1.mp4";
       el1.randomisation = {elementsGroup:'1'};

       var el2 = new Realeyesit.IntegrationAPI.ConfigurationElement();
       el2.key = "video2";
       el2.url = "https://mysite/video2.flv";
       el1.randomisation = {elementsGroup:'2'};

       var el3 = new Realeyesit.IntegrationAPI.ConfigurationElement();
       el3.key = "video3";
       el3.url = "https://mysite/video3.mp4";

       var el4 = new Realeyesit.IntegrationAPI.ConfigurationElement();
       el4.key = "video4";
       el4.url = "https://mysite/video4.flv";
       el1.randomisation = {elementsGroup:'3'};

       config.elements = [el1,el2,el3,el4];

Example 5: Let’s assume we have 4 media, but we want the media 1 and 4 to only be randomized between themselves and then media 2 and 3 to be randomized between themselves.

       var el1 = new Realeyesit.IntegrationAPI.ConfigurationElement();
       el1.key = "video1";
       el1.url = "https://mysite/video1.mp4";
       el1.randomisation = {elementsGroup:'1',randomisationGroup:'1'};

       var el2 = new Realeyesit.IntegrationAPI.ConfigurationElement();
       el2.key = "video2";
       el2.url = "https://mysite/video2.flv";
       el1.randomisation = {elementsGroup:'2',randomisationGroup:'2'};

       var el3 = new Realeyesit.IntegrationAPI.ConfigurationElement();
       el3.key = "video3";
       el3.url = "https://mysite/video3.mp4";
       el1.randomisation = {elementsGroup:'3',randomisationGroup:'2'};

       var el4 = new Realeyesit.IntegrationAPI.ConfigurationElement();
       el4.key = "video4";
       el4.url = "https://mysite/video4.flv";
       el1.randomisation = {elementsGroup:'4',randomisationGroup:'1'};

       config.elements = [el1,el2,el3,el4];

Default collection flow

You should understand workflow of collection process to implement optimal integration with Realeyesit software.

Main idea of the integration is that the survey software shows their content with usual flow and only when media playback with emotion measurement is needed, the software will send commands to Realeyes API via the Client (commands like: askPermissions, preloadMedia, play etc.) which in turn then displays the neccesary webcam prompts and media.

The iframe approach is required because of the security requirements of webcam access. Namely the access to the webcam can only be requested for the duration of a single page and in case the survey consists of multiple pages, then it would mean bothering the user multiple times. Having it in a iframe that’s never loaded, would work around that.

To make the integration work, all components should be placed correctly:

Iframe container element should be placed on main window. Main IntegrationClient should be included in the same window and initialized with init function. if you need execute methods from different iframes you can add as many additional clients as you need.

Note: Pay attention not to reload our emotion measurement component iframe, because the webcam access will be lost that way and the user would need to be prompted for access again.

From high level we can describe the workflow as 6 steps:

  • init. Initialize whole collection proccess.
  • ask Webcam Permissons. Asks user for webcam access.
  • check Webcam Quality. Checks webcams and switchs to active webcam. Asks user to adjust environment if it needed.
  • preload Medias. Starts preloading the involved media.
  • start playng. Start playing the involved media
  • save results. Saving collected data. NOTE: the application save results continuosly during video playback but there is some small amount of data which is saved at end of the test

if you execute play() before askWebcamPermissons then we will not record participant’s emotion data and will just play videos. To start emotion tracking you need execute askWebcamPermissons before play method. It’s possible to repeat first and second steps many times before preloading was started but if preloading stage was started/passed then you are not able repeat the stages for current session untill you will not reinitialize it.

Custom styles and text

During the collection process Realeyesit Integration API shows following screens:

  • Ask Webcam permissions screen
  • Check Webcam quality screen. There are 3 different modes for check quality screens
    • Manual
    • Auto
    • None
  • Media content playing screen

It’s possible to define which skin should be used for the screens. To do it you should use the skinName parameter in configuration object: - skinName - name of skin which will be applied for all visible pages of Realeyes emotion measurement component. If the parameter is skipped the default skin will be used. Possible values: ‘original’, ‘IPSOSConnectV7’, ‘IPSOSConnectV8’

However if it is not enough and you want more freedom in the screens customization then custom css can be applied for the pages:

  • startOptions - start options for UI
    • externalCssUrl - css file which should be applied to the UI skin

If it still not enough and you want to override text or add html elements to the pages then you can use text overriding feature:

  • translations - the array of ue messages which should be overriden with new text.
    • key - key of ui message. The kye can be retrived from ui. It placed to data-ui-message-key attribute of html element
    • value - new ui message which will be applied

Example

var config = {
    ...
    translations:[{key:"dc_allow_webcam_instruction",value:"<span style='font-size:12px'>my new <b>overriden</b> instruction<span>"}]
    skinName:"IpsosConnectv8"
};

Security

Crossdomain file loading

When using Programmatic collection setup, you can specify any url for the media to be downloaded and played in our flash player. Due to flash security policy our player can not download content from domain other than our, unless remote domain is not configured to allow this. For that purpose remote domains should host crossdomain.xml files (e.g. at the root ‘somedomain.com/crossdomain.xml’) that allow our player’s domain to access this domain. Here is the example of such a file:

<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
   <allow-access-from domain="*.realeyesit.com"/>
</cross-domain-policy>

You can read more on crossdomain policy files here

Error handling

All public methods of Integration API are isolated. It means - if there is any exception occured it will not block execution of code which called the method. Also Realeyesit.IntegrationAPI.Client and Realeyesit.IntegrationAPI.IntegrationManager object have method onError and the methods indicate that an error occured during initialization or test process and normal flow of collection data can’t be continued.

Initialization timeout handling

To prevent blocking execution flow of main program all public initialization methods are limited with timeout. I.e. if initialization is executing more than the timeout value then an error will be thrown. The error can be handled via “onError” method as usual.

Also it’s possible to change the timeout value vie initial configuration.

Example

var config = {
    apiKey:"3c2819e2026d6168",
    key:"myFirstCollection",

    initializationTimeout: 50000,

    name:"Test Collection via config",
    elements:[
        {key:"video1" ,url:"https://mysite/myvideo1.mp4"}]
    };
Realeyesit.IntegrationAPI.Client.init('iframeContainer', config);

Where initializationTimeout - inititalization timeout value in milliseconds

iframe vs frameset integration

We are recomended to use default integration way which are using iframe element (see Quick start). However some of our clients have different page layauts and it can be that they are using frameset at top of the page. Then to optimise UX and do not ask permissions everytime when frame element of the frameset reloaded we are rocommeding to use integration via frameset (see Quick start frameset integration.

NOTE: first version of integration via frameset has required additional steps:

  • create frame of frameset manually
  • connect IntegrationManager script to main page and do init of the manager instead client. IntegrationManager - it’s just shim object for communications between frames

but it has same functionality and everything what is provided in latest version of frameset integration can be used in the version with IntegrationManager shim. you can find more information about old frameset integration with the link