Skip to content

Commit

Permalink
js client for Recombee recommendation API
Browse files Browse the repository at this point in the history
  • Loading branch information
OndraFiedler committed Nov 5, 2018
0 parents commit 791e8ae
Show file tree
Hide file tree
Showing 30 changed files with 8,351 additions and 0 deletions.
76 changes: 76 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# nyc test coverage
.nyc_output

# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# TypeScript v1 declaration files
typings/

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
.env

# parcel-bundler cache (https://parceljs.org/)
.cache

# next.js build output
.next

# nuxt.js build output
.nuxt

# vuepress build output
.vuepress/dist

# Serverless directories
.serverless

# FuseBox cache
.fusebox/
77 changes: 77 additions & 0 deletions .neutrinorc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
module.exports = {
use: [
['@neutrinojs/fork', {
configs: {
minified: {
use: [
(neutrino) => {
lib = require('./../../../util/neutrino-library');

lib(neutrino, {
name: 'recombee',
filename: 'recombee-api-client.min.js',
minify: true,
target: 'web',
externals: {
whitelist: ['jssha']
},
babel: {
presets: [
['babel-preset-env', {
targets: {
browsers: [
'last 2 Chrome versions',
'last 2 Firefox versions',
'last 2 Edge versions',
'last 2 Opera versions',
'last 2 Safari versions',
'last 2 iOS versions',
'> 2% in BE'
]
}
}]
]
}
});
}
]
},

nonminified: {
use: [
(neutrino) => {
lib = require('./../../../util/neutrino-library');

lib(neutrino, {
name: 'recombee',
filename: 'recombee-api-client.js',
minify: false,
target: 'web',
externals: {
whitelist: ['jssha'],
},
babel: {
presets: [
['babel-preset-env', {
targets: {
browsers: [
'last 2 Chrome versions',
'last 2 Firefox versions',
'last 2 Edge versions',
'last 2 Opera versions',
'last 2 Safari versions',
'last 2 iOS versions',
'> 2% in BE'
]
}
}]
]
}
});
}
]
},
}
}]
]
};
237 changes: 237 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
# Recombee API Client

