# Работа с рекомендательными виджетами

Вы можете использовать специальное API для получения рекомендаций в рамках любого типа веб-кампаний непосредственно в коде своего проекта. Результат возвращается в качестве набора товаров в JSON формате. Вот некоторые преимущества, которые дает использование данного API:

  • полный контроль над тем, как отображать рекомендации;
  • возможность добавлять кастомный прелоадер-скелетон;
  • дополнительная или пост-обработка данных из фида перед тем как отобразить виджет;
  • контроль над fallback - вы можете не отображать виджет, если стратегия ушла в fallback или сделать запрос к другой стратегии в этом случае;
  • использование динамических фильтров;
  • подмена контекста в запросе.

# Получение рекомендаций

Функция используется для получения рекомендаций на основе заданной стратегии или нескольких стратегий. Она позволяет запрашивать рекомендации с индивидуальными настройками и исключать дубликаты между разными стратегиями.

Синтаксис

GF.Recommendations.get(strategy, options, callback)

Параметры:

Параметр Тип Описание
strategy обязательно String | Array of objects Если strategy является строкой, то это идентификатор одной стратегии. Если  strategy является массивом объектов, то каждый объект должен содержать поле id (идентификатор стратегии) и может содержать дополнительные параметры options для каждой стратегии. В таком случае автоматически исключаются дубликаты в запрашиваемых стратегиях.
options обязательно Object Может быть пустым объектом.
Объект options:
context string опциональное свойство, в которое можно передать контекст для стратегии. По умолчанию используется контекст страницы с которой происходит вызов.
maxProducts int количество запрашиваемых товаров, по умолчанию 20. Максимально 50.
realtimeRules Array of objects опциональное свойство, в которое можно передать массив с динамическими фильтрами. Подробнее о них ниже.
callback обязательно function Коллбэк-функция, выполняемая после получения результата работы стратегии.
GF.Recommendations.get('1364138cfe9b4f979a044a32', {
	maxProducts: 10
}, function(err, data) {
    if (err) {
        // error handling
    }
    const recData = data;
})

Набор свойств товара в ответе зависит от настроек продуктового фида в секции.

{
    "wId": "63a98ddd11fad4619a0c05b0",
    "name": "Sample strategy name",
    "fId": "6336f2f22b77b4c6da026ad4",
    "fallback": false,
    "slots": [
        {
            "item": {
                "sku": "1000001",
                "group_id": "1000001",
                "categories": [
                    "Женское",
                    "Платья",
                ],
                "in_stock": true,
                "name": "Платье из вискозы и шерсти",
                "price": "29900",
                "url": "...html",
                "image_url": "https://...image.png",
            },
            "fallback": false,
            "strId": 3
        },
        ...
    ]
}
GF.Recommendations.get(
  ['6406d885d9ea38c202022a73', '1364138cfe9b4f979a044a32'],
  {
    maxProducts: 5,
    realtimeRules:[]
  },
  function (err, data) {
    console.log(data);
  },
);

GF.Recommendations.get(
  [
	  { id: '1364138cfe9b4f979a044a32' }, 
	  { id: '1364138cfe9b4f979a044a32', maxProducts: 2 }
	],
  {
    maxProducts: 5,
    realtimeRules:[],
    context: { type:"PRODUCT", data:["123123"], lng:"spb" }
  },
  function (err, data) {
    console.log(data);
  },
);

# Трекинг рекомендаций

Чтобы отслеживать аналитику рекомендательного виджета, который вы вручную добавили на свой сайт с помощью Client-Side API, необходимо определенным образом разметить виджет и вызвать дополнительную функцию трекинга. Для настройки трекинга используются данные, полученные в ответе API.

Блок, содержащий товары виджета должен иметь дата-атрибуты:

  • data-sl-widget-id - wId из JSON ответа, идентификатор стратегии
  • data-sl-feed-id - fId из JSON ответа, идентификатор фида
  • data-sl-fallback - fallback из JSON ответа, статус фолбека стратегии

Блок, содержащий товар должен иметь дата-атрибуты:

  • data-sl-product-id - sku из JSON ответа, артикул товара
  • data-sl-strategy-id - strId из JSON ответа, идентификатор типа стратегии, может отличаться у разных слотов
  • data-sl-product-fallback - fallback из JSON ответа товара, статус фолбека конкретного товара
  • data-sl-product-slot - порядковый номер товара в виджете, начинается с 0

Допускается произвольный уровень вложенности между блоком-контейнером и товаров.

