Child pages
  • 5. Service Integration
Skip to end of metadata
Go to start of metadata
This documentation is intended to help developers integrating the Recommender System API into an existing application either as a plugin or a custom made solution.

API Integration with rapid feedback

It is always difficult to integrate APIs (especially asynchronously ones) without getting direct feedback if the implementation one has made is working as expected. Therefore YOOCHOOSE decided to help developers with a special mode called 'feedback' which allows to see immediately in the response, if an event or a recommendation request was accepted or not. Additional sample recommendation responses are already in place or can be generated on-demand.

Preconfigured integration mandator

The usage of special params, which support the feedback mechanism without affecting customer data is realized by a parameter called 'feedback' which is valid in each request. It can be used by existing mandators or a mandator with the name '00000'. It is preconfigured to be used always in feedback mode for the tracking part. In the recommendation part, feedback mode must be explicitly enabled with the parameter.

Tracking events

The tracker supports a parameter called feedback, which indicates to respond with a generated event object. It includes all information which can be interpreted from the received request (also partially accepted events like a buy without a price data). Feedback is automatically enabled by using mandator '00000' when tracking events.

Use your own, already registered mandator

 Additionally you can add the parameter &feedback to the request to see if the date you sent is correctly transferred into an event. All data is transient and is not stored if the feedback parameter is used.

The following shows how to use the feedback mode, to verify the acceptance of sent events by the event tracking service. 


http://event.yoochoose.net/api/00000/click/someuser/1/1?categorypath=%2Fgenre%2Faction&feedback

[
  {
    "solutionType": "ebh",
    "customerId": "00000",
    "eventType": "CLICK",
    "hashedUserId": "57563448",
    "itemId": "23",
    "itemType": "1"
  }
]


http://event.yoochoose.net/api/00000/buy/someuser/1/1?fullprice=2.25EUR&quantity=2&feedback

[
  {
    "solutionType": "ebh",
    "customerId": "00000",
    "eventType": "BUY",
    "hashedUserId": "57563448",
    "itemId": "1",
    "itemType": "1",
    "price": "2.25EUR",
    "quantity": "2"
  }
]

 

http://event.yoochoose.net/api/00000/rendered/someuser/1/1,2?feedback

[
  {
    "solutionType": "ebh",
    "customerId": "00000",
    "eventType": "RENDER",
    "hashedUserId: "2090806916",
    "itemId": "1",
    "itemType": "1"
  },
  {
    "solutionType": "ebh",
    "customerId": "00000",
    "eventType": "RENDER",
    "hashedUserId": "2090806916",
    "itemId": "2",
    "itemType": "1"
  }
]

 

http://event.yoochoose.net/api/00000/clickrecommended/someuser/1/1?scenario=personalized&feedback

[
  {
    "solutionType": "ebh",
    "customerId": "00000",
    "eventType": "FOLLOW",
    "hashedUserId": "57563448",
    "itemId": "1",
    "itemType": "1",
    "scenario": "personalized"
  }
]

 

http://event.yoochoose.net/api/00000/login/anonymous/pseudonymous&feedback

[
  {
    "solutionType": "ebh",
    "customerId": "00000",
    "eventType": "TRANSFER",
    "hashedUserId": "57664398",
    "hashedTransferredUserId": "879110496"
  }
]

 

Getting Recommendations

There's different ways of providing recommendations directly. Fro example from predefined editorial lists which recommend static items. The disadvantages are fixed item ids and types that are probably not resolvable in a customer's dataset.

Use your own, already registered mandator

 Like in the tracking you can add the parameter &feedback to the recommendation request. It allows you to use your own, previously generated mandator in feedback mode without effecting stored data or event statistics.


The following describes some example recommendation calls. The first one assumes a static list is configured in a scenario called 'staticlist'.

  • http://reco.yoochoose.net/api/00000/someuser/staticlist.json
{
    "recommendationResponseList": [
        {
            "itemId": 222,
            "reason": "editorial_list (context: ITEM(s))",
            "relevance": 127,
            "itemType": 1
        },
        {
            "itemId": 111,
            "reason": "editorial_list (context: ITEM(s))",
            "relevance": 126,
            "itemType": 1
        }
    ]
}