A javascript library for easy use of the [Recombee](https://www.recombee.com/) recommendation API.

It is intended for usage in browsers and other client side integrations (such as in React Native / NativeScript mobile apps). For Node.js SDK please see [this repository](https://github.com/recombee/node-api-client).

Documentation of the API can be found at [docs.recombee.com](https://docs.recombee.com/).

## Installation

The library is [UMD](https://github.com/umdjs/umd) compatible.

### <script> tag

You can download [recombee-api-client.min.js](./dist/recombee-api-client.min.js) and host it at your site, or use a CDN such as [jsDelivr](https://www.jsdelivr.com/) CDN:

```js
<script src="https://cdn.jsdelivr.net/gh/recombee/[email protected]/dist/recombee-api-client.min.js"></script>
```

### npm
Use `npm` also for React Native / NativeScript applications.
```
npm install recombee-js-api-client --save
```

### Bower

```
bower install recombee-js-api-client -S
```

## How to use

This library allows you to request recommendations and send interactions between users and items (views, bookmarks, purchases ...) to Recombee. It uses the **public token** for authentication.

It is intentionally not possible to change item catalog (properties of items) with public token, so you should use one of the following ways to send it to Recombee:

- Use one of the server-side SDKs (Node.js, PHP, Java...). The synchronization can done for example by a peridodically ran script. See [this section](https://docs.recombee.com/gettingstarted.html#managing-item-catalog) for more details.
- Set a product feed at [Recombee web admin](https://admin.recombee.com/).

### Sending interactions

```javascript
// Initialize client with name of your database and PUBLIC token
var client = new recombee.ApiClient('name-of-your-db', '...db-public-token...');

//Interactions take Id of user and Id of item
client.send(new recombee.AddBookmark('user-13434', 'item-256'));
client.send(new recombee.AddCartAddition('user-4395', 'item-129'));
client.send(new recombee.AddDetailView('user-9318', 'item-108'));
client.send(new recombee.AddPurchase('user-7499', 'item-750'));
client.send(new recombee.AddRating('user-3967', 'item-365', 0.5));
client.send(new recombee.SetViewPortion('user-4289', 'item-487', 0.3));

```

### Requesting recommendations

You can [recommend items to user](https://docs.recombee.com/api.html#recommend-items-to-user) or [recommend items to item](https://docs.recombee.com/api.html#recommend-items-to-item).

It is possible to use callbacks or Promises.

#### Callback
Callback function take two parameters:

- *err* - `null` if request succeeds or `Error` object
- *res* - object containg reply from Recombee

```javascript

var callback = function (err, res) {
if(err) {
console.log(err);
// use fallback ...
return;
}
console.log(res.recomms);
}

// Get 5 recommendations for user-13434
client.send(new recombee.RecommendItemsToUser('user-13434', 5), callback);
```


#### Promise

```javascript
// Get 5 recommendations related to 'item-365' viewed by 'user-13434'
client.send(new recombee.RecommendItemsToItem('item-356', 'user-13434', 5))
.then(function(res) {
console.log(res.recomms);
})
.catch(function(error) {
console.log(error);
// use fallback ...
});

```

#### Optional parameters
Recommendation requests accept various optional parameters (see [the docs](https://docs.recombee.com/api.html#recommendations)). Following example shows some of them:

```javascript
client.send(new recombee.RecommendItemsToUser('user-13434', 5,
{
returnProperties: true, // Return properties of the recommended items
includedProperties: ['title', 'img_url', 'url', 'price'], // Use these properties to show
// the recommended items to user
filter: "'title' != null AND 'availability' == \"in stock\"",
// Recommend only items with filled title
// which are in stock
scenario: 'homepage' // Label particular usage
}
), callback);


```

## Integration Example

### 1. Create instant account at recombee.com


### 2. Upload items catalog
You can use a [script](https://docs.recombee.com/gettingstarted.html#managing-item-catalog) or set a product feed at [Recombee web admin](https://admin.recombee.com/). We will set following sample Google Merchant product feed: [product_feed_sample.xml](./examples/product_feed_sample.xml).
You will see the items in web interface after the feed is processed.

### 3. Use client to send interaction and get recommendations

Let's assume we want to show recommendations at product page of pants `product-270` to user with id `user-1539`. The following HTML+js sample send the detail view of the product by the user and request 3 related items from Recombee:
```html
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
</head>
<body>
<div class="container">
<div class="row">
<h1>Related products</h1>
<div class="col-md-12">
<div class="row" id='relatedProducts'>
</div>
</div>
</div>
</div>

<script src="https://cdn.jsdelivr.net/gh/recombee/[email protected]/dist/recombee-api-client.min.js"></script>

<script type="text/javascript">
// A simple function for rendering a box with recommended product
function showProduct(title, description, link, imageLink, price){
return [
'<div class="col-md-4 text-center col-sm-6 col-xs-6">',
' <div class="thumbnail product-box" style="min-height:300px">',
' <img src="' + imageLink +'" alt="" />',
' <div class="caption">',
' <h3><a href="' + link +'">' + title + '</a></h3>',
' <p>Price : <strong>$ ' + price + '</strong> </p>',
' <p>' + description+ '</p>',
' <a href="' + link +'" class="btn btn-primary" role="button">See Details</a></p>',
' </div>',
' </div>',
'</div>'
].join("\n")
}
// Initialize client
var client = new recombee.ApiClient('js-client-example', 'dXx2Jw4VkkYQP1XU4JwBAqGezs8BNzwhogGIRjDHJi39Yj3i0tWyIZ0IhKKw5Ln7');
var itemId = 'product-270';
var userId = 'user-1539'
// Send detail view
client.send(new recombee.AddDetailView(userId, itemId));
// Request recommended items
client.send(new recombee.RecommendItemsToItem(itemId, userId, 3,
{
returnProperties: true,
includedProperties: ['title', 'description', 'link', 'image_link', 'price'],
filter: "'title' != null AND 'availability' == \"in stock\"",
scenario: 'related_items'
}),
(err, resp) => {
if(err) {
console.log("Could not load recomms: ", err);
return;
}
// Show recommendations
var recomms_html = resp.recomms.map(r => r.values).
map(vals => showProduct(vals['title'], vals['description'],
vals['link'], vals['image_link'], vals['price']));
document.getElementById("relatedProducts").innerHTML = recomms_html.join("\n");
}
);
</script>

</body>
</html>
```
You should see something like this:

<a href="./examples/related_products.png"><img src="./examples/related_products.png" alt="Related products" width="500"/></a>


Please notice how the properties returned by `returnProperties`&`includedProperties` were used to show titles, images, descriptions and URLs.

### Remark on user identification

In order to achieve personalization, you need a unique identifier for each user. An easy way can be using Google Analytics for this purpose. The example then becomes:
```javascript
ga('create', 'UA-XXXXX-Y', 'auto'); // Create a tracker if you don't have one
// Replace the UA-XXXXX-Y with your UA code from Google Analytics.

var client = new recombee.ApiClient('js-client-example', 'dXx2Jw4VkkYQP1XU4JwBAqGezs8BNzwhogGIRjDHJi39Yj3i0tWyIZ0IhKKw5Ln7');

ga(function(tracker) {
var userId = tracker.get('clientId'); // Get id from GA

client.send(new recombee.RecommendItemsToUser(userId, 3,
{
returnProperties: true,
includedProperties: ['title', 'description', 'link', 'image_link', 'price'],
filter: "'title' != null AND 'availability' == \"in stock\"",
scenario: 'homepage'
}),
(err, resp) => { ... }
);
});

```

This time [RecommendItemsToUser](https://docs.recombee.com/api.html#recommend-items-to-user) is used - it can be used for example at your homepage.
Loading

0 comments on commit 791e8ae

Please sign in to comment.