diff --git a/docs/administration/admin_panel/segments_admin_panel.md b/docs/administration/admin_panel/segments_admin_panel.md index a3debe34a83..1f9e3e144c7 100644 --- a/docs/administration/admin_panel/segments_admin_panel.md +++ b/docs/administration/admin_panel/segments_admin_panel.md @@ -6,7 +6,7 @@ edition: experience # Segments You can use segments to display specific content to specific [users](users.md). -They're used out of the box in the Targeting and Dynamic targeting blocks in the page. +They're used out of the box in the Targeting block in the page. You can collect segments in segment groups: @@ -16,4 +16,4 @@ Each segment group can contain segments that you can target content for. ![Segment](admin_panel_segment.png) -You can assign users to segments [through the API](segment_api.md#assigning-users). \ No newline at end of file +You can assign users to segments [through the API](segment_api.md#assigning-users). diff --git a/docs/administration/project_organization/architecture.md b/docs/administration/project_organization/architecture.md index 56b723c31cc..1c687800815 100644 --- a/docs/administration/project_organization/architecture.md +++ b/docs/administration/project_organization/architecture.md @@ -31,5 +31,3 @@ The architecture of [[= product_name =]] is layered and uses clearly defined API | [Solr Storage Engine](solr_overview.md) | Transparent drop-in replacement for the SQL-based Legacy search engine. | | [IO](file_management.md#native-io-handler) | The IO API is organized around two types of handlers, both used by the IOService. | | [IO Handler](clustering.md#dfs-io-handler) | The IO Handler manipulates metadata, making up for the potential inconsistency of network-based filesystems. | -| [Recommendation](enable_personalization.md) | Recommendation API. | -| [Personalization server](enable_personalization.md) | Personalization server allows displaying recommendations on the website. | diff --git a/docs/administration/project_organization/bundles.md b/docs/administration/project_organization/bundles.md index 1f94922e020..dd92d8b382a 100644 --- a/docs/administration/project_organization/bundles.md +++ b/docs/administration/project_organization/bundles.md @@ -83,7 +83,6 @@ To remove a bundle (either one you created yourself, or an out-of-the-box one th |ibexa/migrations|[Migration of repository data](data_migration.md)| |[ibexa/oauth2-client](oauth_client.md)|Authenticate user through a third-party OAuth 2 server, integration with [`knpuniversity/oauth2-client-bundle`](https://github.com/knpuniversity/oauth2-client-bundle)| |[ibexa/oauth2-server](oauth_server.md)|Allow resource access to OAuth 2 client| -|ibexa/personalization|Functionality for personalized recommendations| |ibexa/product-catalog|Product catalog functionality| |ibexa/scheduler|Date-based publishing functionality| |ibexa/seo|Search Engine Optimization (SEO) tool| @@ -91,7 +90,6 @@ To remove a bundle (either one you created yourself, or an out-of-the-box one th |ibexa/tree-builder|Tree builder functionality| |ibexa/version-comparison|Enables comparing between two versions of the same field| |ibexa/workflow|Collaboration feature that enables you to send content draft to any user for a review or rewriting| -|ibexa/recommendation-client|Client for connecting with the personalization engine **deprecated**| |ibexa/commerce-base-design|Standard design and theme for the shop **deprecated** | |ibexa/commerce-checkout|Shop checkout functionality **deprecated** | |ibexa/commerce-fieldtypes|Shop-specific field types **deprecated** | diff --git a/docs/cdp/cdp_activation/cdp_data_export.md b/docs/cdp/cdp_activation/cdp_data_export.md index d2b13ba2a1f..9eab26277fb 100644 --- a/docs/cdp/cdp_activation/cdp_data_export.md +++ b/docs/cdp/cdp_activation/cdp_data_export.md @@ -67,7 +67,7 @@ In the **Transform & Map** section you transform data and map it to a schema. At this point, you can map **email** to **email** and **id** to **integer** fields to get custom columns. If you have [extended user data export with custom fields](cdp_data_customization.md#export-additional-user-data), those fields appear as additional columns in this section. -Make sure to add them to your schema in Raptor so they can be used for segmentation and personalization. +Make sure to add them to your schema in Raptor so they can be used for segmentation. Next, select **Create schema based on the downloaded columns**. It moves you to Schema Creator. diff --git a/docs/cdp/cdp_data_customization.md b/docs/cdp/cdp_data_customization.md index 7b18480f73f..8fb6cd4f8ae 100644 --- a/docs/cdp/cdp_data_customization.md +++ b/docs/cdp/cdp_data_customization.md @@ -12,7 +12,7 @@ It casts their `Value` object to string, thanks to `\Stringable` implementation. ## Export additional user data You can extend user data exported to CDP by attaching custom information, for example user content fields or user preferences. -Use it for advanced customer segmentation and personalization in marketing campaigns. +Use it for advanced customer segmentation in marketing campaigns. To add custom data to user exports, create a class that extends [`\Ibexa\Contracts\Cdp\Export\User\AbstractUserItemProcessor`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-Cdp-Export-User-AbstractUserItemProcessor.html) and implement the `doProcess()` method. The base class handles user field validation and provides helper methods for working with user content. diff --git a/docs/cdp/cdp_guide.md b/docs/cdp/cdp_guide.md index 18de2e1d9d0..998e9fe2949 100644 --- a/docs/cdp/cdp_guide.md +++ b/docs/cdp/cdp_guide.md @@ -51,9 +51,9 @@ This approach helps you create a single customer view. To create a personalized customer experience, you need to group your clients into specified audiences. [[= product_name =]] comes with a ready solution - segment groups. -Segment group information is reused by various [[= product_name =]] functionalities, such as [Personalization](personalization_guide.md) or content targeting. +Segment group information is reused by various [[= product_name =]] functionalities, such as content targeting. -You can [create a segment group]([[= user_doc =]]/personalization/segment_management/) in the back office of [[= product_name =]]. +You can [create a segment group](segments_admin_panel.md) in the back office of [[= product_name =]]. It serves as a container for all segments data generated by [[= product_name_cdp =]]. When you create a segment group, you need to provide its name and identifier. Be careful while doing so, as after you create the segment group in the back office and connect it to [[= product_name_cdp =]], you cannot change it in any way, including edit its name. diff --git a/docs/commerce/transactional_emails/extend_transactional_emails.md b/docs/commerce/transactional_emails/extend_transactional_emails.md index 665ed1cb9a5..cee66585ef9 100644 --- a/docs/commerce/transactional_emails/extend_transactional_emails.md +++ b/docs/commerce/transactional_emails/extend_transactional_emails.md @@ -73,7 +73,7 @@ final class TransactionalMailFactoryEventSubscriber implements EventSubscriberIn ## Customize Actito end-user profile The Actito platform offers many features for customer data collection, including segmentation, subscriptions, and interaction tracking. -This information can be later user for generating statistics, establishing trends, or used to calculate Personalization recommendations. +This information can be later user for generating statistics or establishing trends. To use these features you need to provide profile data to API requests yourself. You do it by means of events that are triggered during profile building. @@ -164,4 +164,4 @@ final class ResolveCampaginEventSubscriber implements EventSubscriberInterface $event->setCampaign($campaign); } } -``` \ No newline at end of file +``` diff --git a/docs/content_management/pages/page_builder_guide.md b/docs/content_management/pages/page_builder_guide.md index 3d8e382086d..566b6dc7d67 100644 --- a/docs/content_management/pages/page_builder_guide.md +++ b/docs/content_management/pages/page_builder_guide.md @@ -213,18 +213,14 @@ Additionally, Page Builder offers you a selection of ready-to-use page blocks th A. **Default** blocks: -- Dynamic targeting - embeds recommended items based on the segment the user belongs to. -- Personalized - displays a list of content items/products that are recommended to end users when specific scenarios are triggered. - Targeting - embeds a content item based on the segment the user belongs to. B. **PIM** blocks: -- Last purchased - displays a list of products that were recently purchased from PIM. -- Last viewed - displays a list of products from PIM that were recently viewed. +- Catalog - displays products from a specific catalog to a selected customer group. - Product collection - displays a list of specifically selected products. -- Recently added - displays a list of products that were recently added to PIM. +- Product embed - displays a specific product. C. **Commerce** blocks: -- Bestsellers - displays a list of products from PIM that were recently a bestseller. - Orders - displays a list of orders associated with a particular company or individual customer. diff --git a/docs/customer_management/customer_portal_guide.md b/docs/customer_management/customer_portal_guide.md index b8991585162..8ca9a9aeac2 100644 --- a/docs/customer_management/customer_portal_guide.md +++ b/docs/customer_management/customer_portal_guide.md @@ -179,6 +179,6 @@ Customer portals help you to automate tasks that otherwise would be done by your An additional benefit of customer portals is their availability 24/7. Thus, reducing the need to allocate resources to extend working hours or hire more employees. -### Localization and personalization +### Localization -The use of Page Builder in the Customer Portal creation process enables you to create unique experiences for each business customer based on their location, business type, company, or market they operate on. \ No newline at end of file +The use of Page Builder in the Customer Portal creation process enables you to create unique experiences for each business customer based on their location, business type, company, or market they operate on. diff --git a/docs/ibexa_products/editions.md b/docs/ibexa_products/editions.md index 30c1031cc27..d77aea65ed6 100644 --- a/docs/ibexa_products/editions.md +++ b/docs/ibexa_products/editions.md @@ -30,7 +30,6 @@ Compare all features available in [[= product_name_headless =]], [[= product_nam | [Editorial workflow]([[= user_doc =]]/content_management/workflow_management/editorial_workflow/) | ✔ | ✔ | ✔ | | [Digital Asset Management]([[= user_doc =]]/dam/ibexa_dam/) | ✔ | ✔ | ✔ | | [Product Information Management]([[= user_doc =]]/pim/pim/) | ✔ | ✔ | ✔ | -| [Personalization](personalization_guide.md) | ✔ | ✔ | ✔ | | [Migrations](managing_migrations.md) | ✔ | ✔ | ✔ | | [[[= product_name_connect =]]]([[= connect_doc =]]/) | ✔ | ✔ | ✔ | | [OAuth client](oauth_client.md) | ✔ | ✔ | ✔ | diff --git a/docs/ibexa_products/ibexa_commerce.md b/docs/ibexa_products/ibexa_commerce.md index 2a99fc715ca..e702c09ba31 100644 --- a/docs/ibexa_products/ibexa_commerce.md +++ b/docs/ibexa_products/ibexa_commerce.md @@ -94,14 +94,6 @@ With this feature you can also [create email campaigns](transactional_emails.md# ### Use cases -#### Create personalized shipping experience - -Use [Ibexa Personalization]([[= user_doc =]]/personalization/use_cases/#ecommerce) to transform your online stores and give your consumers great buying experiences, from initial contact to post-purchase support. -No matter how complicated your product or sales process are, you can present your offer in an approachable way. -Creating engaging and personalized shopping experiences with targeted offers and recommendations helps you boost sales. -Within eCommerce, product recommendations can assist users in finding the exact item that meets their needs. -Recommendations can be used to propose related, alternative, or complimentary products to users who are unsure what to buy. - #### Use effective merchandising Merchandising assists in keeping the consistency of the brand and providing customized product recommendations with captivating visuals and powerful search features. diff --git a/docs/ibexa_products/ibexa_experience.md b/docs/ibexa_products/ibexa_experience.md index 02836622090..3e33409d2c1 100644 --- a/docs/ibexa_products/ibexa_experience.md +++ b/docs/ibexa_products/ibexa_experience.md @@ -96,7 +96,6 @@ Using this tool, your customers can change their organization details, invite an [Segmentation](https://doc.ibexa.co/en/latest/administration/admin_panel/segments_admin_panel/) allows you to split up the user base. By assigning users to segments, you can display specific content to selected visitors and tailor the content that they can see. One of the tools that you can use right out of the box is the Targeting block that is available in the Page Builder. -Segmentation is also useful with the [Personalization](personalization_guide.md). You can assign users to different recommendation groups and create advanced logic with operators to provide your audience with the best recommendations. ![Segments](segments.png) diff --git a/docs/ibexa_products/ibexa_headless.md b/docs/ibexa_products/ibexa_headless.md index f1285f5a2e7..55ca8eea290 100644 --- a/docs/ibexa_products/ibexa_headless.md +++ b/docs/ibexa_products/ibexa_headless.md @@ -109,8 +109,6 @@ On top of this strong core, [[= product_name_headless =]] brings tools to increa [[= product_name_headless =]] is a complete Digital Experience Platform (DXP), which comes with the following components to enhance user's journey: -- [Personalization](personalization_guide.md) engine, which allows you to recommend content to end users according to their behavior, - or, when authenticated, by matching with their segment/group. - Content scheduler, which allows you to establish the future of the content and use events to have a living front application, even when the editorial team is absent or reduced. This way, visitors can discover new content at midnight, during weekends or vacations. A calendar summarises those scheduled content events. diff --git a/docs/multisite/siteaccess/siteaccess.md b/docs/multisite/siteaccess/siteaccess.md index a4e8d747e53..85352bcebc4 100644 --- a/docs/multisite/siteaccess/siteaccess.md +++ b/docs/multisite/siteaccess/siteaccess.md @@ -15,7 +15,6 @@ Each SiteAccess can have different: - [languages](set_up_translation_siteaccess.md) - [tree roots](multisite_configuration.md#location-tree) - [repositories](persistence_cache.md#multi-repository-setup) -- [recommendations](enable_personalization.md#configure-personalization) Many other settings in the application are also configured per SiteAccess (also known as "SiteAccess-aware"). diff --git a/docs/permissions/limitation_reference.md b/docs/permissions/limitation_reference.md index a4fa06fead8..f419127f852 100644 --- a/docs/permissions/limitation_reference.md +++ b/docs/permissions/limitation_reference.md @@ -282,10 +282,6 @@ The Payment Owner (`PaymentOwner`) limitation specifies whether the user can mod |"self"|"self"|Users can access only their own payments. | |"all"| none |Users can access all payments.| -## Personalization access limitation - -The Personalization limitation specifies the SiteAccesses for which the user can view or modify the scenario configuration. - ## Product Type limitation The Product Type (`ProductType`) limitation specifies whether the user has access to products belonging to a specific product type. diff --git a/docs/permissions/limitations.md b/docs/permissions/limitations.md index 5ae896c7870..7fff90b6a34 100644 --- a/docs/permissions/limitations.md +++ b/docs/permissions/limitations.md @@ -15,7 +15,7 @@ Limitations consist of two parts: - `LimitationType` Certain limitations also serve as role limitations, which means they can be used to limit the rights of a role assignment. -Currently, this covers [subtree of location](limitation_reference.md#subtree-limitation), [Section](limitation_reference.md#section-limitation) and [Personalization access](limitation_reference.md#personalization-access-limitation) limitations. +Currently, this covers [subtree of location](limitation_reference.md#subtree-limitation) and [Section](limitation_reference.md#section-limitation) limitations. `Limitation` represents the value, while `LimitationType` deals with the business logic surrounding how it actually works and is enforced. `LimitationTypes` have two modes of operation in regard to permission logic (see [`Ibexa\Contracts\Core\Limitation`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-Core-Limitation-Type.html) interface for more info): diff --git a/docs/permissions/policies.md b/docs/permissions/policies.md index 8feca26b336..eefdd8a9095 100644 --- a/docs/permissions/policies.md +++ b/docs/permissions/policies.md @@ -49,13 +49,6 @@ Each role you assign to user or user group consists of policies which define, wh | | `edit` | edit a customer group | | | `view` | view customer groups | -#### Personalization - -| Module | Function | Effect | Possible limitations | -|--------------------------------|---------------------|-------------------------------------------------------------------|-------------------------------------------------------------------------------------| -| `personalization` | `edit` | modify scenario configuration for selected SiteAccesses | [Personalization access](limitation_reference.md#personalization-access-limitation) | -| | `view` | view scenario configuration and results for selected SiteAccesses | [Personalization access](limitation_reference.md#personalization-access-limitation) | - #### Roles | Module | Function | Effect | Possible limitations | diff --git a/docs/personalization/api_reference/api_reference.md b/docs/personalization/api_reference/api_reference.md deleted file mode 100644 index 7910d079410..00000000000 --- a/docs/personalization/api_reference/api_reference.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -description: Explore Personalization API sets that let you manage item data, track events, combine tracking data with users and render recommendations. -page_type: landing_page ---- - -# Personalization API - -This section provides documentation for the Personalization API operations. - -[[= cards([ - "personalization/api_reference/tracking_api", - "personalization/api_reference/content_api", - "personalization/api_reference/recommendation_api", - "personalization/api_reference/user_api", -], columns=4) =]] diff --git a/docs/personalization/api_reference/content_api.md b/docs/personalization/api_reference/content_api.md deleted file mode 100644 index 24777406186..00000000000 --- a/docs/personalization/api_reference/content_api.md +++ /dev/null @@ -1,220 +0,0 @@ ---- -description: Personalization server can use external information about the items. Use HTTP methods to create, update or get items from the data store. ---- - -# Content API - -Apart from the [events]([[= user_doc =]]/personalization/event_types/) collected by the Personalization client, the Personalization server can use external information about the products. -This information must be uploaded to the Personalization server by the administrator of the website. - -The following information can be loaded to the recommendation solution: - -- Product price - Products cheaper than the specified threshold can be filtered out from recommendations -- Availability timeframe - Certain products are be recommended only in the specified time window -- Custom attributes - You can group recommendations and narrow down the results, for example, to non-food products or to news that are related to the end user's city - -For more information about personalization, see [Introduction](personalization.md) and [Best practices](recommendation_integration.md). - -The Personalization client provides a REST interface that accepts items in XML format. -You can use the interface to post item information within the request's body into the store, and to display or update the items directly. - -You can use HTTP methods to create, update or retrieve items that are in the data store. - -!!! note "Authentication" - - For getting or posting content data, basic authentication is enabled by default. - Use your customer ID and license key as username and password. - If authentication is enabled for recommendation requests and you want to change this, contact support@ibexa.co. - -## GET requests - -Use the GET method to retrieve all information that is stored in the database for the given item ID: - -`GET: https://admin.perso.ibexa.co/api/[customerid]/item/[itemtypeid]/[itemid]` - -## POST requests - -Use the POST request to create or update items with the given ID in the database: - -`POST: https://admin.perso.ibexa.co/api/[customerid]/item` - -A body of the request must contain a valid XML document. -Once uploaded, the item is scheduled to be inserted in the database, and isn't directly available. - -## DELETE requests - -Use the DELETE method to delete all information that is related to the given item ID. - -`DELETE: https://admin.perso.ibexa.co/api/[customerid]/item/[itemtypeid]/[itemid]?lang=` - -The item is scheduled to be removed from the database. - -## Request parameters - -The following call attributes are available: - -| Parameter name | Description | Value | -|---|---|---| -| `customerid` | A customer ID (for example "00000"), as defined when [enabling Personalization](enable_personalization.md#get-authentication-parameters). Can be used to identify a website in installations that [hosts multiple SiteAccesses]([[= user_doc =]]/personalization/use_cases/#multiple-website-hosting). | alphanumeric | -| `itemid` | A unique ID of the content item/product. Used to identify the item in the database. | integer | -| `itemtypeid` | An ID of the type of content item/product. In most cases, the value is 1 but you might have items/products of more than one type. | integer | -| `lang` | A [language code](languages.md) of the content item/product (for example, "ger-DE"). This parameter is optional. | string | - -### Request object format - -An XML representation of the data object used for item import can look like this: - -``` xml - - - - the item's description - 1234 - 2011-01-01T00:00:00 - 2021-01-01T00:00:00 - - /8/4/5 - /84 - /1/847 - - - - - - - - - - - - - - - - - - -``` - -!!! note "XML schema definition" - - The current schema that is used for interpreting the XML objects can be seen [here](https://admin.perso.ibexa.co/api/00000/item/schema.xsd). - -The following keys and attributes used in the XML object are available: - -|Key/Attribute | Description | Type | -|--- | --- | --- | -| `id` | A unique ID of the item/product. This parameter is required. | integer | -| `type` | An ID of the type of item/product. This parameter is required. | integer | -| `description`| Additional information about the item. | alphanumeric | -| `currency` | Currency used for the price. By default, prices are expressed in EUR. | ISO 4217 | -| `price` | The item's price in the currency's fractional units (for example, cents).
[See below for more information.](#price-and-currency) | integer | -| `validfrom` | Together with `validto`, defines the lifespan of an item.
If NULL or not available, the item is considered valid immediately.
See below for more information. | ISO 8601 | -| `validto` | Together with `validfrom`, defines the lifespan of an item.
If NULL or not available, the item is considered valid indefinitely.
See below for more information. | ISO 8601 | -| `categorypath` | A logical (website) navigation path through which the end user can reach the item/product in your website.
You can define multiple paths for the product.| alphanumeric, separated with "/" ("%2F") characters | - -!!! caution "Encoding limitation" - - Keys and their values can only contain letters, digits and underscore characters. - Attribute keys are case-sensitive. - -##### Price and currency - -The price is given as an integer in the fractional unit of the currency, which ends as removing the decimal separators. -For example: - -- 1234 for 12.34 Euro: `1234` -- 12 for 12 Japanese Yen: `12` -- 12345 for 12.345 Tunisian Dinar: `12345` - -To check how many digits the fractional unit of a currency has, see the [ISO 4217 standard](https://en.wikipedia.org/wiki/ISO_4217#List_of_ISO_4217_currency_codes). - -##### Validity - -Items with defined validity are recommended only in the specified timeframe. -Values in the `validto` and `validfrom` attributes must follow the [XSD format](https://www.w3.org/TR/xmlschema-2/#dateTime) and don't include the time zone. -Time zone is always your time zone. - -##### Category path - -With the data import interface, you can upload information about the paths to categories in which the product is located. -However, the category path can be also updated as a result of the "Click" events. -If you regularly upload product data, the "Click" event cannot contain the category path information. -Otherwise, the following negative side effects occur: - -- Every new category path attached to the "Click" event is appended to a list of the categories of the product -- Imported product data overwrites the collected category paths - -For example, when a product that is originally located under `Garden` is clicked in the "Hot Sellers" section, the category path `TopSeller` is sent. - -#### Content items/products with no attributes - -All the elements and attributes except the `type` and `id` are optional. -You can therefore upload a product without any additional information. -You do it, for example, when a random recommendation model is used or you want to want to apply ad-hoc boosting and filtering of recommendations. -As a result, the Personalization server randomly recommends the imported items/products. -This can prove useful for a news agency, where new items are published often. - -#### Custom attributes - -You can also define custom attributes under the `` key. -This section can only contain values that are distinct and used to build pre-filtered models. - -By default, it's assumed that every attribute is of type "NOMINAL", which means that there is a limited set of values, and values of an attribute are treated as distinct when calculating the results of a content-based model. - -If you have an attribute that is of type "NUMERIC", and you add another attribute of the same type, the Personalization server treats the two values as a range. - -``` xml - -``` - -However, if the other attribute is of type "NOMINAL", they're both treated as different and have no "distance-based similarity". - -Another typical example of a custom attribute is the color of an item. -To upload the value to the data store, add the following line under the `` key. - -``` xml - -``` - -You can have multiple attributes with the same name and different type. -For example, `size` can be expressed as a number (40.5) or as a code ("L"). - -## Responses - -### HTTP response codes - -The following HTTP response codes are used by the recommendation controller: - -|HTTP Status Code|Description| -|---|---| -|200 OK|The GET request was processed successfully.| -|202 Accepted|The POST or DELETE request was processed successfully.| -|400 Bad Request|Wrong request formatting. The XML content cannot be validated.| -|404 Not Found|The element requested by the GET or DELETE request was not found.| - -## Transferring item identifiers - -You could use the data import interface to help migrate the database, when it involves changing item IDs of items that are supported by the Personalization server. -If you transfer items from one ID to another, you can use the events recorded for "old" item IDs to calculate model results that present "new" IDs. - -Use the following method to pass the XML object: - -`POST: https://admin.perso.ibexa.co/api/[customerid]/transferitems` -`Content-Type=text/xml` - -``` xml - - - - - - -``` - -All related historical user data is rewritten to point to the new item. -The old item is wiped, including all attributes. - -!!! note - - The attributes of the "old" item ID aren't moved or merged, and if you rely on attributes, for example, for filtering based on prices, you must reimport the new item. diff --git a/docs/personalization/api_reference/recommendation_api.md b/docs/personalization/api_reference/recommendation_api.md deleted file mode 100644 index 42727e5e43c..00000000000 --- a/docs/personalization/api_reference/recommendation_api.md +++ /dev/null @@ -1,286 +0,0 @@ ---- -description: Use HTTP GET request method to render recommendations. -month_change: false ---- - -# Recommendation API - -Recommendations are retrieved from the Personalization server with RESTful requests that rely on the HTTP GET method. -The result is a list of item IDs that can then be used to call the underlying CMS or shop system and load the necessary information for the rendering process. - -For more information about Personalization, see [Introduction](personalization.md) and [Basic integration](recommendation_integration.md). - -!!! note "Authentication" - - For fetching recommendations, authentication is disabled by default, and it must be disabled when you use [JSONP](https://en.wikipedia.org/wiki/JSONP) for response handling. - If authentication is enabled for recommendation requests and you want to change this, contact support@ibexa.co. - -## GET requests - -The request for recommendations uses the following pattern: - -`GET https://reco.perso.ibexa.co/api/v2/[customerid]/[userid]/[scenarioid].[extension]?parameter=value&[attribute=attributekey]` - -## Request parameters - -For the request to return recommendations, you must provide the following parameters: - -|Parameter|Description|Value| -|---|---|---| -|`customerid`|A customer ID (for example "00000"), as defined when [enabling Personalization](enable_personalization.md#set-up-customer-credentials). Can be used to identify a website in installations that [hosts multiple SiteAccesses]([[= user_doc =]]/personalization/use_cases/#multiple-website-hosting).|alphanumeric| -|`userid`|An ID of the tracked user in the website (for example, an internal customer code, a session code, or a cookie for anonymous users.|alphanumeric| -|`scenarioid`|An ID of the scenario used for providing recommendations, as defined in the back office.|alphanumeric| -|`extension`|A format of the response (either JSON or JSONP).|`json` or `jsonp`| - -!!! caution "Parameter encoding limitations" - - All parameters must be URL-encoded (see RFC 3986) and cannot contain a backslash (`%5C`) character. - -### Customizing the recommendation request - -You can customize the recommendation request by using additional query string parameters. -For example, you can send the following request to the Personalization server:  - -`GET https://reco.perso.ibexa.co/api/v2/00000/john.doe/landing_page.json ?contextitems=123&categorypath=%2FCamera%2FCompact&attribute=title&attribute=deeplink,description&numrecs=8` - -The request fetches 8 recommendations for user ID `john.doe`, who is viewing item 123 and the category `/Camera/Compact`, based on the scenario with the identifier `landing_page`. -The recommendation response uses the JSON format and should include values of `title`, `deeplink` and `description` attributes. - -You can use the following parameters to customize a request: - -|Parameter|Example|Description|Value| -|---|---|---|---| -|`numrecs`|20|Defines a number of recommendations to be delivered. The lower this value, the shorter the response time. The default value is 10. |1 to 50| -|`contextitems`|10,13,14, or "CLICKED"|A comma-separated list of items that the user is viewing on the web page. The list is required by [context-based recommendations]([[= user_doc =]]/personalization/recommendation_models/). All items must be of the same type. The type is defined in the scenario configuration. If history code is used ("CLICKED","CONSUMED", "OWNS", "RATED" or "BASKET"), context items are pulled from the user profile (for example, the most recent clicks or purchases). This parameter is optional. |1 to 2147483647 (or alphanumeric if enabled)| -|`outputtypeid`|1|Required for scenarios that are defined with multiple output item types, otherwise optional. By default it's the first/lowest output type enabled in the scenario config.|numeric| -|`crosscontenttype`| |Used instead of `outputtypeid`, if set to true, displays recommendations for all output types defined in the scenario. | boolean| -|`jsonpCallback`|"myCallback"|Function or method name (used for JSONP request only). It can be a function ("callme"), or a method ("obj.callme"). The default value is "jsonpCallback".|legal JavaScript function call| -|`attribute`|"title" or "description"|If you apply this parameter, the engine tries to fetch the value of the attribute. For example, `&attribute=title` means fetching the title for the item that's delivered in the response, if available. The fetch works if content import has been successful. You can pass multiple attributes: `&attribute=title&attribute=description` or `&attribute=title,description`. Use this to pull "pure" client-based recommendations without requesting local customer data.|string| -|`categorypath`|`/Women/Shirts`|Category path for fetching recommendations. The format is the same as the category path used in event tracking. Add this parameter multiple times to get recommendations from multiple categories. The order of recommendations from different categories is defined by the calculated relevance. The default value is `%2F`, which stands for an entire website.|string[/string]* | -|`usecontextcategorypath`| |Used in conjunction with `categorypath`. If set to true, the category path of given context item(s) is resolved by the Personalization server from the internal store and used as base category path. If more than one category is returned, all categories are used for providing recommendations. Setting this parameter to true increases the response time. If possible, use the `categorypath` parameter to provide the category to the recommender engine during the request. The default value is false.|boolean| -|`recommendCategory`| |Used in conjunction with `categorypath`. If set to true, the neighboring category linked with the recommended items is delivered in the response as an additional field `category`. Helps find a suitable template for articles from several categories.
For example, take an article about American football. The article is categorized as `Sport/Football` and `America/USA`. Depending on the category, the webpage displays a football field or an American flag in the background. If the article is recommended and clicked in the `Sport/Cricket` category, it must open with the "field" template. If clicked in the `America/Canada` category, it must open with the "flag" template. The category is returned only if the article is located in several categories and the "closer" category is found. The default value is false.|boolean| -|`usetimeslot`| |If set to true, configured time-slots are active. As a result, recommendations are calculated for specific time frames and they have priority over the recommendations from the main model in the hours for which time slots are configured. Time slots must be enabled by and configured [[= product_name_base =]] Team.|true| - -##### Submodel parameters - -If your recommendation model uses submodels to group content items/products based on an attribute, you can pass the following parameters to request recommendations for a specific group. - -For more information, see [Submodels]([[= user_doc =]]/personalization/recommendation_models/#submodels). - -|Parameter|Example|Description|Value| -|---|---|---|---| -|attribute key|`&color=red`|Applicable if a submodel with the same name and value is configured.|string| -|`userattribute`|gender|If defined, the Personalization server tries to find the attribute value for the current user and, if found, "prefers" recommendations that are typically followed by users with the same value of the attribute. The default value is null.|string, CSV list| - -!!! note "Multiple submodels in recommendations" - - If you send a request with two attribute keys, the response contains an intersection of two recommendation sets that originate from submodels calculated for these attributes. - - For example, to get recommendations for items of certain type that are limited by submodels based on both a nominal and numeric attribute, you can send the following request: - - `GET https://reco.perso.ibexa.co/api/v2/00000/john.doe/landing_page.json?numrecs=50&outputtypeid=1&width-range=10:30&color=green` - -!!! note "Dynamic attribute submodels" - - If dynamic attribute submodels are enabled, you only need to add submodel parameters to the request to trigger dynamic submodels in the upcoming model build. - - Dynamic attribute submodels must be enabled by [[= product_name_base =]] Team. - To start using this functionality, contact support@ibexa.co. - - When enabled, to build dynamic attribute submodels, you need to send the request (which includes `"ATTRIBUTE_NAME=VALUE"` query parameters) to the scenario with model you want to use submodels for: - - `GET https://reco.perso.ibexa.co/api/v2/00000/john.doe/{SCENARIO_NAME}?numrecs=50&outputtypeid=1&color=red` - -##### Segment parameters - -If you have configured segments, you can use them in the recommendation model. Pass the following parameter to request recommendations for a specific segment or segment group. - -|Parameter|Example|Description|Value| -|---|---|---|---| -|`segments`|`&segments=7,8,10,11`|ID from segment group management|string| - -For more information, see [Segments]([[= user_doc =]]/personalization/segment_management/). - -## Responses - -The recommendation request returns information about the currently used context items and an array of recommendation objects in JSON or JSONP format. -The result can be integrated into any webpage on the client side by using script code. -To track user actions like "clickrecommended" and "rendered", use the links delivered in the response. - -For more information, see inline comments below. - -!!! note "Previewing recommendations" - - You can preview the actual responses that come from the Personalization server and how they're rendered in the user interface. - For more information, see [Previewing scenario results]([[= user_doc =]]/personalization/preview_scenario_results/). - -For more information about integrating recommendations in the web page, see [Best practices](recommendation_integration.md). - -### Response object format - -A JSON response can look like this: - -``` json -{ - "contextItems": [ // Information about the request's contextitems - { - "viewers": 134, // A number of users that were looking at this item - // (You could put the information on the currently viewed content item/product page as "Currently viewed by ### visitors".) - "itemType" : 1, - "itemId" : 10, - "sources" : "REQUEST" - }, - { - "viewers": 79, - "itemType" : 1, - "itemId" : 11, - "sources" : "REQUEST" - } - ], - "recommendationItems": [ - { // First recommendation - "relevance": 23, // A level of similarity to the current item, the higher the better - "itemType": 1, - "itemId": 100175717, - "origin": { - "itemIds" : [10, 11], // Items that the recommendations are based on (context or user history items), multiple values are possible - "itemType" : 1, - "source" : "REQUEST" // Possible options: REQUEST (parameter "contextitems") or CLICK, CONSUME, BUY, BASKET, RATE (user history) - }, - "category" : "Women/Shirts", // Provided only if category suggestion is requested - "links" : { - "clickRecommended" : "//event.perso.ibexa.co/api/[customerID]/clickrecommended/[someuser]/[itemtype]/[itemid]?scenario=&...", // A link that is provided if User ID is available. Link is fired when this recommendation is clicked. - "rendered" : "//event.perso.ibexa.co/..." // A link used to inform the engine that this recommendation was shown to the user - }, - "attributes" : [ // Only values that were requested in the query string are provided - { "key": "title", - "value": [ - "French Cuff Cotton Twill Oxford" - ] - }, ... - ] - }, - { // Second recommendation - "relevance": 22, - "itemType": 1, - "itemId": 100172819, - "origin": { - "itemIds" : [10, 11], - "itemType" : 1, - "source" : "REQUEST" - }, - ... - }, - ... - ] -} -``` - -A JSONP response can look like this (same comments apply): - -``` json -jsonpCallback({ - "contextItems": [ - { - "viewers": 134, - "itemType" : 1, - "itemId" : 10, - "sources" : "REQUEST" - }, - { - "viewers": 79, - "itemType" : 1, - "itemId" : 11, - "sources" : "REQUEST" - } - ], - "recommendationItems": [ - { - "relevance": 23, - "itemType": 1, - "itemId": 100175717, - "origin": { - "itemIds" : [10, 11], - "itemType" : 1, - "source" : "REQUEST" - }, - "category" : "Women/Shirts", - "links" : { - "clickRecommended" : "//event.perso.ibexa.co/api/[customerID]/clickrecommended/[someuser]/[itemtype]/[itemid]?scenario=&...", - "rendered" : "//event.perso.ibexa.co/..." - }, - "attributes" : [ - { "key": "title", - "value": [ - "French Cuff Cotton Twill Oxford" - ] - }, ... - ] - }, - { - "relevance": 22, - "itemType": 1, - "itemId": 100172819, - "origin": { - "itemIds" : [10, 11], - "itemType" : 1, - "source" : "REQUEST" - }, - ... - }, - ... - ] -}) -``` - -### HTTP response codes - -The following HTTP response codes are used by the recommendation controller: - -|HTTP Status Code|Description| -|---|---| -|200 OK|Request was processed successfully.| -|304 Not Modified|Recommendation result wasn't modified since the time specified in the provided `If-Modified-Since` header.| -|400 Bad Request
414 Request-URI Too Long|Wrong request formatting. See response body for more information.| -|401 Unauthorized|Invalid authentication credentials.| -|403 Forbidden|Access denied.| -|404 Not Found|The requested element wasn't found. It could be customer ID (or "mandator ID"), model ID, or scenario ID.| -|409 Conflict|The requested combination of models and recommendation parameters can't return recommendations. This could happen, for example, if you request personalized recommendations for a user who has no history.| -|500 Internal Server Error|Unspecified error. Contact [[= product_name_base =]] support if this error is recurring.| - -In case of errors, the response body contains human-readable error messages. -Error messages can change, don't use them for automated processing. - -!!! note "Rendering data" - - If data import with the [Content API](content_api.md) was successful, you can also fetch data used for rendering (for example "title", "description" or "deeplink") from the recommendation response. - -## Cache recommendations - -The Personalization server's response can be cached. -Depending on the recommendation model and context, it can drastically reduce the number of recommendation requests. -The recommendation service supports the following HTTP headers to enable cache control on the client side (all date values must follow the "HTTP-date" format as defined by [RFC 2616](https://datatracker.ietf.org/doc/html/rfc2616)): - -|Scope|Header|Description|Example| -|---|---|---|---| -|Request|`If-Modified-Since`|Enables returning the *304 Not Modified* code if content is unchanged.|`If-Modified-Since: Sat, 29 Oct 2013 19:43:31 GMT`| -|Response|`Last-Modified`|The last modification date of the recommendations.|`Last-Modified: Tue, 15 Nov 2013 12:45:26 GMT`| -|Response|`Expires`|Gives the date/time after which the response is outdated|`Expires: Thu, 01 Dec 2013 16:00:00 GMT`| - -The last modification timestamp indicates a change that could influence the recommendation response. -It depends on an updated recommendation calculation, an update of an item or certain scenario configuration changes.  - -The expiration timestamp is a best-effort prediction based on the model configuration and provided context. -The shortest expiration period is 5 minutes from the request time, the longest is 24 hours. - -You don't usually have to calculate the expiration time manually. -Instead, make sure that the `Expires` header is used in the configuration of your caching system and not a static value out of your configuration. - -To learn how Personalization server calculates the `Expires` header that's provided to your caching system, see the following table with caching strategy examples: - -| Model | Context | Expiration time | Description | -|------|------|-----|-----| -| Bestselling products (last 7 days) | No context | 24 hours | The model with the 7 days scope is usually built once a day. You can cache its results for 24 hours. It has no context, therefore it can be cached globally for all the users of the site. | -| Also bought products (last month) | Current product | 24 hours | The model with the 30 days scope is usually built once a day. The context is always the same, therefore it can be cached for every product, and the same result can be used for all users of the site. | -| Also consumed articles (last hour) | Current article | 30 minutes | Models with a short scope are usually built several times a day or even per hour. The expiration time is set to half of the model build frequency. | -| Personalized recommendation based on the user's statistic | User's click history | Now | Statistical models aren't updated within minutes, and it's likely that the context changes shortly (a user clicks another product, the click is added to their history). The expiration time shouldn't be much longer than the user's activity on the web page. | diff --git a/docs/personalization/api_reference/tracking_api.md b/docs/personalization/api_reference/tracking_api.md deleted file mode 100644 index 36d7c5058c4..00000000000 --- a/docs/personalization/api_reference/tracking_api.md +++ /dev/null @@ -1,543 +0,0 @@ ---- -description: Allows to track items based on an ID. It covers many content types with the same ID configured for tracking. ---- - -# Tracking API - -To provide recommendations, a tracking process needs to collect user behavior on the customer's site. -The most popular user events are: - -- Click - When a user opens a detail page. -- Buy/Consume - When a user buys an item or consumes content -- Rate - When a user likes, comments or rates an item -- Login - When a user logs in on a website -- Clickrecommended - When a user clicks a recommendation - -For a complete list of events, see [Event types]([[= user_doc =]]/personalization/event_types/) in User Documentation.  -Depending on the event type, some additional parameters, such as item price or user rating, must be provided. - -Importing historical user data can help you reduce the delay in delivery of high quality recommendations. - -For more information, see [Importing historical user tracking data](importing_historical_user_tracking_data.md). - -Apart from the tracking API, you can add tracking to the website by integrating a JavaScript library. - -For more information, see [Tracking with ibexa-tracker.js](tracking_with_ibexa-tracker.md). - -## Definitions - -You can use the tracking API both in eCommerce and content publishing scenarios. -eCommerce mostly uses the term "product", whereas the Publisher domain widely uses the terms "content", "article", "images" or "videos". -Therefore, a generic term "item" is used instead to cover all the mentioned types. -For further segmentation the term "item type" is used, which, in combination with the item ID itself, defines a domain specific object. - -For example, an electronic product can be defined by item type "1" and item id "3298", -while a textile product can be defined by item type "2" and item id "3298". - -!!! note - - Usually only one item type is sufficient in the eCommerce business as each product available in an eCommerce shop has a unique identifier. - -|Domain|Item ID|Item Type| -|---|---|---| -|Content publishing|Article|ID of an article| -|Content publishing|Video|ID of a video| -|Content publishing|Photo Gallery|ID of a photo gallery| - -Assuming the numbering of content is independent and the same item ID is used for two items of different item types, it's impossible to tell the difference if there is no segmentation by item types. - -If an article, a video and a photo gallery have the same item ID, use different item types to separate the items that are tracked. -For example: - -- item type "1" and itemid "29712" -> article -- item type "2" and itemid "29712" -> video -- item type "3" and itemid "29712" -> photo gallery - -!!! note - - Even if item IDs cannot overlap in a customer's system, [[= product_name_base =]] recommends using different item types to provide independent tracking and cross-item type recommendations, such as, for example, "Users who read this article also watched these videos" or "Users who liked this gallery also read these articles". - -## Identifiers - -### User identifier - -High quality recommendations can only be delivered if the underlying data is correct and consistent.  -For consistent tracking it's crucial to choose and use a consistent identifier for a user. -A user usually visits a website anonymously. -Therefore, their identifier is either a first-party cookie or a session ID provided by the website.  -If there is no existing user ID handling that can be re-used, it's recommended that you use your own cookie and set the expiry date to at least 90 days from the last usage. -If there is a login mechanism, the user is usually tracked with a temporary identifier before the login. -Immediately after a successful login process a Login event must be sent. -At this point a [pseudonymous](https://eur-lex.europa.eu/legal-content/EN/TXT/HTML/?uri=CELEX:32016R0679&from=EN#d1e1489-1-1) user ID, for example, a system's internal registration id, must be used.  -After logout, the anonymous user ID can be used again. - -!!! note - - The user identifier is required in tracking requests, otherwise it's discarded from the tracking servers. - - If a browser has JavaScript or cookies disabled, make sure that you put some "dummy" value as identifier in the tracking request to avoid losing tracking information. - Even if the event isn't user-specific, it's still useful for [popularity models]([[= user_doc =]]/personalization/recommendation_models/). - -The Personalization server internally creates a hash of every user ID. -The original ID isn't saved. -it's still possible that the original ID appears in the log files for the debugging purposes but log files are purged regularly. -The user ID is case sensitive. - -### Item identifiers - -Persons responsible for the sales policy in place in your organization must decide what should be presented as recommendations on the website. -In the eCommerce business you mostly have the possibility to track items based on: - -- Stock Keeping Unit (SKU) or -- Universal Product Code (UPC) - -The exact identifiers that are tracked are also recommended ("what-you-track-is-what-you-get"). -By default, it's not possible to track SKUs but recommend UPCs. -The following use case is typical for eCommerce business: - -Customer A implements the Personalization server and decides to use the SKU as item identifiers and recommendable items. -End users who browse through the shop probably get recommendations of the same item that is currently displayed but in a different size and/or color, a so-called "variant". -The Personalization server doesn't recognize relations between items, therefore, every single SKU is used to calculate similarities between them. -In the case of bestsellers, this could lead to the appearance of a shirt in size L on position 2 and the same shirt in size M on position 4. - -Customer B decides to use the UPC as item identifiers. -This results in recommendations that don't contain variations of the currently shown item. -Therefore, the detail page of shirt X doesn't contain a recommendation for the same shirt in a different size. -And the same shirt doesn't show up twice on a list of bestseller recommendations. - -If the size of an item or the color is selectable on a detail page of an item, you may prefer to use the UPC. -If recommendations of the same item in different sizes or colors are desired, you should use the SKU as item identifiers. - -Remember to use the same identifier in all interactions between your website and the Personalization server, for example, when a user buys an item, clicks a recommendation, or displays a product page. - -## Request parameter categorypath - -Category paths are logical tree structures that lead to items and are used for recommendation filtering. -For example, "recommend only items from the same category". - -During recommendation requests, the category path must always be provided. -The category path is a forward slash-separated list of categories from the root, for example, `%2FFoto%2FCameras%2FCompact%2FCanon`. -The initial slash (if present) is ignored. -Like all other parameters, the category path must be URL-encoded and cannot contain backslashes. - -The "categorypath" parameter offers the possibility to provide category-based recommendations without an explicit export of the structure of a customer's website. -If enabled by [[= product_name_base =]], it's used for on-the-fly updating of item categories. -If an item is moved to another category, it's handled as present in both categories until the old category ages out or is forcibly deleted. -Multiple category locations of an item (multi-homing) are therefore possible. - -!!! note "Category paths" - - When you import your own item metadata by using the Personalization server import interface, you might choose to not provide the category path in the Click event. - Category path is required by default, contact [[= product_name_base =]] to change the default configuration. - -## Track events - -!!! note - - Events are forwarded to the Personalization server with HTTP or HTTPS requests (or [RESTful-Requests](https://en.wikipedia.org/wiki/Representational_state_transfer)). - Both GET and POST methods are allowed for the event tracking. - Make sure that all embedded and query string parameters are URL encoded and don't use a backslash, encoded as %5C\. - -### Event parameters - -For a list of embedded parameters that each of the events may use, see the following table. - -|Name|Description|Values| -|---|---|---| -|`customerid`|A customer ID (for example "00000"). Can be used to identify a website in installations that [hosts multiple SiteAccesses]([[= user_doc =]]/personalization/use_cases/#multiple-website-hosting).|alphanumeric| -|userid|A user's ID on the website of the customer. It could be an internal customer code, a session code or a cookie for anonymous users.|URL-encoded alphanumeric| -|`itemtypeid`|Item type ID.|1 to 2147483647| -|`itemid`|A unique ID of the item the user has clicked.
String-based identifiers are also supported as item IDs to track content on a website, but it's discouraged due to fraud and security issues. If you're unable to provide numeric identifiers for the tracking process, contact [[= product_name_base =]] for further information and implementation notes.|1 to 2147483647| -|`sourceuserid`|User identifier valid up to now(usually some anonymous session ID)|URL-encoded alphanumeric| -|`targetuserid`|User identifier valid from now on (usually an account ID or login name)|URL-encoded alphanumeric| - -### Basket event - -The Basket event can be used to add products to a user's shopping cart. -This event is especially valuable if anonymized checkout is allowed or no recurring user identification is possible. -By using the shopping cart products as input for getting recommendations, problems with an empty profile or no buy history for the user can be solved. -The more valuable Basket events instead of recent user clicks can be used to provide personalized recommendations. -It also happens quite often that users "store" products on their shopping [wishlist](#wishlist-event) and plan to buy them later. -With the help of this information, personalized shopping cart-based recommendations can be provided in the whole shop. - -`GET https://event.perso.ibexa.co/api/[customerid]/basket/[userid]/[itemtypeid]/[itemid]` - -For a detailed description of embedded parameters, see [event parameters](#event-parameters). -This event has no query string parameters. - -### Blacklist event - -If a website offers a link or button that allows feedback similar to "don't recommend this product to me anymore", a user could express that they have bought it already in another shop. - -The format of the URL is: - -`GET https://event.perso.ibexa.co/api/[customerid]/blacklist/[userid]/[itemtypeid]/[itemid]` - -For a detailed description of embedded parameters, see [event parameters](#event-parameters). -This event has no query string parameters.  - -### Buy event - -As the name suggests, this event is used when an end user buys an item. -It must be sent to the event tracker at the end of a successful check-out process to ensure that no further action of the user can result in an abort. - -The URL has the following format:  - -`GET https://event.perso.ibexa.co/api/[customerid]/buy/[userid]/[itemtypeid]/[itemid]?fullprice=2.50EUR&quantity=4` - -For a detailed description of embedded parameters, see [event parameters](#event-parameters). -In addition to the fact that an item is bought, this event should provide information about the product price and quantity. - -|Name|Description|Values| -|---|---|---| -|`quantity`|The number of products a user has bought. Default value is "1". You can send n events instead of setting this parameter to n. This parameter is optional.|integer (default is "1")| -|`fullprice`|A price for a single product. It contains the price in decimal format plus the currency ISO 4217 code. If the price has a decimal part, the point must be used. There can be no space between price and currency. This parameter is optional.|currency, for example "12.45EUR" or "456JPY"| - -For example, if a user bought 4 pens for 10 Euros, `fullprice` can be set to "2.50EUR" and `quantity` can be set to 4. - -The Buy event is only relevant if the user is charged per product, like in a classic shop. -If products are sold on a subscription basis, or the web presence is ad-sponsored, this event type isn't applicable. - -#### Prices in a Buy event - -Every Buy event can contain a price. -If the price is set, it's stored with the event and used for calculating the revenue for statistics. -The price must be a price the user paid for the item, including all taxes and discounts.  - -If product price filtering is activated, the information provided over the product import is used. - -For more information, see [Content API](content_api.md). - -The currency is stored with the price and normalized only when statistic information is requested. -It's often a good choice to select a base currency and convert prices before sending the buy event. -The price attached to a buy event never overwrites the price which was defined in an item import. - -### Click event - -When the end user opens an item/article detail, a Click events is sent. -The Click event often provides additional information about the category structure of the website. - -!!! note - - User IDs aren't stored in the database. - They're irreversibly anonymized before saving to disk or building the recommendation model. - -The URL to track user clicks has the following format: - -`GET https://event.perso.ibexa.co/api/[customerid]/click/[userid]/[itemtypeid]/[itemid]` - -All embedded parameters are required for the request. -For a detailed description of embedded parameters, see [event parameters](#event-parameters). -Some optional request parameters can be set over query string parameters (GET parameters). - -`GET https://event.perso.ibexa.co/api/[customerid]/click/[userid]/[itemtypeid]/[itemid]?parameter1=value1¶meter2=value2` - -|Name|Description|Values| -|---|---|---| -|`categorypath`|The forward slash-separated path of categories of the item. Like all other parameters it must be URL-encoded, for example `%2FCameras%26Foto%2FCompact%20Cameras%2FCanon`.
For use cases, see [Category path filters]([[= user_doc =]]/personalization/filters/#category-path-filters) in User Documentation.|URL-encoded string.
Initial and trailing slashes are ignored: "/Cameras/" is the same as "Cameras".| - -### Consume event - -!!! note "eCommerce vs. content publishing" - - The Consume event is important for content publishing websites. - For eCommerce stores, this event isn't required but can be used in custom implementations. - -The event is sent when the end user stays on the page for a predefined period of time. -It's then assumed that the user consumed the item (read an article or watched a video). - -The URL has the following format: - -`GET https://event.perso.ibexa.co/api/[customerid]/consume/[userid]/[itemtypeid]/[itemid]` - -For a detailed description of embedded parameters, see [event parameters](#event-parameters). -The following table lists the request parameters: - -|Name|Description|Values| -|---|---|---| -|`percentage`|Informs how much of an item was consumed, for example, that an article was read only in 20%, a movie was watched in 90% or someone finished 3/4 of all levels of a game.|0-100| - -The logic for calculating the percentage is defined by the implementation. -For articles, this could be by scrolling down, for a movie/video based on the consumption part.  -You must decide what 100% consumption means. -For example, a movie contains end titles that are almost never consumed. -Therefore, they should not be part of the percentage calculation. - -The simplest implementation for articles is a JavaScript timer, which sends this event after a predefined time has elapsed (and the user did not leave the page). -The timespan after that the event is triggered should be dependent on the content, for example, it could be 30 seconds for a small newspaper article or a timespan calculated by the amount of words. - -!!! note "Incremental tracking of consume events" - - Consume events for a user can be sent incrementally as the recommender uses only the highest percentage rate. For example, if a user watches a movie, the website could send Consume events in 10% steps to avoid losing tracking information when the browser window is forcibly closed. - -### Deletefrombasket event - -The Deletefrombasket is issued when the end user removes items from their shopping cart. -It could signify that the user no longer plans to purchase the product. -Based on this information, recommendations presented by the store can be more accurate. - -`GET https://event.perso.ibexa.co/api/[customerid]/deletefrombasket/[userid]/[itemtypeid]/[itemid]` - -For a detailed description of embedded parameters, see [event parameters](#event-parameters). -This event has no query string parameters.  - -### Deletefromwishlist event - -This event is issued when the end user removes items from their wishlist. -It could signify that the user has lost interest in the product. -Based on this information, recommendations presented by the store can be more accurate. - -`GET https://event.perso.ibexa.co/api/[customerid]/deletefromwishlist/[userid]/[itemtypeid]/[itemid]` - -For a detailed description of embedded parameters, see [event parameters](#event-parameters). -This event has no query string parameters.  - -### Login event - -Recommendations rely on the fact that user actions can be correlated over a longer period of time. -Moreover, recommendations similar to "users who viewed this product ultimately bought it" require correlating Click events with subsequent Buy events. -In general, users tend to browse a website anonymously and add products to their shopping cart. -Up to this point, a user is identified by a visit-scoped variable (for example, a session ID or a first party cookie). -During the check-out of the shopping cart, a user probably logs in to an existing account. -As a result, the user identifier changes from an anonymous visit-scoped ID (sourceuserid) to a pseudonymous, persistent account ID (targetuserid). -You should correlate both IDs to correlate the Buy events (account ID) with the preceding Click events (visit-scoped ID). -The Login event serves exactly this purpose. - -The format of the URL is:  - -`GET https://event.perso.ibexa.co/api/[customerid]/login/[sourceuserid]/[targetuserid]` - -For a detailed description of embedded parameters, see [event parameters](#event-parameters). - -### Rate event - -Publishers, media or shops often allow commenting/rating products, articles or movies. -If a user comments on an item, it indicates a special interest in this topic that has to be treated separately. - -The format of the URL is: - -`GET https://event.perso.ibexa.co/api/[customerid]/rate/[userid]/[itemtypeid]/[itemid]?rating=50` - -For a detailed description of embedded parameters, see [event parameters](#event-parameters). - -Rate event can also be used for explicit ratings like a five-star rating for hotels. -A predefined rating can be submitted when the user comments on an item. - -|Name|Description|Values| -|---|---|---| -|`rating`|The rating a user gives an item. The rating value is normalized during the calculation of rate-based recommendations. Therefore, there is no need to use the full scale of 0-100 but it needs to be consistent.|integer from 0 to 100| - -### Wishlist event - -This event is issued when the end user puts a product on their shopping list. -It means that they're interested in the product but plan to buy it later. -This information can help return better recommendations. -It can also be used as a basis for the price drop trigger. - -`GET https://event.perso.ibexa.co/api/[customerid]/wishlist/[userid]/[itemtypeid]/[itemid]?price=2.50EUR` - -For a detailed description of embedded parameters, see [event parameters](#event-parameters). -In addition to the fact that an item is placed on the shopping list, this event can provide information about the product price at the time it was saved. - -|Name|Description| -|---|---| -|`price`|A price for a single product. It contains the price in decimal format and the currency code. If the price has a decimal part, the point must be used. There can be no space between price and currency. This parameter is optional.| - -## Tracking events based on recommendations - -Tracking events based on integrated recommendations are the only way to measure the accuracy and effectiveness of recommendations. -Both recommendation response and trigger message include requests to generate these events. -Events of this type inform the Personalization server about the recommendations that were shown to the user and which of those recommendations were clicked. -Otherwise, it would be impossible to calculate reliable statistics that could be checked against the customer's KPIs. - -A recommendation response includes requests to generate a Rendered and Clickrecommended event. -The first one is executed when a recommendation is shown to the user. -The second is called when a recommendation is clicked or otherwise accepted. -Sending Rendered events causes as many requests as recommendations to be displayed, a Clickrecommended event is usually sent only once (when a user clicks on a specific recommendation item). - -Example of a recommendation response: - -``` json -"recommendationItems": [ - { - "relevance": 23, - "itemType": 1, - "itemId": 100175717, - "origin": { - "itemIds" : [10, 11], - "itemType" : 1, - "source" : "REQUEST" - }, - "category" : "Men/Shirts", - "links" : { - "clickRecommended" : "//event.perso.ibexa.co/clickrecommended/johndoe/1/100175717?scenario=also_clicked&modelId=37", - "rendered" : "//event.perso.ibexa.co/rendered/johndoe/1/100175717" - }, -``` - -| Field name | Description | -|---|---| -| `itemIds` |Items that the recommendations are based on (context or user history items), multiple values are possible.| -| `source` |Event that initiated the response: REQUEST (parameter "contextitems") or CLICK, CONSUME, BUY, BASKET, RATE (user history).| -| `category` |A recommended item category. Provided only if category suggestion is requested.| -| `links` | Requests for events that are executed when the end user displays or clicks a recommendation.| - -See [Recommendation API](recommendation_api.md) for more details. - -A trigger message includes requests for a Triggeropened and Clicktriggered event. -The first is executed once, when the end user opens a trigger message (for example, embedded into a newsletter). -The second is called each time the user follows a link to see the recommended item. -Both requests provide the `triggername` parameter, which passes a unique alphanumerical identifier of the trigger that initiated the message. - -Example of a trigger message: - -``` json - "customerID":"177751", - "userExternalId":"user@ibexa.co", - "triggerType":"REACTIVATION|ABANDAONED_SHOPPING_CART", - "triggerName":"trigger_ref_code", - "triggerOpenedLink":"//event.perso.ibexa.co/api/17751/triggeropened/johndoe?triggername=action_trigger_ref_code", - "recommendations":[ - { - "itemId":959, - "itemType":46, - "clickRecommended":"//event.perso.ibexa.co/api/17751/clicktriggered/johndoe/46/959?triggername=action_trigger_ref_code", - "attributes":{ - "ses_name":"Minimalista Coffee Table", - "ses_image":["img_1", "img_2"] - } - } - ] -} -``` - -For more information, see [Send messages with recommendations](../integrate_recommendation_service.md#send-messages-with-recommendations). - -### Rendered event - -This event is sent when the website uses the recommendation provided by the recommendation engine and renders it on the webpage. -In combination with a predefined threshold, it allows the recommender engine to exclude this item from future results and avoid recommending the same item to the same user multiple times during a session. - -The URL for a Rendered event has the following format: - -`GET https://event.perso.ibexa.co/api/[customerid]/rendered/[userid]/[itemtypeid]/[itemid[,itemid]]` - -For a detailed description of embedded parameters, see [event parameters](#event-parameters). - -It's common that recommendations are rendered as a block with multiple items. -To save traffic and speed up the process, you can bundle multiple recommendations in one request. -Several item IDs must be comma-separated. - -### Clickrecommended event - -When the end users clicks a recommendation, the following event is sent to gather statistics related to the acceptance of recommendations. - -The URL has the following format: - -`GET https://event.perso.ibexa.co/api/[customerid]/clickrecommended/[userid]/[itemtypeid]/[itemid]?scenario=` - -For a detailed description of embedded parameters, see [event parameters](#event-parameters). -The request parameters are: - -|Name|Description|Values| -|---|---|---| -|`scenario`|Name of the scenario, where recommendations originated from. This parameter is required.|URL-encoded alphanumeric| - -The scenario parameter identifies the originating scenario to gain detailed statistics about the scenario that motivated the user to click on a recommendation. -This information comes with the recommendation from the recommendation controller.  - -The event is used for providing statistics about how often users accepted the recommendations of the configured recommendation scenario or considered them as valuable. - -### Triggeropened event - -The Triggeropened event is sent when the end user opens a trigger message, for example, by opening an email message with recommendations. - -The URL has the following format: - -`GET https://event.perso.ibexa.co/api/[customerid]/triggeropened/[userid]?triggername=` - -For a detailed description of embedded parameters, see [event parameters](#event-parameters). -The request parameter is: - -|Name|Description|Values| -|---|---|---| -|`triggername`|Identifier of the trigger that the message originates from. This parameter is required.|URL-encoded alphanumeric| - -The event is used for providing statistics about how often trigger messages are considered valuable by the users. - -### Clicktriggered event - -The Clicktriggered event is sent when the end user clicks the link delivered in a trigger message to see the recommended item. - -The URL has the following format: - -`GET https://event.perso.ibexa.co/api/[customerid]/clicktriggered/[userid]/[itemtypeid]/[itemid]?triggername=` - -For a detailed description of embedded parameters, see [event parameters](#event-parameters). -The request parameter is: - -|Name|Description|Values| -|---|---|---| -|`triggername`|Identifier of the trigger that the recommendation originates from. This parameter is required.|URL-encoded alphanumeric| - -The event is used for providing statistics about how often a specific recommendation from the trigger message is considered valuable by the user. - -## Tracking event examples - -Below are examples for the translation of user actions on a website into tracking requests. - -User "Js79009234YU7" navigates to an item 123 of type 1, located under `Shoes/Children`: - -`GET https://event.perso.ibexa.co/api/00000/click/Js79009234YU7/1/123?categorypath=%2FShoes%2FChildren` - -Products 128, 129 and 155 of type 1 are rendered as recommendations for user "Js79009234YU7". -Recommendations were delivered by the scenario "also\_bought": - -`GET https://event.perso.ibexa.co/api/00000/rendered/Js79009234YU7/1/128,129,155` - -User clicks a recommended product 155 that was delivered by the scenario "also\_bought": - -`GET https://event.perso.ibexa.co/api/00000/clickrecommended/Js79009234YU7/1/155?scenario=also_bought` - -User "Js79009234YU7" has watched a video 452 (all videos are item type "3"): - -`GET https://event.perso.ibexa.co/api/00000/consume/Js79009234YU7/3/452` - -User "Js79009234YU7" has watched 60 percent of a video 466: - -`GET https://event.perso.ibexa.co/api/00000/consume/Js79009234YU7/3/452?percentage=60` - -User "Js79009234YU7" puts products 128 and 129 into the cart. - -`GET https://event.perso.ibexa.co/api/00000/basket/Js79009234YU7/1/128` - -`GET https://event.perso.ibexa.co/api/00000/basket/Js79009234YU7/1/129` - -To buy selected products, user "Js79009234YU7" logs in and obtains an internal identifier (for example, the registration ID) "johndoe" from the site. - -`GET https://event.perso.ibexa.co/api/00000/login/Js79009234YU7/johndoe` - -The user buys two products from the cart: product 128 (one piece for the price of EUR 19.99) and product 129 (2 pieces for the price of EUR 4.44 each). - -`GET https://event.perso.ibexa.co/api/00000/buy/johndoe/1/128?quantity=1&fullprice=19.99EUR` -`GET https://event.perso.ibexa.co/api/00000/buy/johndoe/1/129?quantity=2&fullprice=4.44EUR` - -User "johndoe" likes the product 133 and wants to rate it with 5 stars. - -`GET https://event.perso.ibexa.co/api/00000/rate/Js79009234YU7/1/133?rating=5` - -### Response handling - -The following HTTP response codes are used by the event tracker.   - -|HTTP Status Code|Description| -|---|---| -|200 OK
204 No Content|Request was successfully processed.| -|400 Bad Request
414 Request-URI Too Long|The request is wrongly formatted. See response body for more information.| -|401 Unauthorized|Invalid authentication credentials.| -|403 Forbidden|Access denied (not implemented yet).| -|404 Not Found|The customer ID was not found. The event code was not found.| -|500 Internal Server Error|Unspecified error. Contact [[= product_name_base =]] if this error reoccurs frequently.| - -In case of errors, the body of the response contains human-readable error messages. -Human-readable error messages can be changed and should not be used for automated processing. diff --git a/docs/personalization/api_reference/user_api.md b/docs/personalization/api_reference/user_api.md deleted file mode 100644 index 710baa385ab..00000000000 --- a/docs/personalization/api_reference/user_api.md +++ /dev/null @@ -1,110 +0,0 @@ ---- -description: Use HTTP methods to correlate metadata with user data and combine users into clusters of certain type. ---- - -# User API - -When generating recommendations, it's useful to have the ability to correlate metadata with user data and combine users into clusters of certain type. -Such metadata can be gender, ZIP code, discount rate, and more.  -You can use the following user metadata import format to enrich the tracked data with information that cannot be calculated and must be provided by the end-user. - -If you plan to import user metadata, contact support@ibexa.co to ensure that you're compliant with privacy regulations. - -!!! note "Authentication" - - For importing metadata, basic authentication is enabled by default. - Use your customer ID and license key as username and password. - If authentication is enabled for recommendation requests and you want change this, contact support@ibexa.co. - -## GET requests - -Use the following request to fetch user attributes for the specified users: - -`GET: https://import.perso.ibexa.co/api/[customerid]/[source]/user/[userid[,userid[...]]]` - -User data is returned as an XML object. -Make sure that you use the **HTTP Content-Type=text/xml** header. - -## POST requests - -Use the following request to update the specified user's attribute set: - -`POST: https://import.perso.ibexa.co/api/[customerid]/[source]/user` - -## Request parameters - -For the requests to function, you must provide the following parameters: - -|Parameter|Description|Value| -|---|---|---| -|`customerid`|A customer ID (for example "00000"), as defined when [enabling Personalization](enable_personalization.md#set-up-customer-credentials). Can be used to identify a website in installations that [hosts multiple SiteAccesses]([[= user_doc =]]/personalization/use_cases/#multiple-website-hosting).|alphanumeric| -|`source`|An ID of the source of the specified user's metadata.|alphanumeric| -|`userid`|An ID of the tracked user in the website (for example, an internal customer code, a session code, or a cookie for anonymous users.|alphanumeric| - -!!! caution "Parameter encoding limitations" - - All parameters must be URL-encoded (see RFC 3986) and cannot contain slash, backslash or space characters. - -##### Source - -The `source` parameter defines the system that stores the specified user's metadata. -If you have multiple source systems for updating user attributes, for example, a registration service, where users define their gender and age, or an application that integrates with Facebook to source the brands the user "liked" in your shop, every new upload of attributes replaces the attribute set that already exists for the same user/source pair. - -If you need to get all the available attributes for all sources, apply the `allSources` query string parameter, for example: - -`GET: https://import.perso.ibexa.co/api/00000/facebook/user/CUSTOMER_1234?allSources=true` - -When you do that, and the source returned is different from the source passed in the request (in this case, "facebook"), an additional attribute `source` is added to the XML object. - -##### User ID - -User ID is a case-sensitive combination of characters. -If transferred as part of the URL, the attribute must be URL-encoded.  -If transferred in the XML object, the attribute must be XML-encoded. - -For example: - -| User ID | URL encoded | XML encoded | -|---------------------|-------------------------|---------------------------| -| `Customer<12.2014>` | `Customer%3C12.2014%3E` | `Customer<12.2014>` | - - -## DELETE request - -Use the following request to run an opt-out option to delete the user and all data related to this user. After this request, the user is deleted from the database. - -`DELETE: https://admin.perso.ibexa.co/api/[customerid]/user/[userid[,userid[...]]]` - -## Responses - -### Response object format - -For an example of user metadata, see the following XML code. -The attribute keys and values are chosen at random. - -``` xml - - - - - - - - - - - - - -``` - -Attribute keys are POSIX alphanumeric codes that can consist of the following characters: `\[A-Z\]`, `\[0-9\]`, `"\_"` and `"-"`.  -Attribute keys are case sensitive. - -The following attribute types are supported: - -- DATE - An XSD-formatted date, for example, "2014-08-07" -- DATETIME - An XSD-formatted time without a time zone, for example, "2014-08-07T14:43:12" -- NOMINAL - A value from a fixed length list, for example "gender" or "favorite film genre". If you don't set the attribute type, this is the default value -- NUMERIC - A decimal value, for example, "1.23" or "-2345" -- TEXT - A longer text, usually free form diff --git a/docs/personalization/attribute_search_in_elasticsearch.md b/docs/personalization/attribute_search_in_elasticsearch.md deleted file mode 100644 index 01c2b6a7103..00000000000 --- a/docs/personalization/attribute_search_in_elasticsearch.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -description: Attribute search uses Elasticsearch database to display dynamically taken values in scenario and model previews. ---- - -# Attribute search in Elasticsearch database - -If you use external data source for personalization data, it's not possible to display external content in the Universal Discovery Widget as it's deprecated. -Attribute search is used in scenario preview and editorials models instead. -Attribute search works like an autocomplete feature, but values are dynamically taken from the Elasticsearch database. - -## Configure attribute search - -Add the following configuration under the `ibexa.system..personalization` [configuration key](configuration.md#configuration-files): - -```yaml -ibexa: - system: - : - personalization: - output_type_attributes: - : - title: -``` - - -See the example: - -```yaml -ibexa: - system: - default: - personalization: - output_type_attributes: - 1: - title: name - description: short_description - 2: - title: category_name - 3: - title: product_name - 4: - title: short_name - description: body - image: image - -``` - -![Attributes search](perso_attributes_search.png) diff --git a/docs/personalization/enable_personalization.md b/docs/personalization/enable_personalization.md deleted file mode 100644 index 48fa2f6f7ae..00000000000 --- a/docs/personalization/enable_personalization.md +++ /dev/null @@ -1,541 +0,0 @@ ---- -description: Configure your project files to enable Personalization and set up items you want to track. -month_change: false ---- - -# Enable Personalization - -The Personalization service is based on a client-server architecture. -To enable it, you must set up authentication parameters that you receive from [[= product_name_base =]]. - -## Get authentication parameters - -First, either you or another [[= product_name_base =]] user responsible for managing the [[= product_name =]] instance must [request access to the service]([[= user_doc =]]/personalization/enable_personalization/#request-access-to-the-server). - -## Set up customer credentials - -When you receive the credentials, add them to your configuration. - -In the root folder of your project, edit the `.env.local` file by adding the following lines with your customer ID and license key: - -```bash -PERSONALIZATION_CUSTOMER_ID=12345 -PERSONALIZATION_LICENSE_KEY=67890-1234-5678-90123-4567 -PERSONALIZATION_HOST_URI=https://server_uri -``` - -!!! note "Configuring user credentials for multisite setup and different personalization customers" - - If your installation [hosts multiple sites]([[= user_doc =]]/personalization/use_cases/#multiple-website-hosting) with different customer IDs, for example, to provide separate recommendations for different language versions of the store, you can store all credentials in the same file: - - ``` - # Main credentials - ENU store - PERSONALIZATION_CUSTOMER_ID=12345 - PERSONALIZATION_LICENSE_KEY=67890-1234-5678-90123-4567 - PERSONALIZATION_HOST_URI=https://server_uri - - # Additional credentials - FRA store - FRA_CUSTOMER_ID=54321 - FRA_LICENSE_KEY=09876-5432-1098-7654-3210 - FRA_HOST_URI=https://FRA_server_uri - FRA_CUSTOM_EXPORT_LOGIN=65432 - FRA_CUSTOM_EXPORT_PASSWORD=#prtpswd_1 - ``` - -## Configure Personalization - -The [Personalization package](https://github.com/ibexa/personalization-client) adds a personalization solution to [[= product_name =]] and communicates with the Personalization server. - -Its job is to track the way visitors use the website and recommend content based on their behavior. - -For more information about integrating the Personalization service, see [Developer guide](tracking_api.md) and [Best practices](tracking_integration.md). - -### Set up item type tracking - -For the recommendations to be calculated, apart from visitor events (for example, CLICK or BUY), the Personalization server must receive a list of item types that are tracked. - -You define item types to be tracked in [configuration files](configuration.md#configuration-files). -The content is then initially exported by a script. -After this, it's synchronized with the Personalization service every time a change occurs (using any method that triggers the event). - -The Personalization configuration is SiteAccess-aware. -If your installation hosts multiple sites with different customer IDs, for example, to provide separate recommendations for different language versions of the site, provide the credentials that correspond to each of the sites. - -The configuration can resemble the following example: - -``` yaml -ibexa: - system: - : - personalization: - site_name: '' # For example 'ENU store' - host_uri: '%env(PERSONALIZATION_HOST_URI)%' - authentication: - customer_id: '%env(int:PERSONALIZATION_CUSTOMER_ID)%' - license_key: '%env(PERSONALIZATION_LICENSE_KEY)%' - included_item_types: [product, article] - output_type_attributes: - 123: # content type ID - title: 'title' - image: 'image_legend' - description: 'sub_title' - 456: - title: 'short_title' - image: 'primary_image' - description: 'sub_title' - - : - personalization: - site_name: '' # For example 'FRA store' - host_uri: '%env(FRA_HOST_URI)%' - authentication: - customer_id: '%env(int:FRA_CUSTOMER_ID)%' - license_key: '%env(FRA_LICENSE_KEY)%' - included_item_types: [product, article] - output_type_attributes: - 123: # content type ID - title: 'title' - image: 'image_legend' - description: 'sub_title' - 456: - title: 'short_title' - image: 'primary_image' - description: 'sub_title' -``` - -!!! note "Authentication" - - For data exchange purposes, basic authentication is enabled by default. - To change this, contact support@ibexa.co. - For security reasons, [store the authentication credentials in the ENV file](#set-up-customer-credentials), and don't commit them to the Version Control System. - Then, use environment variables to pull them into the YAML file. - -| Parameter | Description | -|--------------------------------------|-----------------------------------------------------------| -| `host_uri` | A location where the site's REST API can be accessed. This is where the Personalization server imports items from. | -| `authentication.customer_id` | A customer ID related to the supported SiteAccess. | -| `authentication.license_key` | The Personalization service's license key. | -| `included_item_types` | A list of alphanumerical identifiers of item types on which the tracking script is shown. | -| `random_item_types` | A list of alphanumerical identifiers of item types that are returned when the response from the server contains no content. | - -You can use an alphanumeric content identifier `remoteId` instead of a numeric `id`. -To enable it, add the following configuration: - -```yaml -ibexa: - system: - : - personalization: - repository: - content: - use_remote_id: true -``` - -!!! note "Support for alphanumeric content identifier" - - Contact support@ibexa.co with your organization's requirements to have the alphanumeric content identifier enabled. - -#### Enable tracking - -The Personalization client bundle delivers a Twig extension which helps integrate the user tracking functionality into your site. -Place the following code snippet in the `` section of your header template: - -``` html+twig -{% if content is defined %} - {{ ibexa_recommendation_track_user(content) }} -{% endif %} -``` - -!!! tip "How tracking works" - - For more information about tracking in general, see [Tracking API](tracking_api.md) and [Tracking with ibexa-tracker.js](tracking_with_ibexa-tracker.md). - -### Check whether the bundle provides REST data - -You can verify the import controller of the bundle by calling the local API. -As the API uses token based authorization you first need a valid bearer token. - -When you publish a content item a bearer token is created and saved to the `ibexa_token` db table. - -Additionally a POST request is send to the Personalization Engine, containing the token and the Rest URL where the Personalization Engine can fetch the changed Content. - -The `BEARER_TOKEN` is the newest one in `ibexa_token` table having `type=1` and `identifier=update`. The token has a default lifetime of one day. - -You can use this token to check what is provided to the Personalization Engine: - - -```bash -curl --location '{PERSONALIZATION_HOST_URI}/api/ibexa/v2/personalization/v1/content/id/{contentId}?lang={comma_separated_languages}' \ ---header 'Accept: application/vnd.ibexa.api.Content+json' \ ---header 'Authorization: Bearer {BEARER_TOKEN}' -``` - -Additionally, check whether the `contentlist` endpoint is working with the following request: - -```bash -curl --location '{PERSONALIZATION_HOST_URI}/api/ibexa/v2/personalization/v1/contentlist/{comma_separated_content_ids}?lang={comma_separated_languages}' \ ---header 'Accept: application/vnd.ibexa.api.ContentList+json' \ ---header 'Authorization: Bearer {BEARER_TOKEN}' -``` - -The `content` endpoint returns one item and the `contentlist` endpoint returns many. - -``` json -{ - "contentList": { - "_media-type": "application/vnd.ibexa.api.ContentList+json", - "content": [ - { - "_media-type": "application/vnd.ibexa.api.Content+json", - "contentId": 72, - "contentTypeId": 38, - "identifier": "place", - "language": "eng-GB", - "publishedDate": "2015-09-17T13:23:10+00:00", - "author": "Sandip Patel", - "uri": "/Places-Tastes/Places/Kochin-India", - "categoryPath": "/1/2/95/71/73/", - "mainLocation": { - "_media-type": "application/vnd.ibexa.api.mainLocation+json", - "_href": "/api/ezp/v2/content/locations/1/2/95/71/73/" - }, - "locations": { - "_media-type": "application/vnd.ibexa.api.locations+json", - "_href": "/api/ezp/v2/content/objects/72/locations" - }, - "name": "Kochin, India", - "intro": "

We got the major port city on the south west coast of India.

\n]]>", - "description": "

Kochi (formerly Cochin) ...

\n]]>", - "image": "/var/site/storage/images/places-tastes/places/kochin-india/282-5-eng-GB/Kochin-India.jpg", - "caption": "