The other possibility is from content which is given in request params like ?contextitems=1,2,3&outputtype=1 which returns a list of recommendations of item type 1 and item ids 1,2 and 3. 

The feedback mandator '00000' is not automatically in feedback mode when requesting recommendations, as therefore it would be impossible to deliver recommendations based on static lists or user profiles. So the &feedback is still needed as a param to generate feedback recommendations.
  • http://reco.yoochoose.net/api/00000/someuser/staticlist.json?contextitems=1,2,3&outputtype=1&feedback
{
    "recommendationResponseList": [
        {
            "itemId": 1,
            "reason": "feedback",
            "relevance": 0,
            "itemType": 1
        },
        {
            "itemId": 2,
            "reason": "feedback",
            "relevance": 0,
            "itemType": 1
        },
        {
            "itemId": 3,
            "reason": "feedback",
            "relevance": 0,
            "itemType": 1
        }
    ]
}

 

Udating profiles while tracking events is enabled as well. If click events are generated on the tracking servers, the information is automatically distributed to the recommendation servers. User profile history is updated (e.g. the latest clicks) internally in order to provide personalized and filtered recommendations. For example the requests

  • http://event.yoochoose.net/api/00000/click/someuser/1/77
  • http://event.yoochoose.net/api/00000/click/someuser/1/88

result in a profile update of user 'someuser' in the Recommender System. The user profile's click list can be fetched with the default scenario history_clicked

  • http://reco.yoochoose.net/api/00000/someuser/history_clicked.json

 

{
    "recommendationResponseList": [
        {
            "itemId": 88,
            "reason": "PROFILE_MODEL_CLICKED_U-CLICKED (context: NONE)",
            "relevance": 100,
            "itemType": 1
        },
        {
            "itemId": 77,
            "reason": "PROFILE_MODEL_CLICKED_U-CLICKED (context: NONE)",
            "relevance": 100,
            "itemType": 1
        }
    ]
}

 

Javascript examples

Event Tracking and Rendering recommendations

//Script which should be placed in each product page in order to track and render recommendations:
<script type="text/javascript">
       var mandatorId = "<mandatorId>"; // the mandatorId is provided by YOOCHOOSE under https://admin.yoochoose.net
       var itemId = "<itemId>"; // the itemId defines the current product
       et_yc_click(mandatorId,itemId);
</script>

Helper functions

//Get User's Cookie
function getCookieY()
{
     var c_name = 'YCID';
     var c_value = document.cookie;
     var c_start = c_value.indexOf(" " + c_name + "=");
     if (c_start == -1){
         c_start = c_value.indexOf(c_name + "=");
     }
     if (c_start == -1){
         c_value = null;
     }else{
         c_start = c_value.indexOf("=", c_start) + 1;
         var c_end = c_value.indexOf(";", c_start);
         if (c_end == -1){
             c_end = c_value.length;
         }
         c_value = unescape(c_value.substring(c_start,c_end));
     }
     return c_value;
}

//Sets User's Cookie; if the coockie exist - extend the expiration time
function setCookieY()
{
     var exdate=new Date();
     var exdays = 30; // expired in 30 days
     exdate.setDate(exdate.getDate() + exdays);
     var cy_value = getCookieY();
     if(cy_value == null || cy_value == ""){
           cy_value = generateGuid(); 
     }
     var c_value=escape(cy_value) + ( "; expires="+exdate.toUTCString()+"; path=/");
     document.cookie='YCID' + "=" + c_value;
}

//Generates random  User's Cookie value
function generateGuid() {
     var S4 = function() {
           return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
     };
     return (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4());
}


//Generates the image for user tracking
function et_yc_makeImage(){
      if(arguments.length < 4)
           return;

      var params = '';
      for(var i=0; i<arguments.length; i++){
            if(i){
                  params += '/';
            }
            params += arguments[i];
      }

      var url = 'http://event.yoochoose.net/'+params;

      var ycimg = new Object();
      ycimg.src = url;

      var ycanchor = document.createElement('img');
      ycanchor.border = 0;
      ycanchor.src = ycimg.src;
      ycanchor.style.display = 'none';

      if(typeof(document.readyState) == 'undefined' ||
         document.readyState == 'complete' ||
         document.readyState == 'loaded')
      {
             var body = document.getElementsByTagName('body')[0];
             body.insertBefore(ycanchor, body.lastChild);
      }else{
            var id = new Date().getMilliseconds();
            document.write('<p id="ycimg'+id+'" style="display:none;"></p>');
            document.getElementById('ycimg'+id).insertBefore(ycanchor, null);
     }
}


