# Search Configuration

You can integrate the Emporix Commerce Engine with any index providers by leveraging the webhook events concept.\
Emporix CE recognizes all changes around a product item like the product itself, its price, category or availability related to the product. If any of the connected entities is modified, our platform prepares an index-item object which contains all the necessary data.

<details>

<summary>See the event schema for an updated index item - <code>IndexItemUpdated</code>.</summary>

```json
"id": "String",
"code" : "String",
"siteCode" : "String",
"name" : "Map<String,String>", // Localized map
"description" : "Map<String, String>", // Localized map
"categoryAssignments" : [
  {
    "id" : "String",
    "code" : "String",
    "name" : "String",
    "localizedName" : "Map<String,String>", // Localized map
    "localizedSlug" : "Map<String,String>", // Localized map
    "parent" : "Object"
  }
],
"tags" : String[], // Array of strings
"popularity" : "Integer",
"prices" : [
  {
    "id" : "String",
    "itemId" : {
      "id" : "String",
      "itemType" : "String" // PRODUCT
    },
    "currency" : "String",
    "originalAmount" : "Number",
    "effectiveAmount" : "Number",
    "location" : {
      "countryCode" : "String"
    },
    "salePrice" : {
      "discountAmount" : "Double",
      "discountRate" : "Double",
      "description" : "String"
    },
    "priceModelId" : "String",
    "priceModel" : {
      "id" : "String",
      "name" : "Map<String,String>", // Localized map
      "description" : "Map<String,String>", // Localized map
      "includesTax" : "Boolean",
      "measurementUnit" : {
        "quantity" : "Double",
        "unitCode" : "String"
      },
      "tierDefinition" : {
        "tierType" : "String",
        "tiers" : [
          {
            "id" : "String",
            "minQuantity" : {
              "quantity" : "Double",
              "unitCode" : "String"
            }
          }
        ]
      }
    },
    "restrictions" : {
      "validity" : {
        "from" : "String",
        "to" : "String"
      },
      "siteCodes" : "String[]" // Array of strings
    },
    "tierValues" : [
      {
        "id" : "String",
        "priceValue" : "Double"
      }
    ],
    "mixins" : "Map<String,Object>",
    "siteCode" : "String"
  }
],
"medias" : [
  {
      "url" : "String",
      "position" : "Integer",
      "contentType" : "String",
      "customAttributes" : Map<String, Object>
  }
],
"availability" : {
  "id" : "String",
  "stockLevel" : "Double",
  "productId" : "String",
  "site" : "String",
  "available" : "Boolean",
  "popularity" : "Integer",
  "distributionChannel" : "String"
},
"mixins" : "Map<String,Object>",
"published" : "Boolean",
"available" : "Boolean"

```

</details>

<details>

<summary>See an example of the index-item object and what is emitted every time a product is created or updated.</summary>

```json
{
  "availability": {
    "available": false,
    "distributionChannel": "ASSORTMENT",
    "id": "main:643dacfad50d664c58694c2d",
    "popularity": -2147483648,
    "productId": "643dacfad50d664c58694c2d",
    "site": "main",
    "stockLevel": 2313
  },
  "available": false,
  "categoryAssignments": [
    {
      "id": "79eccb8b-b163-4cb9-9528-ed9468b9f740",
      "localizedName": {
        "en": "c1"
      },
      "name": "c1"
    }
  ],
  "code": "Oranges",
  "id": "643dacfad50d664c58694c2d",
  "medias": [
    {
      "contentType": "image/jpeg",
      "customAttributes": {
        "height": 800,
        "name": "oranges.jpeg",
        "sizeKB": 156.7138671875,
        "width": 1200
      },
      "mainImage": false,
      "url": "http://res.cloudinary.com/saas-ag/image/upload/v1681763617/lsindexdbstage/media/643dad208fc03d22f4e857e6"
    }
  ],
  "popularity": -2147483648,
  "prices": [
    {
      "currency": "EUR",
      "effectiveAmount": 1.55,
      "id": "643dad10c0dc2925289a6206",
      "itemId": {
        "id": "643dacfad50d664c58694c2d",
        "itemType": "PRODUCT",
        "name": {
          "en": "Oranges"
        }
      },
      "location": {
        "countryCode": "DE"
      },
      "originalAmount": 1.55,
      "priceModel": {
        "description": {
          "en": "Default price model"
        },
        "id": "63402c86af907617bb4e1234",
        "includesTax": false,
        "measurementUnit": {
          "quantity": 1,
          "unitCode": "pc"
        },
        "name": {
          "en": "Default price model"
        },
        "tierDefinition": {
          "tierType": "BASIC",
          "tiers": [
            {
              "id": "63402c86af907617bb4e9826",
              "minQuantity": {
                "quantity": 0,
                "unitCode": "pc"
              }
            }
          ]
        }
      },
      "priceModelId": "63402c86af907617bb4e1234",
      "restrictions": {
        "siteCodes": [
          "main"
        ]
      },
      "siteCode": "main",
      "tierValues": [
        {
          "id": "63402c86af907617bb4e9826",
          "priceValue": 1.55
        }
      ]
    }
  ],
  "published": true,
  "siteCode": "main",
  "tags": [
    "product",
    "published"
  ]
}

```