Chinese fishing nets ...

\n]]>", - "location": "kochin, india", - "authors_position": "Senior Editor", - "tags": "India, Kochin", - "rating": "0", - "publication_date": "1442500260", - "metas": "" - } - ], - .... - } -} -``` -### Export item information - -To get recommendations you must first export the item information to the Personalization server. - -After you [define item types to be tracked and recommended](#set-up-item-type-tracking), start the full export. - -You need to run the `ibexa:personalization:run-export command per SiteAccesses that you want to use together with Personalization. You need different customer IDs for different SiteAccesses. - -``` bash -php bin/console ibexa:personalization:run-export - --item-type-identifier-list=, - --siteaccess= - --customer-id= - --license-key= - --languages=, -``` - -The bundle exporter collects all content related to the ``/`` pair and stores it in files to the folder `public/var/export/yyyy/mm/dd/hh/mm` of your project. -After finishing, the system sends a POST request to the endpoint and informs the Personalization server to fetch new content. -An internal workflow is then triggered, so that the generated files are downloaded and imported in the Personalization server's content store. - -The export process can take several minutes. - -![Personalization Full Content Export](full_content_export.png) - -!!! caution "Re-exporting modified item types" - - If the item types to be recommended change, you must perform a new full export by running the `php bin/console ibexa:personalization:run-export` command again. - -#### Check export results - -There are three ways to check whether content was transferred and stored successfully in the Personalization server: - -- [REST request to client's content store](#rest-request-to-clients-content-store) - -- [Personalization backend](#personalization-backend) - -- [Subsequent content exports](#subsequent-content-exports) - -##### REST request to client's content store - -To get the data of an imported item you can request the following REST resource: - -`GET https://admin.perso.ibexa.co/api//item//` - -This way uses basic authentication. -The username is the customer ID and the password is the license key. - -??? note "Example response" - - ``` xml - - - - - /var/site/storage/images/places-tastes/places/santo-domingo-dominican-republic/288-4-eng-GB/Santo-Domingo-Dominican-Republic.jpg - - /Places-Tastes/Places/Santo-Domingo-Dominican-Republic - 2015-09-17T13:24:25.000 - - - 1/2/95/71/74 - - - - - - - - - - - - - - - - - - - - - - - - - - ``` - -##### Personalization backend - -In the back office, go to **Personalization** > **Import** and review the list of historical import operations to see whether a full import was successful. - -![Item Import tab with full import results](reco_full_import.png) - -#### Subsequent content exports - -The Personalization server is automatically kept in sync with the content in [[= product_name =]]. - -Every time an editor creates, updates or deletes content in the back office, a notification is sent to https://admin.perso.ibexa.co/. -The personalization service also notifies other components of the Personalization server and it eventually fetches the affected content and updates it internally. - -![Subsequent content exports](incremental_content_export.png) - -### Display recommendations - -!!! note "Client-based recommendations" - - Recommendations are fetched and rendered asynchronously, so there is no additional load on the server. - Therefore, it's crucial that you check whether the content export was successful, because certain references, for example, deeplinks and image references, are included. - If the export fails, the Personalization server doesn't have full content information. - As a result, even if the recommendations are displayed, they might miss images, titles or deeplinks. - -To display recommendations on your site, you must include the asset in the template. -To do it, use the following code: - -``` html+twig -{{ encore_entry_script_tags('ibexa-personalization-client-js', null, 'ibexa') }} -``` - -This file is responsible for sending notifications to the [Recommendation API](recommendation_api.md) after the user clicks a tracking element. - -To render recommended content, use a dedicated `showRecommendationsAction()` from the `RecommendationController.php`: - -``` html+twig -render(controller('ibexa_personalization::showRecommendationsAction', { - 'contextItems': content, - 'scenario': 'front', - 'outputTypeId': 57, - 'limit': 3, - 'template': '@IbexaPersonalization::recommendations.html.twig', - 'attributes': ['title', 'intro', 'image', 'uri'] - })) -``` - -!!! tip - - To check whether tracking is enabled on the front end, use the `ibexa_recommendation_enabled()` Twig function. - You can wrap the call to the `RecommendationController` with: - - ``` html+twig - {% if ibexa_recommendation_enabled() %} -
- {# ... #} -
- {% endif %} - ``` - -#### Parameters - -| Parameter | Type | Description | -|------------------|--------|---------------| -| `contextItems` | int | ID of the content you want to get recommendations for. | -| `scenario` | string | Scenario used to display recommendations. You can create custom scenarios in the back office. | -| `outputTypeId` | string | Item type that you expect in response, for example, `blog_post`. | -| `crossContentType`| bool | If set to `true`, returns recommendations for all content types specified in the scenario. | -| `limit` | int | Number of recommendations to fetch. | -| `template` | string | Template name. | -| `attributes` | array | Fields that are required and are requested from the Personalization server. These field names are also used inside Handlebars templates. | - -You can also bypass named arguments with standard value passing as arguments. - -!!! note "Custom templates" - - To use a custom template for displaying recommendations, ensure that it includes `event_tracking.html.twig`: - - `{% include '@IbexaPersonalization/event_tracking.html.twig' %}`. - -Recommendation responses contain all content data that is requested as attribute in the recommendation call. -This response data can be used in templates to render and style recommendations. - -For example, the following GET request should deliver the response below if the content fields were previously exported by the export script. - -`GET https://reco.perso.ibexa.co/api/v2//someuser/popular.json?contextitems=71&numrecs=5&categorypath=/&outputtypeid=&attribute=name,author,uri,image` - -!!! note "Example response" - - ``` json - { - "contextItems": [ - { - "itemId": 71, - "itemType": 38, - "sources": [ - "REQUEST" - ], - "viewers": 0 - } - ], - "recommendationItems": [ - { - "itemId": 71, - "itemType": 38, - "relevance": 3, - "links": { - "clickRecommended": "//event.perso.ibexa.co/api/723/clickrecommended/someuser/38/71?scenario=popular&modelid=4199&categorypath=&requestuuid=d75e7cf0-e4ca-11e7-a94d-0a64dbbea736", - "rendered": "//event.perso.ibexa.co/api/723/rendered/someuser/38/71?scenario=popular&modelid=4199&categorypath=&requestuuid=d75e7cf0-e4ca-11e7-a94d-0a64dbbea736" - }, - "attributes": [ - { - "key": "image", - "values": [ - "/var/site/storage/images/places-tastes/places/valencia-spain/276-4-eng-GB/Valencia-Spain.jpg" - ] - }, - { - "key": "author", - "values": [ - "Tara Fitzgerald" - ] - }, - { - "key": "name", - "values": [ - "Valencia, Spain" - ] - }, - { - "key": "uri", - "values": [ - "/Places-Tastes/Places/Valencia-Spain" - ] - } - ] - }, - { - "itemId": 75, - "itemType": 38, - "relevance": 1, - "links": { - "clickRecommended": "//event.perso.ibexa.co/api/723/clickrecommended/someuser/38/75?scenario=popular&modelid=4199&categorypath=&requestuuid=d75e7cf0-e4ca-11e7-a94d-0a64dbbea736", - "rendered": "//event.perso.ibexa.co/api/723/rendered/someuser/38/75?scenario=popular&modelid=4199&categorypath=&requestuuid=d75e7cf0-e4ca-11e7-a94d-0a64dbbea736" - }, - "attributes": [ - { - "key": "image", - "values": [ - "/var/site/storage/images/places-tastes/places/brooklyn-new-york/300-4-eng-GB/Brooklyn-New-York.jpg" - ] - }, - { - "key": "author", - "values": [ - "Elizabeth Liu" - ] - }, - { - "key": "name", - "values": [ - "Brooklyn, New York" - ] - }, - { - "key": "uri", - "values": [ - "/Places-Tastes/Places/Brooklyn-New-York" - ] - } - ] - } - ] - } - ``` - -#### Modify recommendation data - -You can retrieve data returned from the Personalization server and modify it before it's shown to the user. - -To modify recommendation data, subscribe to `RecommendationResponseEvent`. -See [`Event/Subscriber/RecommendationEventSubscriber.php`](https://github.com/ibexa/personalization-client/blob/4.6/src/lib/Event/Subscriber/RecommendationEventSubscriber.php) for an example: - -``` php -public static function getSubscribedEvents(): array -{ - return [ - RecommendationResponseEvent::class => ['onRecommendationResponse', -10], - ]; -} -``` - -The `-10` refers to priority, which must be negative so this action is performed before the main subscriber is run. - -### Image variations - -Displaying image variations isn't supported out of the box. - -You can work around this limitation by creating a template (based on [recommendations.html.twig](https://github.com/ibexa/personalization-client/blob/4.6/src/bundle/Resources/views/recommendations.html.twig)). - -To access a specific image variation through API, add the `image` parameter to the request URL with the name of the variation as its value. -For example, to retrieve the `rss` variation of the image, use: - -`/api/ezp/v2/ibexa_recommendation/v1/contenttypes/16?lang=eng-GB&fields=title,description,image,intro,name&page=1&page_size=20&image=rss` - -### Troubleshooting - -#### Logging - -Most operations are logged by using the `ibexa-personalization` [Monolog channel]([[= symfony_doc =]]/logging/channels_handlers.html). -To log everything about Personalization to `dev.recommendation.log`, add the following configuration: - -``` yaml -monolog: - handlers: - ibexa_personalization: - type: stream - path: '%kernel.logs_dir%/%kernel.environment%.recommendation.log' - channels: [ibexa-personalization] - level: info -``` - -You can replace `info` with `debug` to increase verbosity. - -## Set up user roles and permissions - -Depending on your requirements, you may need to set up `edit` and `view` [permissions](permissions.md) to grant users access to recommendation settings that relate to different SiteAccesses and results that come from these websites. - -## Configure recommendation logic - -When you enable the Personalization, you can go back to the back office, refresh the Personalization dashboard and proceed with [configuring the logic]([[= user_doc =]]/personalization/configure_personalization/) used to calculate the recommendation results. diff --git a/docs/personalization/how_it_works.md b/docs/personalization/how_it_works.md deleted file mode 100644 index ee28481dced..00000000000 --- a/docs/personalization/how_it_works.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -description: Integrate recommendation service into your website. ---- - -# How Personalization works - -The idea behind the Personalization service is built upon four main steps. - -1. A user visits a news service or an online store, navigates through it and leaves some footprints. The most popular footprints are selecting (CLICK) and purchasing products (BUY). -2. This information is sent to the Personalization client every time these events happen. -3. The Personalization server accumulates the tracked events, categorizes them and calculates recommendations for every product and every user in the shop. -4. Recommendations can be fetched from the Personalization service and presented to users during their sessions or pushed by the service to a dedicated endpoint, for example, to be forwarded to customers. - -![Overview of how recommendation works](recommendation_overview.png) - -For more information about available functionalities, see [User Documentation]([[= user_doc =]]/personalization/personalization/). - -For more information about enabling the Personalization service, see [Enable Personalization](enable_personalization.md). diff --git a/docs/personalization/img/Diagram source/full_content_export.xml b/docs/personalization/img/Diagram source/full_content_export.xml deleted file mode 100644 index 7245cb8e9ce..00000000000 --- a/docs/personalization/img/Diagram source/full_content_export.xml +++ /dev/null @@ -1,129 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/personalization/img/Diagram source/incremental_content_export.xml b/docs/personalization/img/Diagram source/incremental_content_export.xml deleted file mode 100644 index 8f7696fd501..00000000000 --- a/docs/personalization/img/Diagram source/incremental_content_export.xml +++ /dev/null @@ -1 +0,0 @@ -7VtLc+I4EP41VGUPoWT5ARyBCZk5ZGpqslszcxS2AqoYy2uLAPPrV7IlP2QbHGKzTCo5JLhbyFJ/X6tbXZ2BOd/s7yMUrh+oh/0BBN5+YH4aQGjAyZj/EZJDKhmBSSpYRcSTg3LBI/mNpRBI6ZZ4OC4NZJT6jIRloUuDALusJENRRHflYU/UL781RCtcETy6yK9KfxCPrVPpGI5y+WdMVmv1ZsOR+9sgNVjuJF4jj+4KIvNuYM4jSln6abOfY18YT9kl/d6iQZstLMIBa/OFh52z+uoww3vyGP1s/+OSH9NbQ07zgvyt3PGXJd4jLvr085tcODsoa0R0G3hYTGgMzNluTRh+DJErtDuOP5et2caX6icaMAmoYalnOVeiJ74/pz6NkrnNJ8NGHHVzFrOIPuM6jZihIF8kP1xeNYXaFo4Y3hdE0jT3mG4wiw58iNSaEiVJU0s+7nLMDSVbF/BWMiRptsomzpHgHyQYrwEGVoAZQMdn0golWJx/t1QpbuPE4lM+wLDCfa7kn1YsAYgJ15mK5cEF8jYkGIY4iumQCOCHLlXv4er0VekXL0oGbwI9C9aRIdP0SQZ4kg0QXJQNZoUNc759nBCBbELKdxZdFCAAxtB26wDKND0C5FjX5q5WjbtqcODAm4qIxJ8CGnDhzEPxOsOngEWjhWK6jVx8ZB3QTgdirxTWqoYsWMquMZSSRdhHjLyUg2Gd9eQbvlGScFKhCMo42Y4GQLoh+a1i8Dox0Vibh6FohVllngTLbNdvgNe+EnjBVcFrwY7g1Se6NLxOl/ByVKPDT/4AhrZ6/PV26OWSUlO0iBVXwpGR0RFH9IlacoSDhg6FYaEYELdfrwr0OeXSGbsl4Og0AV8XzcvRGk/GS4jronWm6SAqT8qWM2Bd2lQlmjHpLSqPT5vV3UYvmVULTu76KI6J2+DaxhAWXRsMx1Ym+IYjwtePhYXz+4y6PcJjtj7t3KOrcm5D5T0Kcj3Bah3fnYs4tzEGtettXJY2Ho4ucRhMXhWNaola5VxG3Vugc9d0rCbuns/UK0tVDO1YN8G5qQo4MVHPuYqya1+h4m4xAva8LlRkmg5ChaVHWadlrDD6ihWwWgk75nXnpvh/mt+8lxRfodmX29jGzJladW6TaTpwm5F++LRMsaB+SHXnNtXK1Bvc5qyr02mXglflUv/3jagzl2pR8zozuy7nJxP7Eqn1tbFEr0Gb57Lk1Ane1cVZy5WtE7l1ZfzkArk1bFHI++Mu2ua4XRTQge8uCHRaP3uDC39Uv3s56FtUp15/IW2E+UrQg/r5pF89WqNnnJiob/haVMHeUE8A5WBtNQbrdxOaO2OGrYVms2Vo7owZvVeatEzOePfcsLRGEvPciqillx71KnnP3FD7qGlAWeYtIV10pNwYf3HdNEhAJIwnTBC4EUYM82yTLx5sQy99AInOwz5OH13VA9HQsJKJl41NLDzjYnWEVpmbzFWKaZ4UIZ+sAuEVfAWCxzORvxEX+VOp2BDPE6+pTSHzJFM1NhWbL3y0xP4Muc+rZFyxFyr56SaNNDSuGqOWfS6jvhJJs1qEu4GCHV8pI0/cuIxQwRMi0I+xZP714dkCv+P9Nt2DC+vAdWrA1e+Z3YELq+CaHFwHbYQFg2UcFrw2DlGgvPY7dulmwyORwh8HK8JBE+FTHkmRGptQI0jowuHIj4DifB+saazL6+EL2O1YA3tjTbXAeGOLI+FLEPNtZeHBK8YDQJJTQkASID/BmkY4/sC9sbCsN9TVddQdS5u6x71aXbyxBO73d3/Xg15/jsjcxM2MmqcfJnAsG3nVjEQ0xoaE/yZpL/TiRWwm6ZLldCK/5TG0GA6HJ3KP/Fxqsx7Z21pZzwN6FoddvI3EnwPdCoP7Pk/KIfh+9yjsgVwXx3ECjhjUroP3g/57jdpHKmp2XSZ0RkmNP+ZN/2m2nv/rhHn3Hw== \ No newline at end of file diff --git a/docs/personalization/img/Diagram source/recommendation_overview.xml b/docs/personalization/img/Diagram source/recommendation_overview.xml deleted file mode 100644 index 48b06587498..00000000000 --- a/docs/personalization/img/Diagram source/recommendation_overview.xml +++ /dev/null @@ -1,179 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/docs/personalization/img/categories.png b/docs/personalization/img/categories.png deleted file mode 100644 index 1350cfdb22d..00000000000 Binary files a/docs/personalization/img/categories.png and /dev/null differ diff --git a/docs/personalization/img/full_content_export.png b/docs/personalization/img/full_content_export.png deleted file mode 100644 index caaf547ad4a..00000000000 Binary files a/docs/personalization/img/full_content_export.png and /dev/null differ diff --git a/docs/personalization/img/how_perso_works.png b/docs/personalization/img/how_perso_works.png deleted file mode 100644 index 390f0746e06..00000000000 Binary files a/docs/personalization/img/how_perso_works.png and /dev/null differ diff --git a/docs/personalization/img/incremental_content_export.png b/docs/personalization/img/incremental_content_export.png deleted file mode 100644 index ea394cceec2..00000000000 Binary files a/docs/personalization/img/incremental_content_export.png and /dev/null differ diff --git a/docs/personalization/img/perso_attributes_search.png b/docs/personalization/img/perso_attributes_search.png deleted file mode 100644 index 4589ab09160..00000000000 Binary files a/docs/personalization/img/perso_attributes_search.png and /dev/null differ diff --git a/docs/personalization/img/perso_dashboard_revenue.png b/docs/personalization/img/perso_dashboard_revenue.png deleted file mode 100644 index d1410bf2bbd..00000000000 Binary files a/docs/personalization/img/perso_dashboard_revenue.png and /dev/null differ diff --git a/docs/personalization/img/perso_segment_group_or.png b/docs/personalization/img/perso_segment_group_or.png deleted file mode 100644 index 272cf151d52..00000000000 Binary files a/docs/personalization/img/perso_segment_group_or.png and /dev/null differ diff --git a/docs/personalization/img/reco_full_import.png b/docs/personalization/img/reco_full_import.png deleted file mode 100644 index ed4f50d7232..00000000000 Binary files a/docs/personalization/img/reco_full_import.png and /dev/null differ diff --git a/docs/personalization/img/recommendation_overview.png b/docs/personalization/img/recommendation_overview.png deleted file mode 100644 index 6b0e60a05a8..00000000000 Binary files a/docs/personalization/img/recommendation_overview.png and /dev/null differ diff --git a/docs/personalization/img/recommendations.png b/docs/personalization/img/recommendations.png deleted file mode 100644 index ea7cc5dac76..00000000000 Binary files a/docs/personalization/img/recommendations.png and /dev/null differ diff --git a/docs/personalization/importing_historical_user_tracking_data.md b/docs/personalization/importing_historical_user_tracking_data.md deleted file mode 100644 index fd655a8e596..00000000000 --- a/docs/personalization/importing_historical_user_tracking_data.md +++ /dev/null @@ -1,44 +0,0 @@ ---- -description: Use historical user tracking data to build user profiles and generate better recommendations. ---- - -# Importing historical user tracking data - -The recommendation engine supports replaying historical user events by adding a special parameter *overridetimestamp* on the buy event to simulate the event date. -This is then used as the datetime of an event instead of the current timestamp of the request. - -To give an example: it's often requested to import the buy history of users to avoid the cold start problem and being able to start with good recommendations. -Instead of waiting till the user profile is built by collecting events from the day, you implemented the tracking. -Usually a curl input file is generated which creates buy requests that are sent to the tracking endpoint. - -!!! note "User identifiers" - - Ensure that user identifiers used in an import file are the same that are used in the live tracking, for example, the user login identifiers. - -There must be some validation to avoid importing buy events by any user. -Therefore a signature parameter needs to be added, which is calculated like the following: - -`String signature=md5(encode("&&&fullprice=&overridetimestamp=&quantity="));` - -!!! caution "Parameters without a value" - - The order of the parameters to be signed is crucial. - They must be sent in alphabetical order based on the parameter names to create a signature. - Encodings must always contain capital letters (for example, %3A and not %3a). - - If a parameter value is "" or "null" or "undefined" it needs to be excluded from the signing and must not be sent in the query string. - - **valid**: `https://event.perso.ibexa.co/api/00000/buy/johndoe/1/11?fullprice=19.99EUR&overridetimestamp=2012-01-01T11%3A00%3A00&quantity=1&signature=d0026f017ae823f19530d93318c5a2f6` - - **invalid**: `https://event.perso.ibexa.co/api/00000/buy/johndoe/1/11?fullprice=19.99EUR&overridetimestamp=2012-01-01T11%3A00%3A00&quantity=&signature=d0026f017ae823f19530d93318c5a2f6` - -## Example - -With a license key of "8695-1828-92810-5535-4239" and a purchase of certain products, there can be the following signature values: - -```text -https://event.perso.ibexa.co/api/00000/buy/johndoe/1/11?fullprice=19.99EUR&overridetimestamp=2012-01-01T11%3A00%3A00&quantity=1&signature=d0026f017ae823f19530d93318c5a2f6 -https://event.perso.ibexa.co/api/00000/buy/johndoe/1/94?fullprice=23.99EUR&overridetimestamp=2012-01-02T11%3A00%3A00&quantity=5&signature=53ae5744879d5a3ae833f3ef34109b44 -https://event.perso.ibexa.co/api/00000/buy/johndoe/1/78?fullprice=7.59EUR&overridetimestamp=2012-01-03T11%3A00%3A00&quantity=1&signature=d73e76754fb333e9733936bbd11bb5cd -... -``` diff --git a/docs/personalization/integrate_recommendation_service.md b/docs/personalization/integrate_recommendation_service.md deleted file mode 100644 index a2049f526c5..00000000000 --- a/docs/personalization/integrate_recommendation_service.md +++ /dev/null @@ -1,220 +0,0 @@ ---- -description: Integrate recommendation service into your website. -month_change: false ---- - -# Integrate recommendation service - -To return recommendations, you must first [enable the Personalization service](enable_personalization.md). -Next, integrate the service with [[= product_name =]] by activating event tracking and embedding recommendation results into the website. - -!!! note - - Examples below use '00000' as a customer ID for creating requests. - In a real-life scenario, use the customer ID that you receive from Ibexa. - -## Track events - -The service primarily relies on event tracking. -For the events to be registered, every content item or product page must call a special tracking URL. -The easiest way of embedding the tracking URL is placing a one pixel image on every page, like in the case of analytical tools or visitor counters. -A code that includes an image looks like this: - -`` - -where: - -- `` stands either for the user ID or session ID of the user who is currently logged into your website (any URL-encoded string is allowed). - -- `` stands for the [contentTypeId](content_model.md#content-information) of the content item or product that you want to track and recommend. - -- `` stands for the [id](content_model.md#content-information) of the content item or product that you want to track and recommend. - -The following examples show how you can integrate a CLICK event: - -PHP: - -``` php -$mandator_id = '00000'; -$content_type_id = '1'; -$product_id = '123'; -$server = '//event.perso.ibexa.co'; -$tracking = $server.'/api/'.$mandator_id.'/click/'.urlencode(user_id()).$content_type_id.$product_id; -echo ""; -``` - -JavaScript: - -``` js -var mandator_id = '00000'; -var content_type_id = '1'; -var product_id = '123'; -var server = '//event.perso.ibexa.co'; -var url = server + '/api/' + mandator_id + '/click/' + getUserId() + content_type_id + product_id; -var ycimg=new Image(1,1); -ycimg.src=url; -``` - -A similar tracking image can be placed on a confirmation page that ends the payment process. - -``` php -$server = '//event.perso.ibexa.co'; -foreach ($just_bought_products as $product_id) { - $tracking = $server.'/api/'.$mandator_id.'/buy/'.urlencode(user_id()).$content_type_id.$product_id; - echo "\n"; -} -``` - -## Embed recommendations - -As soon as the Personalization server collects enough events, it can generate recommendations. -The more tracking data is available, the more accurate the recommendations. -Recommendations can be fetched with the following calls, and the response is returned in JSON format. - -To return the most popular products, use: - -`https://reco.perso.ibexa.co/api/v2/00000//landing_page.json` - -To return products that the current user is most probably interested in, use: - -`https://reco.perso.ibexa.co/api/v2/00000//cross_sell.json?contextitems=OWNS,CLICKED` - -To return products that are most probably interesting for users interested in product 123, use: - -`https://reco.perso.ibexa.co/api/v2/00000//cross_sell.json?contextitems=123` - -A response with two recommendations resembles the following object: - -``` json -{ - "contextItems":[ - { - "itemId":123, - "itemType":1, - "sources":[ - "REQUEST" - ], - "viewers":0 - } - ], - "recommendationItems":[ - { - "itemId":555, - "itemType":1, - "relevance":127, - "links":{ - "clickRecommended":"//event.perso.ibexa.co/api/00000/clickrecommended/user/1/555?scenario=landing_page&modelid=5768", - "rendered":"//event.perso.ibexa.co/api/00000/rendered/user/1/555?scenario=landing_page&modelid=5768" - } - }, - { - "itemId":444, - "itemType":1, - "relevance":126, - "links":{ - "clickRecommended":"//event.perso.ibexa.co/api/00000/clickrecommended/user/1/444?scenario=landing_page&modelid=5768", - "rendered":"//event.perso.ibexa.co/api/00000/rendered/user/1/444?scenario=landing_page&modelid=5768" - } - } - ] -} -``` - -You can use the following code to make requests and parse results: - -``` php -$mandator_id = '00000'; -$license_key = '67890-1234-5678-90123-4567'; -$server = "https://reco.perso.ibexa.co"; -$scenario = "category_page"; -$url = $server.'/api/v2/00000/'.urlencode(user_id()).'/'.urlencode($scenario).'.json'; - -$curl = curl_init(); -$request = array( - CURLOPT_URL => $url, - CURLOPT_RETURNTRANSFER => true, - CURLOPT_USERPWD => "$mandator_id:$license_key"); -curl_setopt_array($curl, $request); -$body = curl_exec($curl); -$recommendations = json_decode($body); -if ($recommendations && isset($recommendations->recommendationResponseList)) { - foreach ($recommendations->recommendationResponseList as $product) { - $product_id = $product->itemId; - # load the product and create the recommendation HTML here - echo($product->itemId); - echo(" \n"); - }; -} else { - echo("Error: ".$body); -} -curl_close($curl); -``` - -## Send messages with recommendations - -Triggers are push messages with recommendations. -With this feature, your organization can invite individual visitors to return to the website, inform about a change in prices of products from their wishlist, suggest product alternatives, or remind them of items abandoned in a cart by delivering messages, for example, through email. -Before you can start [using triggers]([[= user_doc =]]/personalization/triggers/), you must contact [[= product_name_base =]] and define specific conditions, for example: - -- the time that must pass before messages start being sent -- content types and attributes that are included in a response -- a number of repetitions - -Triggers are then processed on the Personalization server and responses are delivered to a dedicated endpoint. - -To let your visitors receive emails with recommendations: - -1\. With the [User API](api_reference/user_api.md#post-requests), add the `e-mail` attribute (or another identifier) to the user record. - -2\. Prepare an endpoint to intercept push messages and pass them on, for example, to your mailing system. -Out of many options, it could be an [[= product_name_connect =]] [webhook]([[= connect_doc =]]/tools/webhooks/). -The endpoint must meet the following requirements: - - - must support POST requests - - must accept JSON objects in a format that resembles the following example: - -``` json -{ - "customerID":"1234567", - "userExternalId":"user@domain.com", - "triggerType":"REACTIVATION|ABANDONED_SHOPPING_CART", - "triggerName":"TRIGGER_REF_CODE", - "triggerOpenedLink":"NEW_EVENT_FOR_TRIGGER_OPENED", - "recommendations":[ - { - "itemId":959, - "itemType":46, - "clickRecommended":"CLICK_RECOMMENDED_LINK_WITH_TRIGGER_REF_CODE", - "attributes":{ - "ses_name":"Minimalista Coffee Table", - "ses_image":["img_1", "img_2"] - } - }, - { - "itemId":123, - "itemType":55, - "clickRecommended":"CLICK_RECOMMENDED_LINK_WITH_TRIGGER_REF_CODE", - "attributes":{ - "ses_name_for_type_55":"Minimalista Coffee Table" - } - } - ] -} -``` - -The object contains links to the recommended items (`triggerOpenedLink`, `clickRecommended`), which are monitored by the Personalization server to gather statistical data. - -!!! note "Support for endpoints with authorization" - - The trigger service supports additional Basic/Bearer token authentication to secure communication between the Personalization server and the endpoint. - If your endpoint requires authentication, you must provide Ibexa with the token. - -3\. Contact `support@ibexa.co` with your organization's requirements to have the email triggers enabled. - -## Advanced integration - -You can configure integration at a more advanced level to track more events, use additional parameters, apply custom scenario configurations, filters, and enable additional features. - -For more information about available functionalities, see [User Documentation]([[= user_doc =]]/personalization/personalization/). - -For more information about integrating the Personalization service, see [tracking API](tracking_api.md) and [tracking integration](tracking_integration.md) documentation. diff --git a/docs/personalization/legacy_recommendation_api.md b/docs/personalization/legacy_recommendation_api.md deleted file mode 100644 index d4ad29df541..00000000000 --- a/docs/personalization/legacy_recommendation_api.md +++ /dev/null @@ -1,273 +0,0 @@ ---- -description: An old method of fetching recommendations from the system using recommendation requests. ---- - -# Legacy Recommendation API - -!!! caution - - This is a page describing the old version of the recommendation API. - It's available for reference purposes only. - - Use the new [Recommendation API](recommendation_api.md) instead. - -This page describes how to fetch recommendations from the Recommender System through recommendation requests. -Before recommendation can be fetched from the recommendation controller, a sufficient number of events must be collected and the model build must finish successfully. - -!!! note - - **BASIC Authentication** for fetching recommendations is enabled for some configurations (for example for Gambio Plugin) by default. - Use the `customerid` as username and the license key as password. - The license key is displayed in the upper right in the [Admin GUI](https://admin.yoochoose.net/)) after you log in with your registration credentials. - - If you plan to use [JSONP](https://www.w3schools.com/js/js_json_jsonp.asp), authentication must be disabled. - If it's enabled in your solution (can be easily tested with a recommendation request in a browser), please contact the eZ Recommender support () for further information and disabling. - -## Getting recommendations - -Recommendations are retrieved from the Personalization server with RESTful requests by using the GET method. -The result is a list of item IDs that can be used to call the underlying CMS or shop system, to retrieve the necessary information for the rendering process. - -To allow the customer to retrieve different types of recommendations based on different methods (for example, Collaborative Filtering, Content Based, or Stereotype) the Recommendation System uses scenario IDs relating to a predefined set of configurations inside the system. -These configurations are a combination of methods and filters that should be applied including possible fallbacks if the requested methods don't deliver a result. - -A recommendation request looks like this: - -**`https://reco.perso.ibexa.co/\[solutionid\]/\[customerid\]/\[userid\]/\[scenarioid\].\[extension\]?parameter=value&\[attributename=attributevalue\]`** - -The embedded parameters `solutionid`, `clientid` and `userid` are the same as used for event tracking. Additional embedded parameters are described in the following table. - -| Parameter Name | Description | Values | -|-----|-----|------| -| `scenarioid` | The ID of the scenario used for providing recommendations. It's configured or predefined in the Administration GUI. | alphanumeric | -| `extension` | The format the server generates the response in. There are three formats supported: JSON, XML and JSONP. For more information, see [Response Handling](#response-handling). | json, xml or jsonp | - -## Basic Request Parameters - -Using additional query string parameters one can customize the recommendation request. - -|Parameter name|Description|Values| -|---|---|---| -|`numrecs`|Defines the number of recommendations that should be delivered. Keep this amount as low as possible as this increases the response time of the recommendation call.|1 to 50 (default "10")| -|`contextitems` (required for context based recommendations)|Comma-separated list of items that the user is currently viewing on the webpage. All items must be from the same type. The type is defined in the scenario configuration.|comma separated list of item IDs (1 to 2147483647)| -|`itemid` (deprecated)|A single item to be used as a source for creating recommendations. This parameter is deprecated. Use `contextitems` instead.|1 to 2147483647| -|`outputtypeid` (required, if the scenario defined multiple output item types, otherwise it's optional)|Item type of the requested recommendations. This can differ from the input item type, for example, if you want to get recommendations for pictures based on an article the item type for pictures has to be used here. For a web shop this is probably not needed as only one type of items is tracked. Multiple item types are available only for advanced license.|numeric| -|`categorypath`|Base category path for providing recommendations. The format is the same as the category path for the event tracking. It's possible to add this parameter multiple times. The order of recommendations from the different categories is defined by the calculated relevance.|alphanumeric[/alphanumeric]*| -|`jsonpcallback` (used only for JSONP request)|Function or method name for a JSONP request. It can be a function ("callme"), or a method ("obj.callme").|valid JavaScript function call (by default "jsonpCallback")| - -An example of the recommendation request:  - -**`https://reco.perso.ibexa.co/ebl/0000/smith/productpage.json?contextitems=123&categorypath=%2FCamera%2FCompact&numrecs=8`** - -It fetches 8 recommendations for user Smith, who is watching the item 123 and the category *"/Camera/Compact"* from the scenario with the identifier productpage. - -!!! tip - - See the section [Advanced Request Parameter](#advanced-request-parameter) below in this document for advanced features. - - See the section [Integration best Practices](#integration-best-practices) below in this document for the implementation examples. - -## Response handling - -The recommendation request returns a list of item IDs that are JSON, JSONP or XML-formatted. -The result can be integrated into any webpage by using some lines of script code.  - -!!! tip - - See the [Quickstart Guide](integrate_recommendation_service.md) for a simple example written in PHP. - -The recommendation result list looks like the following: - -Example JSON response: - -``` json -{ recommendationResponseList: [  - { reason: "CF_I2I (context: ITEMS(s))",  - itemType: 2,  - itemId: 1399,  - relevance: 100 }, - { reason: "POPULARITY_SHORT_BUY (context: ITEMS(s))",  - itemType: 2,  - itemId: 4711,  - relevance: 91  - } ] } -``` - -Example JSONP response: - -``` json -jsonpCallback( -{ recommendationResponseList: [ - { reason: "CF_I2I (context: ITEMS(s))", - itemType: 2, - itemId: 1399, - relevance: 100 }, - { reason: "POPULARITY_SHORT_BUY (context: ITEMS(s))", - itemType: 2, - itemId: 4711, - relevance: 91 - } ] }) -``` - -Example XML response: - -``` xml - - - 1241769000 - POPULARITY_SHORT_BUY (context: ITEMS(s)) - 148 - 1 - - -``` - -The "reason" field string tells the user out of which model the recommendations were provided. The models are preconfigured by the Personalization server. -For example "*CF\_I2I (context: ITEMS(s))*" means that the model which provides the recommendation is "Collaborative Filtering based on an Item to Item similarity" with the context item as input. -The human readable explanation is (in this case) "Users who bought this item also bought these items". - -The "relevance" defines the similarity to the context item according to internal algorithm and scenario configuration. -A higher value means a "better" recommendation. The list of recommendations is sorted by the relevance in descending order. - -### Response Codes - -The Following HTTP response codes are used by the recommendation controller. - -|HTTP Status Code|Description| -|---|---| -|200 OK|Request was successfully processed.| -|304 Not Modified|Recommendation result was not modified since the time specified in the provided If-Modified-Since header.| -|400 Bad Request
414 Request-URI Too Long|The request is wrongly formatted. See response body for more information.| -|401 Unauthorized|Not valid authentication credentials.| -|403 Forbidden|Access denied.| -|404 Not Found|The requested element was not found. It can be, for example, customer ID (a.k.a. mandator ID), model ID, or scenario ID.| -|409 Conflict|The combination of used models and the recommendation request parameters doesn't allow to provide recommendations. This could be, for example, if personalized recommendations are requested for a user who has no history at all.| -|500 Internal Server Error|Unspecified error. Please inform support if you get this error repeatedly.| - -The body of the response in case of errors contains human-readable error message. -The format of error messages can be changed and should not be used for automated processing. - -## Advanced Request Parameter - -There are some additional special request parameters. - -###### any attribute name (used only if submodels are configured) - -Item's attribute, for example, color, price, and more. -These are customer specific and can only be understood by the recommender system if the item attributes are imported by using the YOOCHOOSE content import APIs. -There can be multiple attributename and attributevalue pairs. - -Legacy Recommendation API and [Submodel configuration]([[= user_doc =]]/personalization/recommendation_models/#submodels) is required for taking an advantage from this parameter. - -**Values**: alphanumeric=alphanumeric [&alphanumeric=alphanumeric] - -###### `usecontextcategorypath` - -If set to true, the category path of the contextitem(s) is resolved by the recommender engine from the internal store and used as base category path. -If more than one category is returned, all categories are used for providing recommendations. -Avoid setting this parameter to true to minimize the response time. -Use the parameter categorypath to provide the category to the recommender engine during the request. - -**Values**: true or false (default "false") - -###### `recommendCategory` (to be used only in the eZ Recommendation extension) - -If passed in combination with a "categorypath" value, the "closest" category the recommended items linked with is delivered in the response as additional field "category". - -```javascript -recommendationResponseList: [ { - itemId: 1007640000, - category: "09/0901/090113", ... } ... ] -``` - -This feature helps to find "better" template for articles, which are located in several categories. - -For example there is an article about football in the USA. -The article is located in both categories "/Sport/Football" and "/America/USA". -Depending on the category it's shown with a football field or the USA flag in the background. - -If this article is recommended and is clicked in the category "/Sport/Cricket" it must open with the "football" template. -If the article is clicked in the category "/America/Canada" it must open with the "USA" template. - -The category information is returned only if the article is located in several categories and the "better" category found. - -**Values**: true or false (default "false") - -## Recommendation Caching - -In most cases the response of the recommendation service can be cached for some time. -Depending on the used recommendation model and context it can dramatically reduce the number of recommendation requests and therefore the price for using the recommendation service. -Recommendation service support following HTTP headers to allow cache control on the client side: - -|Scope|||Example|Format| -|---|---|---|---|---| -|Request|`If-Modified-Since`|Allows a *304 Not Modified* to be returned if content is unchanged.|`If-Modified-Since: Sat, 29 Oct 2013 19:43:31 GMT`|"HTTP-date" format as defined by [RFC 2616](https://datatracker.ietf.org/doc/html/rfc2616)| -|Response|`Last-Modified`|The last modification date of the recommendations.|`Last-Modified: Tue, 15 Nov 2013 12:45:26 GMT`|-| -||`Expires`|Gives the date/time after which the response is considered to be outdated|`Expires: Thu, 01 Dec 2013 16:00:00 GMT`|-| - -The last modification timestamp indicates a change that could influence the recommendation response. -It depends on an updated recommendation calculation, an update of an item or some scenario configuration changes. -The expiration timestamp is a best-effort prediction based on the model building configuration and provided context. -The shortest expiration period is 5 minutes from the request time. The longest is 24 hours. -In the table below several examples are illustrated: - -| Model | Context | Expiration time | Description | -|------|------|-----|-----| -| Bestselling products last 7 days | no context | 24 hours | The model with the 7 days scope is usually built once a day. It can be cached for 24 hours. It has no context and can therefore be cached globally for all the users of a customer. | -| Also bought products in the last month | current product | 24 hours | The model with the 30 days scope is usually built once a day. The context is always the same. It can be cached for every product. The same result can be used for all users of a customer. | -| Also consumed read articles in the last hour | current article | 30 minutes | Models with a short scope are usually built several times a day or even per hour. In this case the expiration time is set to the half of the model build frequency/period. | -| Personalized recommendation based on the user's statistic | customers click history | now | Although the statistic model isn't updated within minutes, it's very likely that the context is changed shortly (customer clicks another product and therefore the click is added to his history). The expiration time should not be much longer than the user activity on the web page. | - -In most cases you don't need to calculate the expiration time manually. -The table above is provided for the orientation, how the Expires header of the HTTP response is calculated by the recommendation engine and already provided to your caching system. -You just need to make sure that the Expires header is used in the configuration of your caching system instead of a static value out of your configuration. - -## Integration best Practices - -There are several ways to integrate the REST calls to the Recommendation engine and avoid the blocking of the web page rendering, if the communication with the Recommender is distrusted or interrupted. - -#### **Simple Way** - -The simplest way to load recommendations is to synchronously request the Recommendation Engine for recommendations as they're needed. -This way is sufficient in most cases. The most important drawback is that the request time increases by the time of the recommendation request. -If the network is overloaded or the Recommendation Engine isn't available it can lock the request. - -#### Loading in the bottom - -You can place the code that loads the data from the eZ Recommender at the bottom of the generated document and flush the output buffer to the client just before requesting recommendations. -The browser gets a whole page to render and can display it even if the very end of the page is still loading. -Then the JavaScript code with the recommendation information loaded at the bottom of the page must fill the gaps on the page with recommendation as soon as it's completely loaded. - -#### Non-blocking loading in the background - -If the website is implemented in a language which supports multithreading or non-blocking I/O, it's possible to start the recommendation request just after the browser request is received. -The page generation and the recommendation requests are accomplished in parallel. -By combining this idea with the previous solution and placing the recommendation results at the bottom of the page you can avoid any interruption in the processing. - -#### Using JSONP to load from JavaScript - -It's not possible to request the recommendation controller server directly from the JavaScript (over AJAX library or directly over XMLHttpRequest) because of the cross-domain restriction in most browsers. -One of the possible technique to work around this limitation is [JSONP](https://en.wikipedia.org/wiki/JSONP). - -#### Loading over proxy - -A better solution in comparison with JSONP is to provide the proxy on the server side, which forwards script requests to the Recommender system. -It can be implemented as a very simple proxy using the [mod\_proxy module](https://httpd.apache.org/docs/2.2/mod/mod_proxy.html) of Apache Webserver. -It transfers the data and the JavaScript renders the response into HTML itself. - -An alternative approach is creating the HTML code on the server side for every target page in a sense to simplify the script on the client side. - -As a possible implementation of such a proxy following tools can be used: the apache proxy module, some independent daemon like “netcat” or a PHP script. - -#### Comparison - -An overview of pros and cons for each of the above techniques: - -|Problem|Simple Way|Bottom loading|Background loading|JSONP|XMLHttpRequest + Proxy| -|---|---|---|---|---|---| -|Isn't blocked by ad blockers or no-track plug-ins|Yes|Yes|Yes|-|Yes| -|Works if JavaScript is disabled|Yes|depends|-|-|-| -|Works for server without multithreading functionality|Yes|Yes|-|Yes|Yes| -|Compatible with frontend caching on the server|-|-|-|Yes|Yes| -|Doesn't delay page rendering|-|depends|depends|Yes|Yes| -|Supports authentication for recommendation fetching|Yes|Yes|Yes|-|depends| diff --git a/docs/personalization/personalization.md b/docs/personalization/personalization.md deleted file mode 100644 index 68ba2eafdaa..00000000000 --- a/docs/personalization/personalization.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -description: Personalization tracks consumed content and suggests targeted content to your website visitors. -page_type: landing_page ---- - -# Personalization - -[[= product_name_base =]] Personalization is a service that allows you to track the visitors of your website and offers personalized recommendations or serves targeted content, based on their preferences and behavior. - -Personalization can be used both by publishers, for example, to track content consumption and promote content, and in e-commerce, to drive purchases. - -To provide online recommendations, the service must at least: - -- Track user actions through a web browser or a mobile app -- Store the user actions -- Use the data to generate recommendations -- Provide recommendations on a customer's website - -[[= cards([ - "personalization/personalization_guide", - "personalization/how_it_works", - "personalization/enable_personalization", - "personalization/integrate_recommendation_service", - "personalization/api_reference/api_reference", -], columns=3) =]] - - - - - diff --git a/docs/personalization/personalization_guide.md b/docs/personalization/personalization_guide.md deleted file mode 100644 index 0bb32baff3b..00000000000 --- a/docs/personalization/personalization_guide.md +++ /dev/null @@ -1,135 +0,0 @@ ---- -description: Discover Personalization - a cloud-based service that tracks and analyzes customer behaviors. ---- - -# Personalization product guide - -## What is Personalization - -Personalization engine is a cloud-based service that tracks and analyzes customer behaviors and delivers optimized, user-tailored content, and information. - -The engine uses artificial intelligence and machine learning modeling to learn and create behavioral patterns and generate recommendations ready to be presented on one or more websites hosted by the [[= product_name =]] instance. - -## Availability - -Personalization service is available in all supported [[= product_name =]] versions and editions. - -Pricing is based on the number of Personalization API events. - -To enable recommendation engine, request access to the service by [creating an account]([[= user_doc =]]/personalization/enable_personalization/#request-access-to-the-server). - -After setting up an account and receiving credentials, pass them to your administrator who can configure Personalization service in your [[= product_name =]] instance. - -Now, you can start collecting data and boost your business. - -## How does Personalization work - - -![How it works](how_perso_works.png) - - -Personalization with tracking scripts, monitors individual sessions from user’s behavior and interest data through events (clicks, viewed articles, pages, purchases) and demographic data (location, industry, occupation). - -Next, collects data and computes models thanks to complex algorithms. - -Personalization is SiteAcces-aware, it means it can serve on multiple sites with different customer IDs and deliver recommendations for each site (for example, if you host multi language site). - -Use Twig extension to add a tracking script and implement it into your site configuration. - -## Capabilities - -### Models - -Models are statistics-based and perform calculations based on data from content, users and events. - -They work in the background and update on regular time intervals to ensure best and accurate recommendations. Personalization service includes a few predefined models according to your needs and agreements between your organization and [[= product_name_base =]]. - -If you need more customized models, contact customer support. - -Personalization service includes the following model types: - -- popularity models - based on trends, Top clicked, Top purchased, algorithm recommends trending content - -- collaborative models - generate predictions by analyzing user behavior and their interactions with target items, compares to other users behavior with similar browsing behavior - -- editorial models - returns items, products from the manually prepared list - -- B2B models - returns items clicked or bought by a segment group of a company - -![Structure](categories.png) - - -### Scenarios - -Scenarios are sequences of events. -You can use scenarios to determine how and when render particular content to your customers. -Each scenario can include also subscenarios used for granular personalized rendering of content. - -### Segments - -Use segments to get content targeted at particular user groups. -Segments calculate models based on the segment attribute factor. Assign users to different recommendation groups and create advanced logic with operators to get best segmentation for your audience. - -![Segments](perso_segment_group_or.png) - -![Recommendations](recommendations.png) - - -### REST API - -Personalization includes interface as API that you can use to interact with stored data and to send requests and export data from the service. - -For more information, see documentation for API operations available for Personalization: - -- [Tracking API](api_reference/tracking_api.md/) -- [Content API](api_reference/content_api.md/) -- [Recommendation API](api_reference/recommendation_api.md/) -- [User API](api_reference/user_api.md/) - -## Benefits - -### Web design and content development - -Create websites with content targeted at your customers. -Deliver your visitors relevant content and build trust in your brand. - -### Reduce clutter and improve customer retention - -Help users find content of their interest quicker, use words to appeal to individual customers and segments. -Enrich customer data by integrating [[= product_name_base =]] Personalization with other systems such as ERP, CRMs. -Track user’s scenarios and develop strategies that match your strategies and improve engagement. - -### Satisfy customer expectations - -Personalization engine shows customers products relevant to their interests, builds a feeling of connection and understanding. - -### Increase customer engagement - -Targeted and customized content considerably improves engagement by delivering content that fits your visitors interests and anticipates their needs. -This creates a bound between your brand and users who spend more time on your website, and are more likely to come back to your services. -A kind of loyalty is created. - -### Improve customer experience - -Stand out from other companies by provided well-suited content and make a space for your customers where they feel known and valued and treated exceptional. -Build trust and a bond with visitors, who are more likely to come back. - -### Increase average order value - -Apply collaborative models with predictive analysis and find out what motivates users to put extra items into their carts. -Start building predictions of their behaviors and suggest items, products your visitors are willing to buy. - -![Dashboard](perso_dashboard_revenue.png) - - -### Measure your return and boost conversion rates - -Connect Personalization engine with your eCommerce shop, focus on the revenue generated by recommendations. -Track what recommendations are shown to your visitors and analyze conversion rates. -Effectively evaluate quality of recommendations and compare with your KPIs. - -## Use cases - -- [eCommerce]([[= user_doc =]]/personalization/use_cases/#ecommerce) -- [Content publishing]([[= user_doc =]]/personalization/use_cases/#content-publishing) -- [Multiple website hosting]([[= user_doc =]]/personalization/use_cases/#multiple-website-hosting) diff --git a/docs/personalization/recommendation_integration.md b/docs/personalization/recommendation_integration.md deleted file mode 100644 index 769f3f16710..00000000000 --- a/docs/personalization/recommendation_integration.md +++ /dev/null @@ -1,59 +0,0 @@ ---- -description: Methods for REST call with Personalization server. ---- - -# Recommendation integration - -There are several ways to integrate the REST calls with the Personalization server and to avoid blocking webpage rendering, if the communication with the Recommender is distrusted or interrupted. - -## Use page blocks - -[[= product_name =]] ships with a number of page blocks that editors can place on landing pages and configure to present scenario results. -To work, these blocks require that Personalization and scenarios are properly configured. -For a list of all page blocks that are available out-of-the-box, see [Page block reference]([[= user_doc =]]/content_management/block_reference/). - -## Request recommendations synchronously - -The simplest way to load recommendations is to synchronously request the Personalization server for recommendations as they're needed. This way is sufficient in most cases. -The most important drawback is that the request time increases by the time of the recommendation request. -If the network is overloaded or the Personalization server isn't available, it can lock the request. - -## Load in the bottom - -You can place the code that loads the data from the eZ Recommender at the bottom of the generated document and flush the output buffer to the client before requesting recommendations. -The browser gets a whole page to render and can display it even if the very end of the page is still loading. -Then the JavaScript code with the recommendation information loaded at the bottom of the page must fill the gaps on the page with recommendations as soon as it's completely loaded. - -## Non-blocking load in the background - -If the website is implemented in a language that supports multithreading or non-blocking I/O, the recommendation request can start right after the browser request is received. -The page generation and the recommendation requests are accomplished in parallel. -By combining this idea with the previous solution and placing the recommendation results at the bottom of the page you can avoid any interruption in the processing. - -## Load from JavaScript using JSONP - -You cannot request the recommendation controller server directly from the JavaScript (over AJAX library or directly over XMLHttpRequest) because of the cross-domain restriction in most browsers. -One of the possible ways to work around this limitation is JSONP. - -## Load over proxy - -A better solution than JSONP is to provide the proxy on the server side, which forwards script requests to the Personalization service. -It can be implemented as a basic proxy by using the `mod_proxy` module of the Apache Webserver. -It transfers the data and the JavaScript renders the response into HTML itself. - -An alternative approach is to create the HTML code on the server side for every target page, to simplify the script on the client side. - -You can use the following tools as an implementation of such a proxy: the Apache proxy module, an independent daemon like “netcat” or a PHP script. - -## Comparison - -An overview of pros and cons for each of the presented techniques: - -|Feature|Synchronous loading|Bottom loading|Background loading|JSONP|XMLHttpRequest + Proxy| -|---|---|---|---|---|---| -|Isn't blocked by ad blockers or no-track plug-ins|✔|✔|✔|-|✔| -|Works if JavaScript is disabled|Yes|depends|-|-|-| -|Works for server without multithreading functionality|✔|✔|-|✔|✔| -|Compatible with frontend caching on the server|-|-|-|✔|✔| -|Doesn't delay page rendering|-|depends|depends|✔|✔| -|Supports authentication for recommendation fetching|✔|✔|✔|-|depends| diff --git a/docs/personalization/tracking_integration.md b/docs/personalization/tracking_integration.md deleted file mode 100644 index 3ab8b635424..00000000000 --- a/docs/personalization/tracking_integration.md +++ /dev/null @@ -1,79 +0,0 @@ ---- -description: See the methods of event tracking integration using tracking from server or from client-side. -month_change: false ---- - -# Tracking integration - -There are several ways to integrate event reporting into the webpage. -The simplest way is to generate code of a tiny image and put it on the webpage where the event must be sent [pixel tracking](integrate_recommendation_service.md#track-events). - -For example, with HTML:  - -``` html - -``` - -or with JavaScript: - -``` js - -``` - - - -The drawback of this option is that such calls can be blocked by ad blockers or do-not-track plugins on the client side. - -## Server-side tracking - -Another option is to call the tracker from the server. -The most important drawback is that the event request increases the general request time. -If the network is overloaded or the Personalization server isn't available, the number of requests can grow and lead to a stalled and finally crashing HTTP service. -See below the techniques that help avoid these problems. - -### Tracking at the bottom - -You can place the code at the very end of the generating script and flush the output buffer to the client before sending the events. -The connection to the browser can remain open for the time of processing, but it's transparent for the end user. - -### Tracking asynchronously - -If the website is implemented in a language that supports multithreading, non-blocking I/O or messaging infrastructure, you can start the event request right after the browser request is received instead of waiting for this process to finish. - -## Client-side tracking - -### Using JSONP - -Another solution is to provide a proxy on the server side, which forwards script requests to the Personalization server. -In this model, the requests are triggered from the client, when the page is already loaded and rendered. -It's impossible to request the recommendation controller server directly from JavaScript (either through the AJAX library or directly over XMLHttpRequest) because of the cross-domain restriction in most browsers. -One possible work around this limitation is [JSONP](https://www.w3schools.com/js/js_json_jsonp.asp). - -### Using server proxy - -Another option is to tunnel the JavaScript request through the proxy on the same server. -The server only forwards requests to the Personalization server. -It can be an implemented Apache proxy module, an independent daemon (for example, "netcat"), or a PHP script. - -## Comparison - -An overview of pros and cons for every technique: - -| Feature | Pixel | Server-side | Page bottom | Async. reporting | JSONP | XMLHttpRequest + Proxy | -|----|-----|-----|-----|-----|-----|------| -| Isn't blocked by ad blockers or do-not-track plug-ins. |-|✔|✔|✔|-|✔| -| Works if JavaScript is disabled. |✔|✔|✔|✔|-|-| -| Is compatible with frontend caching on the server. |-|-|-|-|✔|✔| -| Doesn't delay page rendering. |✔|-|✔|✔|✔|✔| -| Supports authentication for event tracking (not implemented yet). |-|✔|✔|✔|-| Yes/No | - -!!! tip "The recommended approach" - - An Ibexa-recommended solution is to use pixel tracking for non-complex events, or where every page is generated on the server side without any caching logic. - For hints about preloading image URLs with JavaScript elements (`var img = new Image(); img.src="uri"`) or without them (`<img src="uri"... />`), see [How to Preload Images](https://www.mediacollege.com/internet/javascript/image/preload.html). - - If you plan to implement caching mechanisms and more complex events like Consume (depending on the viewing time of the page), Basket (which is usually an in-page event) or custom in-page events that take place on the client side, a JavaScript implementation is strongly encouraged. - For a sample script and instructions, see [Track with ibexa-tracker.js](tracking_with_ibexa-tracker.md). diff --git a/docs/personalization/tracking_with_ibexa-tracker.md b/docs/personalization/tracking_with_ibexa-tracker.md deleted file mode 100644 index 8357133ab7a..00000000000 --- a/docs/personalization/tracking_with_ibexa-tracker.md +++ /dev/null @@ -1,102 +0,0 @@ ---- -description: Integrate tracking with a Google-style JavaScript. -month_change: false ---- - -# Track events with ibexa-tracker.js - -This is another example of how you can integrate the tracking with a Google-style JavaScript in your site. -The approach is very generic and evaluate it if it meets your **requirements and security policy**. - -If you want the `userid` to be generated automatically, set user parameter as empty `''` in the `_ycq.push` calls. -If a predefined cookie already exists, it is used. - -Otherwise a new one is created. - -## Tracking code quickstart - -The Personalization JavaScript is a Google-like tracking API (ga.js) that you can paste into your pages. -It activates the tracking by inserting  or into the page. - -To use this mechanism on your pages, copy the code snippet below, and replace: - -- `` with the customer ID -- `` with the content type ID -- `` with the content item ID -- `` with an empty string for cookie based anonymous user or with the value generated by your user identifier system for logged-in user. In case user activity should not be tracked, 'not_defined' value should be used to still have an event stored without a link to the user. - -All identifiers can be any form of string. -Paste this snippet into your website template page so that it appears before the closing `` tag. - -``` js - -``` - -## Asynchronous syntax - -The `_ycq` object is what makes the asynchronous syntax possible. -It acts as a queue, which is a "first-in, first-out" (FIFO) data structure that collects API calls until `ibexa-tracker.js` is ready to run them. -To add to the queue, use the `_ycq.push` method. - -To push an API call into the queue, you must convert it from the traditional JavaScript syntax to a command array. -Command arrays are JavaScript arrays that conform to a certain format. -The first element in a command array is the name of the tracker object method that you want to call. -It must be a string. The remaining elements are the arguments you want to pass to the tracker object method. -These can be any JavaScript value. - -## Tracking code - -The `_ycq` global object can be used directly for asynchronous page tracking with the `push(...)` method.  - -### `_ycq` object methods - -#### push - -`push(commandArray)` - -Executes the command array, which is a JavaScript array that conforms to the following format.  -The first element of the array must be the name of a tracker object method passed as a string.  -The rest of the array elements are the values to be passed in as arguments to the function.  - -Here is an example of typical usage of the method: - -``` js -var _ycq = _ycq || []; -_ycq.push(['_setMandator', '']); -_ycq.push(['_trackEvent', '1', 'click', '10', '']); -``` - -## Tracker object names - -| Object | Description | Example | -| --------------- | ------------- | ------ | -| `_setMandator ` | - Executed with one additional parameter: `MandatorId` | `_ycq.push (['_setMandator' , '']);` | -| `_trackEvent` | - Executed with four additional parameters: `ItemType`, `EventType`, `ItemId`, `UserId`.
- `EventType` can be any of the [described types]([[= user_doc =]]/personalization/event_types/) | capturing an event: `_ycq.push(['_trackEvent', '1', 'buy', '10', '']);` | -| `_trackTimedEvent` | - Executed with five additional parameters: `ItemType`, `EventType`, `ItemId`, `Timeout`, `UserId`.
- `EventType` can be any of the [described types]([[= user_doc =]]/personalization/event_types/).
- `Timeout` can be any integer greater than 0 representing time in ms | consume event sent after 20s: `_ycq.push(['_trackTimedEvent', '1', 'consume', '10', '20000', '']);` | -| `_login` | - Executed with two additional parameters: anonymous userId, pseudonymous userId.
- It is to be triggered when a user logs in and the tracking identity is changed.
| - | -| `ycreco=true` | - If you want to send a click recommended event you can append the following parameter to the recommended item URLs: | [https://mydomain.com/mypage.html?ycreco=true](https://mydomain.com/mypage.html?ycreco=true) or
[https://mydomain.com/mypage.html?myparameter=x&ycreco=true](https://mydomain.com/mypage.html?myparameter=x&ycreco=true) | - -## Tracking with HTML event handlers - -The asynchronous tracking syntax should also be used from within DOM event handlers. -For example, the following button generates an event when it's clicked: - -``` js -