History management with pipe.js

The purpose of this tutorial is to learn how to capture and share the history of viewing client-side to be able to get content-based recommendations.

Prerequisites

To be able to complete this tutorial, you will need to integrate pipe.js library. For more information about the process, you can follow the first part of this complete guide on pipe.js integration regarding pipe.js integration.

How to save the history of viewings

In order to save the history, we implemented a basic function _pipe("pushHistoryElement", history) which allow us to store json formatted data in client local storage. This data will then be easily retrievable through another pipe.js function.

The simplest solution is to send the id of the video (and other informations if needed) each time the client play a video, but you should be aware that duplicated entries will be stored. When the limit is reached, we simply shift the oldest value stored and push the new one.

At the moment we allow a maximum of 100 elements in the history.

Here is a simple example of how we store a media id and its type on each play event

collectMedia: function(event) {

    [...]

    player.getMetadata(function(data) {
        var history = {
           type: data.type,
           id: data.id
        };
        //send video to history when played
        if(event == "playing") {
            _pipe("pushHistoryElement", history); 
        }
        pipe("collect", type, data);
    });
}

Retrieve the history

As stated earlier another function is available to retrieve client stored history : _pipe("getStorage", "historyElements", function(err, history). First and second parameters should not be changed as they defined the pipe function we need to use and the name of the stored element we want to retrieve, which is the default one. Then the err represents an error callback in case you want to add a specific behavior if an error occured during the process of retrieving the history. Finally history is the json formatted data containing of all data stored with _pipe("pushHistoryElement", history) function.

Here is an example of how we use this function to get client data stored and directly push it back to another one

_pipe("getStorage", "historyElements", function(err, history){
    if(err) {
        handlePipeStorageError(err);
    }
    this.getRecommendationsSendHistory(history, recommendationUrl);
});

Be careful with browsers private mode (mostly safari) because they do not handle local storage the same way and it could lead to errors when retrieving data.

Send history to recommendation system

Once you retrieved the client data stored, you can push it at the same time you request recommendations. If you need more informations on how to use a player (like default html one) and grab events from it to send data to the Recommendation Pipe API, you can refer to this tutorial. To be able to send the history, each id of stored elements must be concatenate together and separated by dash like this 12345-67890-09876 and send along with the request to get recommendations.

Here is the code we use to format data coming from pipe and then send the request to push history elements and also get recommendations

getRecommendationsSendHistory: function(history, recommendationUrl) {
     var _this = this;
     var formattedHistory = "";

     if (history !== null) {
         //let's format history as String for url parameter
         history = JSON.parse(history);
         for(var i = 0; i < history.length; i++) {
             // first element without dash
             if(i == 0) {
                 formattedHistory += history[i].id;
             } else {
                 formattedHistory += "-"+history[i].id;
             }
         }
     }

     var options = {
         method: "GET",
         url: recommendationUrl,
         data : {
             identifier: this.$block.attr("id"),
             type: this.settings.type,
             limit: 4,
             history: formattedHistory
         }
     };

     $.ajax(options).success(function (data, textStatus, xhr) {
         _this.$block.find(blockContainerSelector).empty().append(data);
         _this.initPlayer();
     });
}

Info

recommendationUrl corresponds to an endpoint you should have previously created. They are accessible right here.

Additional Documentation

Some documents to know more about pipe :

  • pipe.js documentation: More details on available informations, options, and methods using pipe.js.
  • Metrics: Proposition to standardize and set the best practices in terms of media consumption and data collection.