</details>

<details>

<summary>See the event schema for a deleted index item - <code>IndexItemDeleted</code>.</summary>

```json

"id": "String",
"siteCode" : "String"

```

</details>

<details>

<summary>See an example message that is sent when a product is deleted.</summary>

```json
{
  "id": "643dab38a9e0f24d6bda45ee",
  "siteCode": "main"
}

```

</details>

## Enabling webhook service

1. Log in to the Management Dashboard and go to **Administration** -> **Webhooks**.
2. Choose the webhooks strategy that best suits your needs.

{% hint style="info" %}
For more information on webhooks strategies and configuration, see [Webhooks](https://developer.emporix.io/ce/management-dashboard/administration/webhooks).
{% endhint %}

3. Extend the **Index item** webhook details and enable the **Index item updated** and the **Index item deleted** events.

<figure><img src="https://3057647601-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbTY7EwZtYYQYC6GOcdTj%2Fuploads%2Fgit-blob-ac0f677d1c7d5a5c3544c5a68d161a9884ec4678%2Fmdwebhooks.png?alt=media" alt=""><figcaption></figcaption></figure>

4. Depending on the chosen webhook strategy, there are different ways to configure the endpoints for receiving notifications about events happening in the system. Configure your strategy to be able to process the events.

<details>

<summary>See example webhook configuration</summary>

For Svix-shared strategy, you can use Open Svix Dashboard option to configure the relevant endpoints.

1. Go to **Endpoints** and choose the **Add Endpoint** button to start the endpoint configuration.

For testing purposes, you can use **Svix Play** configuration, it automatically creates a sandbox destination.

<figure><img src="https://3057647601-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbTY7EwZtYYQYC6GOcdTj%2Fuploads%2Fgit-blob-4d4fda6d084161559a21b58e1ace67e44e82b2ce%2FendpointURL.png?alt=media" alt=""><figcaption></figcaption></figure>

2. In the **Message Filtering** section, choose the **index-item** events:

* `index-item.deleted`
* `index-item.updated`

<figure><img src="https://3057647601-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbTY7EwZtYYQYC6GOcdTj%2Fuploads%2Fgit-blob-72db540c07e089c4d5aa974608c95f44dcfd93d4%2Fmessage_filtering.png?alt=media" alt=""><figcaption></figcaption></figure>

3. Save your endpoint configuration by choosing the **Create** button.

You can test the configuration by going back to the Emporix Management Dashboard and adding a new product.\
After a few minutes, you should see the updated delivery statistics in Svix.

<figure><img src="https://3057647601-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbTY7EwZtYYQYC6GOcdTj%2Fuploads%2Fgit-blob-1ff2fdfc00f32453cb7b09d06630ebcddb6ee431%2Fsvix.png?alt=media" alt=""><figcaption></figcaption></figure>

</details>

## Search provider configuration

Commerce Engine allows you to configure your own search functionality. You can choose any provider that suits your needs. For demonstration purposes of how you can configure search through the webhooks functionality, we present examples of configuring **Algolia** and **BatteryIncluded**. These are the search engines that can be configured to work with Emporix CE and Svix.

{% hint style="info" %}
To learn more about **Algolia**, see [algolia.com](https://www.algolia.com/).\
To learn more about **BatteryIncluded**, see [batteryincluded.ai](https://batteryincluded.ai/en/).
{% endhint %}

### Prerequisites

Before you start configuring a search engine in Emporix, ensure the following:

* Enable the **Index item updated** and **Index item deleted** events are enabled in Management Dashboard, see [Enabling webhook service](#enabling-webhook-service).
* Activate Algolia or BatteryIncluded account.

**Initial steps**

1. Log in to the Management Dashboard and go to **Administration** -> **Webhooks**.
2. Go to Svix by choosing the **Open Svix Dashboard** button.
3. To start the endpoint configuration, go to **Endpoints**.
4. Follow the steps for one of the providers: Algolia or BatteryIncluded.

### Algolia Configuration

**Creating and updating products**

1. In **Endpoints**, choose **Add Endpoint** and fill in the fields with the following values:

* Endpoint URL - `https://{ALGOLIA_APPLICATION_ID}.algolia.net/1/indexes` - provide your Algolia application ID
* Description - `Algolia Create/Update`
* Message filtering - select only the `index-item.updated` event

<figure><img src="https://3057647601-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbTY7EwZtYYQYC6GOcdTj%2Fuploads%2Fgit-blob-5719f426b3ebb0b5c2b71945f0031bac3aa7f26d%2Falgolia.png?alt=media" alt="" width="563"><figcaption></figcaption></figure>

2. Choose **Create** and check if your configuration was properly saved.
3. Go to the **Advanced** tab, provide the required custom headers and enable the transformation feature:
   * Key: `X-Algolia-API-Key`\
     Value: `YOUR_ALGOLIA_ADMIN_API_KEY`
   * Key: `X-Algolia-Application-Id`\
     Value: `YOUR_ALGOLIA_APPLICATION_ID`

Find the right values for your keys in your application settings (API Keys) in your Algolia account.

4. In the **Transformations** section, set the **transformation** feature to **enabled**.

<figure><img src="https://3057647601-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbTY7EwZtYYQYC6GOcdTj%2Fuploads%2Fgit-blob-650d3a3f8d29416ee71458a33b7e158ec3764027%2Falgolia2.png?alt=media" alt="" width="563"><figcaption></figcaption></figure>

5. In **Edit transformation**, start working on the Algolia mapping.

Since there are differences between the default mapping in Svix and Algolia requirements, we need to adjust the mapping to make it work properly.

The default mapping available in Svix is as follows:

```json
/**
 * @param webhook the webhook object
 * @param webhook.method destination method. Allowed values: "POST", "PUT"
 * @param webhook.url current destination address
 * @param.webhook.eventType current webhook Event Type
 * @param webhook.payload JSON payload
 * @param.webhook.cancel whether to cancel dispatch of the given webhook
 */
function handler(webhook) {
  // modify the webhook object...
  
  // and return it
  return webhook
}
```

\
According to Algolia API Reference, the request that should be sent is as follows:

```json
curl "https://${APPLICATION_ID}.algolia.net/1/indexes/contacts/myID" \
     -X PUT \
     -H "X-Algolia-API-Key: ${API_KEY}" \
     -H "X-Algolia-Application-Id: ${APPLICATION_ID}" \
     -d '{
            "name": "Betty Jane Mccamey",
            "company": "Vita Foods Inc.",
            "email": "betty@mccamey.com"
         }'
```

To learn more about Algolia API, see [Algolia API Reference](https://www.algolia.com/doc/rest-api/search/#add-or-replace-object-by-id).

In the **Edit transformation** section, change the code to create the right mapping:\
\
a. Change the http method:

```json
/**
 * @param webhook the webhook object
 * @param webhook.method destination method. Allowed values: "POST", "PUT"
 * @param webhook.url current destination address
 * @param.webhook.eventType current webhook Event Type
 * @param webhook.payload JSON payload
 * @param.webhook.cancel whether to cancel dispatch of the given webhook
 */
function handler(webhook) {

  webhook.method = "PUT";
  return webhook
}
```

\
b. Modify the target URL:

```json
/**
 * @param webhook the webhook object
 * @param webhook.method destination method. Allowed values: "POST", "PUT"
 * @param webhook.url current destination address
 * @param.webhook.eventType current webhook Event Type
 * @param webhook.payload JSON payload
 * @param.webhook.cancel whether to cancel dispatch of the given webhook
 */
function handler(webhook) {

  var indexName = "emporix_" + webhook.payload.siteCode;
  webhook.url = webhook.url + "/" + indexName + "/" + webhook.payload.id;
  webhook.method = "PUT";
  return webhook
}
```

\
c. Optional: Modify the message body. For example, you can add additional field like image based on media field:

```json

/**
 * @param webhook the webhook object
 * @param webhook.method destination method. Allowed values: "POST", "PUT"
 * @param webhook.url current destination address
 * @param.webhook.eventType current webhook Event Type
 * @param webhook.payload JSON payload
 * @param.webhook.cancel whether to cancel dispatch of the given webhook
 */
function handler(webhook) {

  if(webhook.payload.medias && webhook.payload.medias.length > 0) {
    webhook.payload.image = webhook.payload.medias[0].url;
  }

  var indexName = "emporix_" + webhook.payload.siteCode;
  webhook.url = webhook.url + "/" + indexName + "/" + webhook.payload.id;
  webhook.method = "PUT";
  return webhook
}
```

6. Choose **Run test** for the `index-item.updated` payload. As a result, you can see your transformed output.
7. If the output is correct, save your changes.

To test the configuration, create a product in Management Dashboard and after a few minutes check if it appears in your index in the Algolia account. With this configuration, every time when a product is created or updated, the appropriate event is propagated to Svix, transformed and sent to Algolia.

**Deleting products**

1. In **Endpoints**, choose the **Add Endpoint**. Fill in the fields with the following values:

* Endpoint URL - `https://{ALGOLIA_APPLICATION_ID}.algolia.net/1/indexes` - provide your Algolia application ID
* Description - `Algolia Delete`
* Message filtering - select only the `index-item.deleted` event

<figure><img src="https://3057647601-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbTY7EwZtYYQYC6GOcdTj%2Fuploads%2Fgit-blob-e37a3245f7bc8747e52c6b337b3c59d3797d9dd4%2Falgolia1.png?alt=media" alt="" width="563"><figcaption></figcaption></figure>

2. Choose **Create** and check if your configuration was properly saved.
3. Go to the **Advanced** tab, provide the required custom headers and enable the transformation feature:
   * Key: `X-Algolia-API-Key`\
     Value: `YOUR_ALGOLIA_ADMIN_API_KEY`
   * Key: `X-Algolia-Application-Id`\
     Value: `YOUR_ALGOLIA_APPLICATION_ID`

Find the right values for your keys in your application settings (API Keys) in your Algolia account.

4. In the **Transformations** section, set the **transformation** feature to **enabled**.

<figure><img src="https://3057647601-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbTY7EwZtYYQYC6GOcdTj%2Fuploads%2Fgit-blob-650d3a3f8d29416ee71458a33b7e158ec3764027%2Falgolia2.png?alt=media" alt="" width="563"><figcaption></figcaption></figure>

According to Algolia API Reference, the request that should be sent is as follows:

```json
curl -X DELETE \
     -H "X-Algolia-API-Key: ${API_KEY}" \
     -H "X-Algolia-Application-Id: ${APPLICATION_ID}" \
    "https://${APPLICATION_ID}.algolia.net/1/indexes/contacts/myID"
```

To learn more about Algolia API, see [Algolia API Reference](https://www.algolia.com/doc/rest-api/search/#add-or-replace-object-by-id).

In the **Edit transformation** section, change the code to create the right mapping:\
\
a. Change the http method:

```json
/**
 * @param webhook the webhook object
 * @param webhook.method destination method. Allowed values: "POST", "PUT"
 * @param webhook.url current destination address
 * @param.webhook.eventType current webhook Event Type
 * @param webhook.payload JSON payload
 * @param.webhook.cancel whether to cancel dispatch of the given webhook
 */
function handler(webhook) {

  webhook.method = "DELETE";
  return webhook
}
```

\
b. Change the target URL:

```json
/**
 * @param webhook the webhook object
 * @param webhook.method destination method. Allowed values: "POST", "PUT"
 * @param webhook.url current destination address
 * @param.webhook.eventType current webhook Event Type
 * @param webhook.payload JSON payload
 * @param.webhook.cancel whether to cancel dispatch of the given webhook
 */
function handler(webhook) {

  var indexName = "emporix_" + webhook.payload.siteCode;
  webhook.url = webhook.url + "/" + indexName + "/" + webhook.payload.id;
  webhook.method = "DELETE";
  return webhook
}
```

c. If the output is correct, save your changes.

To test the configuration, delete a product in Management Dashboard and after a few minutes check if it was deleted in your index in the Algolia account. With this configuration, every time when a product gets deleted, the appropriate event is propagated to Svix, transformed and then sent to Algolia.

### BatteryIncluded Configuration

**Creating and updating products**

1. In **Endpoints**, choose **Add Endpoint**. Fill in the fields with the following values:

* Endpoint URL - `https://api.batteryincluded.io/api/v1/collections/{BATTERY_INCLUDED_TENANT}/documents/import`
* Description - `BatteryIncluded Create/Update`
* Message filtering - select only the `index-item.updated` event

{% hint style="success" %}
Replace the `{BATTERY_INCLUDED_TENANT}` with the value from the URL address in the BatteryIncluded Portal. For example, if the URL looks like this `https://portal.batteryincluded.io/#/discover/customer.emporix`, the `{BATTERY_INCLUDED_TENANT}` value is `customer.emporix`.
{% endhint %}

<figure><img src="https://3057647601-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbTY7EwZtYYQYC6GOcdTj%2Fuploads%2Fgit-blob-5b74f631eac6b462d441a210e5a59c67b2742789%2Fbatteryincluded.png?alt=media" alt="" width="563"><figcaption></figcaption></figure>

2. Choose **Create** and check if your configuration was properly saved.
3. Go to the **Advanced** tab, provide the required custom headers:
   * Key: `X-BI-API-KEY` Value: Your private integration key

Find the right values for your keys in your connection settings in your BatteryIncluded account.

To test the configuration, create a product in Management Dashboard and after a few minutes check if it appears in your index in the BatteryIncluded account. With this configuration, every time when a product is created or updated, the appropriate event is propagated to Svix, transformed and then sent to BatteryIncluded.

**Deleting products**

1. In **Endpoints**, choose **Add Endpoint**. Fill in the fields with the following values:

* Endpoint URL - `https://api.batteryincluded.io/api/v1/collections/{BATTERY_INCLUDED_TENANT}/documents/delete`
* Description - `BatteryIncluded Delete`
* Message filtering - select only the `index-item.deleted` event

{% hint style="success" %}
Replace the `{BATTERY_INCLUDED_TENANT}` with the value from the URL address in the BatteryIncluded Portal. For example, if the URL looks like this `https://portal.batteryincluded.io/#/discover/customer.emporix`, the `{BATTERY_INCLUDED_TENANT}` value is `customer.emporix`.
{% endhint %}

<figure><img src="https://3057647601-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbTY7EwZtYYQYC6GOcdTj%2Fuploads%2Fgit-blob-a9f4294fc2b904723a76ace908c6366a5fcfa941%2Fbatteryincluded-delete.png?alt=media" alt="" width="563"><figcaption></figcaption></figure>

2. Choose **Create** and check if your configuration was properly saved.
3. Go to the **Advanced** tab, provide the required custom headers and enable the transformation feature:
   * Key: `X-BI-API-KEY` Value: Your private integration key
4. In the **Transformations** section, set the **transformation** feature to **enabled**.
5. In the **Edit transformation** section, change the code to create the right mapping. Modify the HTTP method:

```json
  /**
* @param webhook the webhook object
* @param webhook.method destination method. Allowed values: "POST", "PUT"
* @param webhook.url current destination address
* @param.webhook.eventType current webhook Event Type
* @param webhook.payload JSON payload
* @param.webhook.cancel whether to cancel dispatch of the given webhook
*/
function handler(webhook) {
  // modify the webhook object...

  // convert data
  const playload = [webhook.payload.id]

  webhook.method = "DELETE";
  webhook.payload = playload

  return webhook
}
```

6. If the output is correct, save your changes.

To test the configuration, delete a product in Management Dashboard and after a few minutes check if it was deleted in your index in the BatteryIncluded account. With this configuration, every time when a product is deleted, the appropriate event is propagated to Svix, transformed and then sent to BatteryIncluded.