<div 
   data-sl-widget-id="6308a8277asdf28f7b055a9d" 
   data-sl-feed-id="6308a8277asdf28f7b055a9d"
   data-sl-fallback="false" 
>
	<div 
     data-sl-product-fallback="false" 
     data-sl-product-id="123456" 
     data-sl-strategy-id="4"
     data-sl-product-slot="0" 
  >
     ...
  </div>
	
</div>

После того, как виджет вставлен на страницу необходимо вызывать функцию, которая будет отслеживать взаимодействие с виджетом:

Синтаксис

GF.Recommendations.track(element, variationData)

Параметры:

Параметр Тип Описание
element обязательно DOM element В данный параметр передается DOM элемент - контейнер, который был размечен дата-атрибутами (data-sl-widget-id и другими)
variationData Object Объект, содержащий информацию о том, к какой вариации относится данный виджет. Обязателен для использования внутри платформы (при создании кампании). Не требуется, если виджет создается вне платформы (без создания кампании)

Объект variationData:

{
      var: '${slVariationId}',
      ver: '${slVersionId}',
      exp: '${slExperienceId}',
      cam: '${slTagId}',
}
const element = document.querySelector([data-sl-widget-id="6308a8277asdf28f7b055a9d"]);
GF.Recommendations.track(element, {
      var: '${slVariationId}',
      ver: '${slVersionId}',
      exp: '${slExperienceId}',
      cam: '${slTagId}',
})

# Динамические правила

В некоторых случаях может появиться потребность в создании правила для стратегии, которое будет зависеть от условий, имеющихся в момент просмотра страницы. Для таких случаев существуют динамические фильтры, которые позволяют создавать правила в реальном времени и получать рекомендации на основании данных, полученных в ходе сеанса. Например, показывать товары по более высокой цене, чем те, которые пользователь просматривает в данный момент, или предлагать товары на основе известных данных о пользователе.

# Распространные варианты использования

  • Предложения по бесплатной доставке: рекомендуемые товары, которые попадают в ценовой диапазон, позволяющий пользователю получить бесплатную доставку (выше порогового значения).
  • Рекомендовать товары в определенном диапазоне относительно просматриваемого товара, например, от 80% до 150% от текущей цены товара.
  • Рекомендовать товары исходя из параметров URL, например, отфильтрованная страница категории по бренду.
  • Рекомендовать товары исходя из количества бонусных баллов пользователя в системе лояльности.

Фильтры передаются как массив объектов realtimeRules в параметрах запроса рекомендаций.

Описание параметров правила

Параметр Тип Описание
id number Уникальный идентификатор правила. Если передавать несколько правил с одним идентификатором - выполнится только первое.
type* string Правило может либо включать определенные товары, либо исключать. В зависимости от этого передается include или exclude
slots* array of numbers Слоты на которое распространяется правило, пустой массив для всех слотов, начиная с 1.
query* object
query.conditions* array of objects Массив условий правила, которые будут работать как логическое И
query.conditions[].field* string Название колонки фида, к которой относится правило
query.conditions[].arguments array of objects Массив условий правила, которые будут работать как логическое ИЛИ внутри конкретной колонки фида.
query.conditions[].arguments[].action string Способ сравнения. Может принимать следующие значения: equal, not_equal, more, more_or_equal, less, less_or_equal, contains
query.conditions[].arguments[].value array Массив значений, если передано больше одного - будет работать как логическое ИЛИ
GF.Recommendations.get(
	'6634e31af6df45aa130d31d8', {
		maxProducts: 20,
		realtimeRules: [{
				"query": {
					"conditions": [{
						"field": "categories",
						"arguments": [{
							"action": "equal",
							"value": [
								"Столы"
							]
						}, {
							"action": "equal",
							"value": [
								"Стулья"
							]
						}]
					}]
				},
				"type": "include",
				"slots": [1]
			},

		],
	},
	function(err, data) {
		// process data
	},
);
const currentProductPrice = 10000;
const minPrice = currentProductPrice * 0.8;
const maxPrice = currentProductPrice * 1.5;

GF.Recommendations.get(
	'6634e31af6df45aa130d31d8', {
		maxProducts: 20,
		realtimeRules: [{
				"query": {
					"conditions": [{
						"field": "price",
						"arguments": [{
							"action": "more",
							"value": [
								minPrice
							]
						}]
					}, {
						"field": "price",
						"arguments": [{
							"action": "less",
							"value": [
								maxPrice
							]
						}]
					}]
				},
				"type": "include",
				"slots": []
			},

		],
	},
	function(err, data) {
		console.log(data.slots.map(s => s.item.price))
	},
);