//Creates tracking image and triggers get recommendation script generator
function et_yc_click(clientid,itemId){
     var pageid = itemId;
     var atype = 1; // itemType can also be changed
	 var solutionId = 'ebl'; // 'ebl' is the defined solutionId -> depending on the Recommender Product contract
     setCookieY();
     var userid = getCookieY();
     var evtype = 'click'; // action could also be 'buy','consume', ...
     et_yc_makeImage("ebl", clientid, evtype , userid, atype, pageid); 
     if(document.URL.toString().indexOf('recommended=true') != -1){
            evtype = 'clickrecommended';
            et_yc_makeImage("ebl", clientid, evtype , userid, atype, pageid);
     }
     call_recs(clientid, userid, pageid, solutionId);
}

//Generates a script in order to call for recommendations
function call_recs(clientid, userid, pageid, solutionId){
       var scriptSrc = 'https://reco.yoochoose.net/'+solutionId+'/'+clientid+'/'+userid+'/product_page.jsonp?contextitems='+pageid+'&numrecs=5'; // preparing to call 5 recommendations
       var heads = document.getElementsByTagName('head');
       var head = null;
       if (heads != null){
          head = heads[0];
       }
       var script = document.createElement('script');
       script.type = 'text/javascript';
       script.src = scriptSrc;
       if(head != null){
             head.appendChild(script);
       }else{
             if(typeof(document.readyState) == 'undefined' ||
                document.readyState == 'complete' ||
                document.readyState == 'loaded')
             {
                    var body = document.getElementsByTagName('body')[0];
                    body.insertBefore(script, body.lastChild);
             }
             else{
                   var id = new Date().getMilliseconds();
                   document.write('<p id="ycscrp'+id+'" style="display:none;"></p>');
                   document.getElementById('ycscrp'+id).insertBefore(script, null);
             }
       }
}

//This function is called by the response of the recommendation engine, you should implement the rendering of the recommendations in this function 
function jsonpCallback(json){

     if(json == null || json.length == 0){
          return;
     }

     var items = json.recommendationResponseList;
     if(items == null || items.length == 0){ 
          return;
     }

     var recamount =  items.length;
     for(var i = 0;i<recamount;i++){
          var itemId = items[i].itemId;
         //get title,image, price, url ... of the product using AJAX
         //insert to the reserved place in the document the recommendation
     }

}

Implementation Checklist

ActionYes/NoComment
Event Tracking
All request parameters are URL encoded  
A user clicks on a detail page and a "click" event with the userid, configured itemtype and the corresponding itemid is sent. The categorypath information should be included.  
A user logs in and changes to its pseudonymous. A "login" event is sent with the anonymous userid as sourceuser and the pseudonymous userid as targetuser  

For Publisher: A user consumes a detail page and a "consume" event with the given userid, configured itemtype and the corresponding itemid is sent

 

 

For Shop: A user puts an item in the shopping cart and a "basket" event is sent with the item's single price and quantity information  

For Shop: A user buys items and a "buy" event with single price and quantity information is sent for each distinct item after a successful buying process

 

 

A user rates an item and a rate event is sent  
A user clicks on a recommendation and a "clickrecommended" event with the name of the scenario that provided the recommendations is sent in the parameters.  
Recommendations are presented to a user and a "render" event with all displayed recommendations is sent.  
   
Getting recommendations
The endpoint is configurable  
BASIC Authentication is supported  
There are no cross site scripting issues  
Some fallback data is available if the reco engine is not responding  

 

External Links

[1] Representational state transfer - Wikipedia
http://en.wikipedia.org/wiki/Representational_state_transfer
[2]

Uniform Resource Identifier (URI): Generic Syntax
http://tools.ietf.org/html/rfc3986 

[3]

JSONP - Wikipedia
http://en.wikipedia.org/wiki/JSONP 

  • No labels