> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kameleoon.com/llms.txt
> Use this file to discover all available pages before exploring further.

# SDK de Elixir

> Integre el SDK de Elixir de Kameleoon para ejecutar experimentos y activar feature flags en servicios y back-ends web de Elixir.

Con el SDK de Elixir de Kameleoon, puede ejecutar experimentos y activar feature flags en sus servicios y back-ends web de Elixir.

**Primeros pasos**: Para obtener ayuda para comenzar, consulte la [guía del desarrollador](#guía-del-desarrollador).

**Versión**: Última versión del SDK de Elixir: 0.8.6 [Changelog](https://docs.kameleoon.com/developer-docs/sdks/web-sdks/elixir-sdk).

**Métodos del SDK**: Para la documentación de referencia completa del SDK de Elixir, consulte la sección [referencia](#referencia).

## Guía del desarrollador

Esta guía está diseñada para ayudarle a integrar rápidamente el SDK de Elixir y comenzar a evaluar feature flags en su aplicación Elixir.

### Primeros pasos

#### Instalar el cliente de Elixir

Añada el SDK como una dependencia en su archivo `mix.exs`:

```elixir title="mix.exs" theme={null}
def deps do
  [
    {:kameleoon_client, "~> 0.8.6"}
  ]
end
```

#### Configuración adicional

Cree un archivo de configuración `client-elixir.conf` para proporcionar las credenciales y personalizar el comportamiento del SDK.

Recomendamos guardar este archivo en la ruta predeterminada, `/etc/kameleoon/client-elixir.conf`. `Kameleoon.ClientFactory.create` utiliza esta ruta automáticamente cuando no se pasan opciones de configuración. Si almacena el archivo en otra ubicación, pase la ruta con la opción `config_path:` al crear el cliente.

El SDK de Elixir puede configurarse mediante un archivo de configuración utilizado por `Kameleoon.ClientFactory.create` o pasando un struct `%Kameleoon.ClientConfig\{\}` con la opción `config:`.

La siguiente tabla muestra las propiedades disponibles que puede establecer:

| Clave (Código / Archivo de configuración)                          | Descripción                                                                                                                                                                                                                                                   | Valor predeterminado |
| ------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- |
| `client_id` / `clientId` (*obligatorio*)                           | Necesario para autenticarse en el servicio de Kameleoon. Para encontrar su `client_id`, consulte la documentación de [credenciales de API](/user-manual/account-and-team-management/users-and-teams/api-credentials).                                         |                      |
| `client_secret` / `clientSecret` (*obligatorio*)                   | Necesario para autenticarse en el servicio de Kameleoon. Para encontrar su `client_secret`, consulte la documentación de [credenciales de API](/user-manual/account-and-team-management/users-and-teams/api-credentials).                                     |                      |
| `session_duration_minutes` / `sessionDurationMinutes` (*opcional*) | Intervalo de tiempo, en minutos, durante el cual el SDK mantiene a un visitante y sus datos asociados en memoria.                                                                                                                                             | `30` minutos         |
| `refresh_interval_minutes` / `refreshIntervalMinutes` (*opcional*) | Intervalo, en minutos, utilizado para actualizar la configuración de experimentos y feature flags activos.                                                                                                                                                    | `60` minutos         |
| `default_timeout_millis` / `defaultTimeoutMillis` (*opcional*)     | Tiempo de espera predeterminado, en milisegundos, para las solicitudes de red del SDK.                                                                                                                                                                        | `10000` milisegundos |
| `tracking_interval_millis` / `trackingIntervalMillis` (*opcional*) | Intervalo, en milisegundos, utilizado para agrupar las solicitudes de seguimiento. Los valores se limitan al rango `[1000, 5000]`.                                                                                                                            | `1000` milisegundos  |
| `environment` / `environment` (*opcional*)                         | Entorno desde el que debe utilizarse la configuración de feature flags. El valor puede ser `production`, `staging` o `development`.                                                                                                                           | `production`         |
| `top_level_domain` / `topLevelDomain` (*opcional*)                 | El dominio de nivel superior actual de su sitio web. Utilice el formato `example.com`, sin protocolo ni subdominios.                                                                                                                                          | `nil`                |
| `proxy_host` / `proxyHost` (*opcional*)                            | Host proxy para las llamadas salientes del SDK. Formatos admitidos: `https://my.prox`, `https://my.prox:4545`, `socks5://192.168.1.1:9000`.                                                                                                                   | `nil`                |
| `network_domain` / `networkDomain` (*opcional*)                    | Dominio personalizado utilizado por los SDKs para las solicitudes salientes, a menudo para hacer proxy. Debe ser un dominio válido (por ejemplo, example.com o sub.example.com). Los formatos no válidos se sustituyen por el valor por defecto de Kameleoon. | `nil`                |

#### Inicializar el cliente de Kameleoon

Una vez que haya instalado el SDK y configurado sus credenciales, cree un `%Kameleoon.Client\{\}` mediante `Kameleoon.ClientFactory`.

<Tabs>
  <Tab title="Archivo de configuración">
    ```elixir theme={null}
    alias Kameleoon.Client
    alias Kameleoon.ClientFactory

    site_code = "a8st4f59bj"

    {:ok, client} = ClientFactory.create(site_code, config_path: "/etc/kameleoon/client-elixir.conf")
    :ok = Client.initialize(client)
    ```
  </Tab>

  <Tab title="Código">
    ```elixir theme={null}
    alias Kameleoon.Client
    alias Kameleoon.ClientConfig
    alias Kameleoon.ClientFactory

    site_code = "a8st4f59bj"

    config = %ClientConfig{
      client_id: "<client-id>",
      client_secret: "<client-secret>",
      refresh_interval_minutes: 60,
      session_duration_minutes: 30,
      default_timeout_millis: 10_000,
      tracking_interval_millis: 1_000,
      environment: "development",
      top_level_domain: ".example.com",
      proxy_host: "http://192.168.0.25:8080",
      network_domain: "example.com"
    }

    {:ok, client} = ClientFactory.create(site_code, config: config)
    :ok = Client.initialize(client)
    ```
  </Tab>
</Tabs>

Un `%Kameleoon.Client\{\}` es el objeto principal utilizado para evaluar feature flags, añadir datos de visitantes y enviar solicitudes de seguimiento.

<Warning>
  * Se recomienda usar `%Kameleoon.Client\{\}` como un objeto singleton, ya que sirve como puente entre su aplicación y la plataforma Kameleoon. Expone todos los métodos y propiedades necesarios para ejecutar experimentos de forma eficiente.
  * El SDK de Elixir se inicializa a través del Core nativo. Debe llamar a [`initialize()`](#initialize) antes de confiar en la evaluación de funcionalidades en código de producción.
</Warning>

#### Activar un feature flag

##### Asignar un ID único a un usuario

Para asignar un ID único a un usuario, puede utilizar el método [`Client.get_visitor_code`](#get_visitor_code). Si no existe un **visitor code** (procedente de la cookie de las cabeceras de la solicitud), el método genera un ID único aleatorio o utiliza un `default_visitor_code` que usted haya generado. El ID se establece entonces en una cookie de las cabeceras de respuesta.

Si está utilizando Kameleoon en [modo híbrido](/developer-docs/feature-experimentation/get-started/hybrid-experimentation), llamar al método `Client.get_visitor_code` garantiza que el ID único (**visitor code**) se comparta entre el archivo de la aplicación `engine.js` (anteriormente llamado `kameleoon.js`) y el SDK.

##### Recuperar una configuración de flag

Para implementar un feature flag en su código, primero debe crear el feature flag en su cuenta de Kameleoon.

Para determinar el estado o la variación de un feature flag para un usuario específico, debe utilizar el método [`Client.get_variation`](#get_variation) o [`Client.is_feature_active?`](#is_feature_active) para recuperar la configuración basada en la `feature_key`.

El método `Client.get_variation` gestiona tanto feature flags simples con estados ON/OFF como flags más complejos con múltiples variaciones. El método recupera la variación adecuada para el usuario comprobando las reglas de la funcionalidad, asignando la variación y devolviéndola en función de `feature_key` y `visitor_code`.

El método `Client.is_feature_active?` puede usarse si quiere recuperar la configuración de un feature flag simple que solo tiene un estado ON u OFF, en contraposición a feature flags más complejos con múltiples variaciones u opciones de segmentación.

Si su feature flag tiene variables asociadas (como comportamientos específicos vinculados a cada variación), `Client.get_variation` también le permite acceder al objeto [`Variation`](#variation), que proporciona detalles sobre la variación asignada y su experimento asociado. Este método comprueba si el usuario está segmentado, encuentra la variación asignada al visitante y la guarda en el almacenamiento. Cuando `track=true`, el SDK enviará el evento de exposición al experimento especificado en la siguiente solicitud de seguimiento, que se activa automáticamente en función del [`tracking_interval_millis`](#configuración-adicional) del SDK. De forma predeterminada, este intervalo se establece en 1000 milisegundos (1 segundo).

El método `Client.get_variation` le permite controlar si se realiza el seguimiento. Si `track=false`, el SDK no enviará eventos de exposición. Esto es útil si prefiere no realizar el seguimiento de los datos a través del SDK y, en su lugar, confiar en el seguimiento del lado del cliente gestionado por el motor de Kameleoon, por ejemplo. Además, establecer `track=false` resulta útil al utilizar el método `Client.get_variations`, donde quizá solo necesite las variaciones de todos los flags sin desencadenar ningún evento de seguimiento. Si quiere saber más sobre cómo funciona el seguimiento, consulte [este artículo](/developer-docs/feature-experimentation/technical-reference/faq-global#when-does-the-sdk-send-a-tracking-request-for-analytics).

##### Añadir puntos de datos para segmentar a un usuario o filtrar / desglosar visitas en los informes

Para segmentar a un usuario, asegúrese de haber añadido puntos de datos relevantes a su perfil antes de recuperar la variación de la funcionalidad o comprobar si el flag está activo. Utilice el método [`Client.add_data`](#add_data) para añadir estos puntos de datos al perfil del usuario.

Para recuperar puntos de datos recogidos en otros dispositivos o para acceder a datos pasados del usuario (recogidos en el lado del cliente al utilizar Kameleoon en modo híbrido), use el método [`Client.get_remote_visitor_data`](#get_remote_visitor_data). Este método obtiene datos de los servidores de forma asíncrona. Es importante llamar a `Client.get_remote_visitor_data` *antes* de recuperar la variación o comprobar si el feature flag está activo, ya que estos datos podrían ser necesarios para asignar al usuario a una variación determinada.

Para obtener más información sobre las condiciones de segmentación disponibles, consulte el [artículo detallado sobre el tema](/developer-docs/feature-experimentation/targeting-and-segmentation/native-segmentation).

Además, los puntos de datos que añade al perfil del visitante estarán disponibles al analizar sus experimentos, lo que le permite filtrar y desglosar sus resultados por factores como dispositivo y navegador. El modo híbrido de Kameleoon recopila automáticamente diversos puntos de datos en el lado del cliente, lo que facilita desglosar sus resultados a partir de estos datos previamente recopilados. Consulte la lista completa [aquí](/es/user-manual/experiment-analytics/analyze-results/results-page/results-page-settings#desglose-de-audiencia).

Si necesita realizar el seguimiento de puntos de datos adicionales más allá de los que se recopilan automáticamente, puede utilizar la [funcionalidad de datos personalizados](#customdata) de Kameleoon. Los datos personalizados le permiten capturar y analizar información específica relevante para sus experimentos. No olvide llamar al método [`Client.flush`](#flush) para enviar los datos recopilados a los servidores de Kameleoon para su análisis.

<Note>
  Para asegurar que sus resultados sean precisos, se recomienda filtrar los bots utilizando el tipo de dato [`UserAgent`](#useragent).
</Note>

##### Seguimiento de conversiones de objetivos

Cuando un usuario completa una acción deseada (como realizar una compra), se registra como una conversión. Para realizar el seguimiento de conversiones, utilice el método [`Client.track_conversion`](#track_conversion) y proporcione los parámetros obligatorios `visitor_code` y `goal_id`.

La solicitud de seguimiento de la conversión se enviará junto con la siguiente solicitud de seguimiento programada, que el SDK envía a intervalos regulares (definidos por [`tracking_interval_millis`](#configuración-adicional)). Si prefiere enviar la solicitud de inmediato, utilice el método [`Client.flush_instant`](#flush).

##### Envío de eventos a soluciones de analítica

Para realizar el seguimiento de conversiones y enviar eventos de exposición a su solución de analítica de clientes, primero debe implementar Kameleoon en [modo híbrido](/developer-docs/feature-experimentation/get-started/hybrid-experimentation/). A continuación, utilice el método [`Client.get_engine_tracking_code`](#get_engine_tracking_code).

El método `Client.get_engine_tracking_code` recupera el código de seguimiento único necesario para enviar eventos de exposición a su solución de analítica. El uso de este método le permite registrar eventos y enviarlos a la plataforma de analítica de su elección.

### Uso de una clave de bucketing personalizada

De forma predeterminada, Kameleoon utiliza un ID de visitante único y anónimo (`visitor_code`) para asignar usuarios a las variaciones de los feature flags. Este ID normalmente se genera y se almacena en el dispositivo del usuario (en una cookie del navegador para los SDKs del lado del cliente y del lado del servidor, y en el almacenamiento persistente para los SDKs móviles). Sin embargo, en ciertos escenarios puede que necesite asegurarse de que todos los usuarios de la misma organización vean la misma variante de un feature flag.

La opción **Clave de bucketing personalizada** le permite anular este comportamiento predeterminado proporcionando su propio identificador personalizado para el bucketing. Esta anulación garantiza que la lógica de asignación de Kameleoon utilice la clave que usted especifique en lugar del `visitor_code` predeterminado.

#### Casos de uso

El uso de una clave de bucketing personalizada es esencial para mantener la coherencia y la precisión de las asignaciones de sus feature flags, especialmente en estas situaciones:

* **Experimentos a nivel de cuenta o de organización:** Para productos B2B o escenarios en los que quiere asignar a todos los usuarios de la misma organización a la misma variación, puede utilizar un identificador como un `account_id`. Las claves de bucketing personalizadas son cruciales para realizar pruebas A/B de funcionalidades que afectan a todo un equipo o empresa.

Al implementar una clave de bucketing personalizada, garantiza mayor coherencia y precisión en sus experimentos, lo que conduce a resultados más fiables y una mejor experiencia de usuario.

#### Detalles técnicos

Cuando configura una clave de bucketing personalizada para un feature flag, proporciona a Kameleoon un identificador específico de los datos de su aplicación:

```elixir theme={null}
alias Kameleoon.Client
alias Kameleoon.Data.CustomData

:ok = Client.add_data(client, visitor_code, CustomData.new!(42, ["new_visitor_code"]))
```

* **Proporcionar la clave personalizada:** Usted proporciona su identificador personalizado al SDK de Kameleoon mediante el método [`Client.add_data`](#add_data). En este método, pasará su clave de bucketing personalizada elegida como un objeto [`CustomData`](#customdata). Aquí, `new_visitor_code` se refiere al identificador que desea utilizar para su bucketing (por ejemplo, el nuevo `user_id` o `account_id`).

<Warning>
  Para que la clave de bucketing personalizada funcione correctamente, también debe estar definida y configurada para el feature flag durante el proceso de creación o edición del flag. Sin esta configuración correspondiente, el bucketing del SDK no aplicará su clave personalizada. Para obtener instrucciones detalladas sobre cómo configurar esto en Kameleoon, consulte este [artículo](/user-manual/experimentation/feature-experimentation/create-and-manage-flags/create-a-feature-flag#Advanced_Flag_Settings).
</Warning>

* **Lógica de bucketing:** Una vez que se proporciona una clave de bucketing personalizada a través del método `Client.add_data`, todos los cálculos de hash para asignar usuarios a variaciones utilizarán este `new_visitor_code` (su clave personalizada) en lugar del `visitor_code` predeterminado. Utilizar el `new_visitor_code` significa que la decisión de bucketing está ligada a su identificador personalizado, lo que garantiza asignaciones coherentes en diversos contextos donde está presente ese identificador.
* **Seguimiento de datos y analítica:** Es crucial tener en cuenta que, aunque el `new_visitor_code` (su clave personalizada) se utiliza para las decisiones de bucketing, **todos los datos posteriores (eventos de seguimiento y conversiones, por ejemplo) se envían y se asocian con el `visitor_code` *original*.** Esta separación garantiza que sus analíticas reflejen con precisión los recorridos e interacciones individuales de los usuarios dentro del contexto más amplio de su experimento, incluso cuando el bucketing se realice a un nivel superior (como una cuenta) o entre varios dispositivos/sesiones. Sus datos originales del visitante permanecen intactos para informes integrales.

#### Requisitos técnicos

Para utilizar eficazmente una clave de bucketing personalizada:

* La clave debe ser un `String.t()`.
* Debe ser única para la entidad que pretende usar para el bucketing (por ejemplo, si utiliza un `user_id`, el ID de cada usuario debe ser único).
* La clave debe estar disponible para el SDK en el momento exacto en que se evalúa la decisión del feature flag para ese usuario o solicitud.

### Condiciones de segmentación

Los SDKs de Kameleoon admiten una variedad de condiciones de segmentación predefinidas que puede utilizar para segmentar a los usuarios en sus campañas. Para obtener la lista de condiciones que admite este SDK, consulte [usar el historial de visitas para segmentar usuarios](/developer-docs/feature-experimentation/targeting-and-segmentation/native-segmentation).

También puede utilizar sus propios [datos externos para segmentar usuarios](/developer-docs/apis/data-api-rest/tutorials/storing-and-retrieving-external-data-to-target-users).

### Experimentación entre dispositivos

Para dar soporte a los visitantes que acceden a una aplicación desde varios dispositivos, Kameleoon permite la sincronización de los datos del visitante previamente recopilados en cada uno de los dispositivos del visitante, y la reconciliación de su historial de visitas entre dispositivos mediante la experimentación entre dispositivos. Hay casos de estudio e información detallada sobre cómo Kameleoon gestiona los datos entre dispositivos disponibles en el [artículo sobre la experimentación entre dispositivos](/developer-docs/cross-device-experimentation).

#### Sincronización de datos personalizados entre dispositivos

Aunque la sincronización de mapeo personalizado se utiliza para alinear los datos del visitante entre dispositivos, no siempre es necesaria. A continuación se presentan dos escenarios en los que no se requiere la sincronización de mapeo personalizado:

**Mismo ID de usuario en todos los dispositivos**
Si se utiliza el mismo ID de usuario de forma coherente en todos los dispositivos, la sincronización se gestiona automáticamente sin una sincronización de mapeo personalizado. Basta con llamar al método `Client.get_remote_visitor_data` cuando quiera sincronizar los datos recopilados entre varios dispositivos.

**Instancias multi-servidor con IDs coherentes**
En configuraciones complejas que involucran varios servidores (por ejemplo, instancias de servidor distribuidas), donde el mismo ID de usuario está disponible entre servidores, la sincronización entre servidores (con `Client.get_remote_visitor_data`) es suficiente sin necesidad de sincronización adicional de mapeo personalizado.

Los clientes que necesiten datos adicionales pueden consultar la descripción del método [`Client.get_remote_visitor_data`](#get_remote_visitor_data) para más orientación. En el siguiente código, se asume que el mismo identificador único (en este caso, el `visitor_code`, que también puede denominarse `userId`) se utiliza de forma coherente entre los dos dispositivos para una recuperación precisa de los datos.

<Note>
  Si quiere sincronizar los datos recopilados en tiempo real, debe elegir el ámbito **Visitor** para sus datos personalizados.
</Note>

```elixir title="Device A" theme={null}
# En este ejemplo, un Custom data con índice `90` se configuró con el ámbito "Visitor" en Kameleoon.
alias Kameleoon.Client
alias Kameleoon.Data.CustomData

visitor_scope_custom_data_index = 90

:ok = Client.add_data(client, visitor_code, CustomData.new!(visitor_scope_custom_data_index, ["your data"]))

:ok = Client.flush_instant(client, visitor_code)
```

```elixir title="Device B" theme={null}
# Antes de trabajar con los datos, llame al método `get_remote_visitor_data`.
:ok = Client.get_remote_visitor_data(client, visitor_code)

# Después de llamar al método, el SDK en el Dispositivo B tendrá acceso a los CustomData de ámbito Visitor definidos en el Dispositivo A.
# Por lo tanto, "your data" estará disponible para la segmentación y el seguimiento del visitante.
```

#### Usar datos personalizados para la fusión de sesiones

La [experimentación entre dispositivos](/developer-docs/cross-device-experimentation) permite combinar el historial de un visitante en cada uno de sus dispositivos (reconciliación del historial). La reconciliación del historial permite fusionar diferentes sesiones de un visitante en una sola. Para reconciliar el historial de visitas, utilice [`CustomData`](#customdata) para proporcionar un identificador único para el visitante. Para más información, consulte la [documentación dedicada](/developer-docs/cross-device-experimentation/#activating-cross-device-history-reconciliation).

Una vez habilitada la reconciliación entre dispositivos, llamar a [`Client.get_remote_visitor_data`](#get_remote_visitor_data) con el parámetro `userId` recupera todos los datos conocidos para un usuario determinado.

A las sesiones con el mismo identificador siempre se les mostrará la misma variación en un experimento. En la vista de Visitante de las páginas de resultados de su experimento, estas sesiones aparecerán como un único visitante.

La configuración del SDK garantiza que las sesiones asociadas siempre vean la misma variación del experimento. Sin embargo, existen algunas limitaciones con respecto a la asignación de variaciones entre dispositivos. Estas limitaciones se describen [aquí](/developer-docs/cross-device-experimentation#critical-points-and-practical-insights).

Siga la guía [activación de la reconciliación de historial entre dispositivos](#experimentación-entre-dispositivos) para configurar sus datos personalizados en la plataforma Kameleoon.

Posteriormente, puede utilizar el SDK normalmente. Los siguientes métodos pueden ser útiles en el contexto de la fusión de sesiones:

* `Client.get_remote_visitor_data` con `UniqueIdentifier(true)` añadido: para recuperar datos de todos los visitantes vinculados.
* [`Client.track_conversion`](#track_conversion) o [`Client.flush`](#flush) con datos `UniqueIdentifier(true)` añadidos: para realizar el seguimiento de algunos datos para un visitante específico que está asociado con otro visitante.

<Tip>
  Como los datos personalizados que utiliza como identificador deben tener el ámbito **Visitor**, debe utilizar la [sincronización de datos personalizados entre dispositivos](/developer-docs/cross-device-experimentation) para recuperar el identificador con el método [`Client.get_remote_visitor_data`](#get_remote_visitor_data) en cada dispositivo.
</Tip>

A continuación se muestra un ejemplo de cómo usar datos personalizados para la fusión de sesiones.

```elixir theme={null}
# En este ejemplo, 91 representa el índice del Custom Data configurado como identificador único en Kameleoon.
alias Kameleoon.Client
alias Kameleoon.Data.CustomData
alias Kameleoon.Data.UniqueIdentifier

mapping_index = 91
feature_key = "ff123"

anonymous_visitor_code = "anonymous-visitor"
user_id = "authenticated-user"

# 1. Antes de que el visitante esté autenticado

# Recuperar la variación para un visitante no autenticado.
# Se asume que anonymousVisitorCode es el ID generado aleatoriamente para ese visitante.
{:ok, anonymous_variation} = Client.get_variation(client, anonymous_visitor_code, feature_key)

# 2. Después de que el visitante esté autenticado

# Se asume que `userId` es el código de visitante del visitante autenticado.
:ok = Client.add_data(client, anonymous_visitor_code, CustomData.new!(mapping_index, [user_id]))
:ok = Client.flush_instant(client, anonymous_visitor_code)

# Indicar que `userId` es un identificador único.
:ok = Client.add_data(client, user_id, UniqueIdentifier.new!(true))

# 3. Después de que el visitante haya sido autorizado

# Recuperar la variación para el `userId`, que coincidirá con la variación del código de visitante anónimo.
{:ok, user_variation} = Client.get_variation(client, user_id, feature_key)
is_same_variation = user_variation.key == anonymous_variation.key # true

# `userId` y `anonymousVisitorCode` están ahora vinculados y pueden ser rastreados como un único visitante.
:ok = Client.track_conversion(client, user_id, 123)

# Además, los visitantes vinculados comparten todos los datos remotos previamente rastreados y obtenidos.
:ok = Client.get_remote_visitor_data(client, user_id)
```

En este ejemplo, la aplicación tiene una página de inicio de sesión. Dado que el ID de usuario es desconocido en el momento del inicio de sesión, se utiliza un identificador de visitante anónimo generado por el método [`Client.get_visitor_code`](#get_visitor_code). Después de que el usuario inicia sesión, el visitante anónimo se asocia con el ID de usuario y se utiliza como identificador único para el visitante.

### Registro (Logging)

El SDK genera registros que reflejan diversos procesos e incidencias internos.

#### Niveles de registro

El SDK admite la configuración del registro limitándolo por nivel.

```elixir theme={null}
alias Kameleoon.Logger

# El nivel de registro `:none` no permite ningún registro.
:ok = Logger.set_log_level(:none)

# El nivel de registro `:error` solo permite registrar incidencias que puedan afectar al comportamiento principal del SDK.
:ok = Logger.set_log_level(:error)

# El nivel de registro `:warning` permite registrar incidencias que pueden requerir atención.
# Amplía el nivel de registro `:error`.
# El nivel `:warning` es el nivel de registro predeterminado.
:ok = Logger.set_log_level(:warning)

# El nivel de registro `:info` permite registrar información general sobre los procesos internos del SDK.
# Amplía el nivel de registro `:warning`.
:ok = Logger.set_log_level(:info)

# El nivel `:debug` registra detalles adicionales sobre los procesos internos del SDK.
:ok = Logger.set_log_level(:debug)
```

#### Gestión personalizada de los registros

El SDK escribe sus registros en la salida de la consola de forma predeterminada. Este comportamiento puede sobrescribirse.

<Note>
  La limitación del registro por nivel se realiza de forma independiente a la lógica de gestión de registros.
</Note>

```elixir theme={null}
defmodule MyKameleoonLogger do
  @behaviour Kameleoon.Logger
  require Logger

  @impl true
  def log(level, message) do
    Logger.log(level, message)
  end
end

# El filtrado por nivel de registro se aplica de forma independiente a la lógica de gestión de registros.
# El logger personalizado solo aceptará registros que cumplan o superen el nivel especificado.
:ok = Kameleoon.Logger.set_log_level(:debug)
:ok = Kameleoon.Logger.set_logger(MyKameleoonLogger)
```

## Referencia

Esta es la documentación de referencia completa para el SDK de Elixir.

### Inicialización

#### create()

Para usar el SDK, cree un `%Kameleoon.Client\{\}` con `Kameleoon.ClientFactory.create`. De forma predeterminada, `create` lee `/etc/kameleoon/client-elixir.conf`. También puede proporcionar bien un struct `%Kameleoon.ClientConfig\{\}` a través de `config:`, o bien una ruta personalizada al archivo de configuración a través de `config_path:`.

<Tabs>
  <Tab title="config:">
    ```elixir theme={null}
    alias Kameleoon.ClientConfig
    alias Kameleoon.ClientFactory

    config = %ClientConfig{
      client_id: "<client-id>",
      client_secret: "<client-secret>",
      refresh_interval_minutes: 60,
      session_duration_minutes: 30,
      default_timeout_millis: 10_000,
      tracking_interval_millis: 1_000,
      environment: "development",
      top_level_domain: ".example.com",
      proxy_host: "http://192.168.0.25:8080",
      network_domain: "example.com"
    }

    {:ok, client} = ClientFactory.create(site_code, config: config)
    ```

    ##### Argumentos

    | Nombre                      | Tipo                         | Descripción                                                 |
    | --------------------------- | ---------------------------- | ----------------------------------------------------------- |
    | `site_code` (*obligatorio*) | `String.t()`                 | Clave única del proyecto de Kameleoon utilizada por el SDK. |
    | `config` (*obligatorio*)    | `Kameleoon.ClientConfig.t()` | Struct de configuración del SDK.                            |
  </Tab>

  <Tab title="config_path:">
    ```elixir theme={null}
    alias Kameleoon.ClientFactory

    {:ok, client} = ClientFactory.create("a8st4f59bj", config_path: "/etc/kameleoon/client-elixir.conf")
    ```

    ##### Argumentos

    | Nombre                        | Tipo         | Descripción                                                 |
    | ----------------------------- | ------------ | ----------------------------------------------------------- |
    | `site_code` (*obligatorio*)   | `String.t()` | Clave única del proyecto de Kameleoon utilizada por el SDK. |
    | `config_path` (*obligatorio*) | `String.t()` | Ruta al archivo de configuración.                           |
  </Tab>
</Tabs>

##### Valor devuelto

| Tipo                           | Descripción                      |                                                                                       |
| ------------------------------ | -------------------------------- | ------------------------------------------------------------------------------------- |
| \`\{:ok, Kameleoon.Client.t()} | \{:error, Kameleoon.Error.t()}\` | Una instancia del cliente si tiene éxito, de lo contrario un error de inicialización. |

##### Errores

| Tipo                       | Descripción                                  |
| -------------------------- | -------------------------------------------- |
| `ConfigCredentialsInvalid` | Faltan las credenciales del SDK.             |
| `SiteCodeIsEmpty`          | El código de sitio proporcionado está vacío. |

#### initialize()

Espera a que el cliente de Kameleoon se inicialice, utilizando el [`default_timeout_millis`](#configuración-adicional) configurado o un `timeout` proporcionado. Este método garantiza que el cliente esté totalmente inicializado antes de realizar cualquier otra operación.

```elixir theme={null}
alias Kameleoon.Client

# Inicializa el cliente utilizando el tiempo de espera predeterminado configurado
:ok = Client.initialize(client)

# Inicializa el cliente con un tiempo de espera personalizado de 5 segundos
:ok = Client.initialize(client, timeout: 5_000)
```

##### Argumentos

| Nombre                 | Tipo                | Descripción                                                      |
| ---------------------- | ------------------- | ---------------------------------------------------------------- |
| `timeout` (*opcional*) | `non_neg_integer()` | Tiempo máximo de espera para la inicialización, en milisegundos. |

##### Valor devuelto

| Tipo  | Descripción                      |                                                                             |
| ----- | -------------------------------- | --------------------------------------------------------------------------- |
| \`:ok | \{:error, Kameleoon.Error.t()}\` | Indica si la inicialización se completó con éxito o si se produjo un error. |

##### Errores

| Tipo             | Descripción                                            |
| ---------------- | ------------------------------------------------------ |
| `Initialization` | Indica que el SDK aún no está totalmente inicializado. |

#### is\_ready()

Comprueba si el cliente ha sido inicializado.

```elixir theme={null}
{:ok, ready?} = Kameleoon.Client.is_ready?(client)

if ready? do
  # El cliente está listo
end
```

##### Valor devuelto

| Tipo                | Descripción                      |                                                                                                                    |
| ------------------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
| \`\{:ok, boolean()} | \{:error, Kameleoon.Error.t()}\` | `\{:ok, true\}` si el cliente está listo para ser usado, `\{:ok, false\}` si no lo está, de lo contrario un error. |

#### forget()

Elimina el cliente del SDK almacenado en caché asociado al `site_code` especificado.

```elixir theme={null}
alias Kameleoon.ClientFactory

# Elimina el cliente almacenado en caché para el site code dado
:ok = ClientFactory.forget("a8st4f59bj")

# Elimina el cliente almacenado en caché para el site code y el entorno dados
:ok = ClientFactory.forget("a8st4f59bj", environment: "production")
```

##### Argumentos

| Nombre                      | Tipo         | Descripción                                     |
| --------------------------- | ------------ | ----------------------------------------------- |
| `site_code` (*obligatorio*) | `String.t()` | Identificador único del proyecto de Kameleoon.  |
| `environment` (*opcional*)  | `String.t()` | Clave del entorno asociada al cliente en caché. |

##### Valor devuelto

| Tipo  | Descripción                      |                                                                              |
| ----- | -------------------------------- | ---------------------------------------------------------------------------- |
| \`:ok | \{:error, Kameleoon.Error.t()}\` | Indica si el cliente en caché se eliminó con éxito o si se produjo un error. |

### Feature flags y variaciones

#### is\_feature\_active()

* 📨 *Envía datos de seguimiento a Kameleoon (dependiendo de la opción `track`)*

Determina si un feature flag está activo para un usuario determinado.

Si el visitante aún no ha sido evaluado para este feature flag, el SDK evalúa las reglas de segmentación y devuelve el resultado. Si el visitante ya tiene una evaluación almacenada para la funcionalidad, el SDK reutiliza el resultado existente para garantizar la coherencia.

<Note>
  Kameleoon usa el seguimiento para contar sesiones y visitantes cuando llama a determinados métodos, como `Client.is_feature_active?`, `Client.get_variation` o `Client.get_variations`.

  Utilice el valor predeterminado `true` para el parámetro `track` cuando exponga a los visitantes a una variación y necesite contarlos. Establezca el parámetro `track` en `false` solo si llama a estos métodos antes de exponer a los visitantes.

  Por ejemplo, si llama a `Client.get_variations` para recuperar todas las variaciones antes de exponer a los visitantes, establezca el parámetro `track` en `false`. Esta configuración evita que Kameleoon cuente prematuramente una sesión. Posteriormente, podrá activar el seguimiento cuando exponga explícitamente al visitante.

  Kameleoon envía datos de seguimiento cada segundo de forma predeterminada. Puede configurar este intervalo hasta cinco segundos mediante la opción de configuración del intervalo de seguimiento. Kameleoon agrupa los eventos de seguimiento en una única sesión siempre que el intervalo entre eventos sea inferior a 30 minutos. Si transcurren más de 30 minutos entre eventos de seguimiento, Kameleoon cuenta los eventos como sesiones separadas. Una visita aparece en sus informes 30 minutos después del último evento registrado en la sesión.
</Note>

<Warning>
  El método `Client.is_feature_active?` evalúa la variante servida, no el estado del flag maestro. Si excluye reglas, el método utiliza el estado predeterminado **Then, for everyone else serve**. Si selecciona **Off** para este estado predeterminado, el método siempre devuelve `false` incluso cuando el feature flag maestro está **On**.
</Warning>

```elixir theme={null}
alias Kameleoon.Client

feature_key = "new_checkout"

# Evalúa el feature flag y envía datos de seguimiento (comportamiento predeterminado)
{:ok, active?} = Client.is_feature_active?(client, visitor_code, feature_key)

# Evalúa el feature flag sin enviar datos de seguimiento
{:ok, active_without_tracking?} =
  Client.is_feature_active?(client, visitor_code, feature_key, track: false)
```

##### Argumentos

| Nombre                         | Tipo         | Descripción                                                             | Valor predeterminado |
| ------------------------------ | ------------ | ----------------------------------------------------------------------- | -------------------- |
| `visitor_code` (*obligatorio*) | `String.t()` | Identificador único del usuario.                                        |                      |
| `feature_key` (*obligatorio*)  | `String.t()` | Clave de la funcionalidad a evaluar para el usuario.                    |                      |
| `track` (*opcional*)           | `boolean()`  | Activa o desactiva el seguimiento de la evaluación de la funcionalidad. | `true`               |

##### Valor devuelto

| Tipo                | Descripción                      |                                                                                                 |
| ------------------- | -------------------------------- | ----------------------------------------------------------------------------------------------- |
| \`\{:ok, boolean()} | \{:error, Kameleoon.Error.t()}\` | Indica si el feature flag está activo para el `visitor_code` especificado, o devuelve un error. |

##### Errores

| Tipo                 | Descripción                                                                                                                                                                                                                                                                                                |
| -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Initialization`     | Indica que el SDK aún no está totalmente inicializado.                                                                                                                                                                                                                                                     |
| `FeatureNotFound`    | Excepción que indica que la clave de funcionalidad solicitada no se ha encontrado en la configuración interna del SDK. Esto normalmente significa que el feature flag no está activado en la aplicación de Kameleoon (pero el código que implementa la funcionalidad ya está desplegado en la aplicación). |
| `VisitorCodeInvalid` | Excepción que indica que el código de visitante proporcionado no es válido. Está vacío o tiene más de 255 caracteres.                                                                                                                                                                                      |

#### get\_variation()

* 📨 *Envía datos de seguimiento a Kameleoon (dependiendo del parámetro `track`)*

Recupera la [`Variation`](#variation) asignada a un visitante determinado para un feature flag específico.

Este método requiere `visitor_code` y `feature_key` como argumentos obligatorios. El argumento `track` es opcional y su valor predeterminado es `true`.

Devuelve la `Variation` asignada al visitante. Si el visitante no está asociado con ninguna regla de feature flag, el método devuelve la `Variation` predeterminada para el feature flag dado.

Asegúrese de implementar el manejo de errores adecuado en su código para gestionar las posibles excepciones.

<Note>
  La variación predeterminada se refiere a la variación asignada a un visitante cuando este no coincide con ninguna regla de entrega predefinida para un feature flag. En otras palabras, es la variación de respaldo aplicada a todos los usuarios que no están segmentados por reglas específicas. Se representa como la variación en la sección "Then, for everyone else..." en una interfaz de gestión.
</Note>

```elixir theme={null}
alias Kameleoon.Client

feature_key = "new_checkout"

# Recupera la variación asignada al visitante (con el seguimiento activado de forma predeterminada)
{:ok, variation} = Client.get_variation(client, visitor_code, feature_key)

# Recupera la variación sin enviar datos de seguimiento
{:ok, variation_without_tracking} =
  Client.get_variation(client, visitor_code, feature_key, track: false)
```

##### Argumentos

| Nombre                        | Tipo         | Descripción                                                                                          | Valor predeterminado |
| ----------------------------- | ------------ | ---------------------------------------------------------------------------------------------------- | -------------------- |
| visitor\_code (*obligatorio*) | `String.t()` | Identificador único del visitante.                                                                   |                      |
| feature\_key (*obligatorio*)  | `String.t()` | Clave de la funcionalidad que quiere exponer a un visitante.                                         |                      |
| track (*opcional*)            | `boolean()`  | Un parámetro opcional para activar o desactivar el seguimiento de la evaluación de la funcionalidad. | `true`               |

##### Valor devuelto

| Tipo                                                                        | Descripción                                                                                                                                 |
| --------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `\{:ok, Kameleoon.Types.Variation.t()\} \| \{:error, Kameleoon.Error.t()\}` | Una [`Variation`](#variation) asignada a un visitante determinado para un feature flag específico si tiene éxito, de lo contrario un error. |

##### Errores

| Tipo                         | Descripción                                                                                                                                                                                                                                                                                                |
| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Initialization`             | Indica que el SDK aún no está totalmente inicializado.                                                                                                                                                                                                                                                     |
| `VisitorCodeInvalid`         | Excepción que indica que el código de visitante proporcionado no es válido. Está vacío o tiene más de 255 caracteres.                                                                                                                                                                                      |
| `FeatureNotFound`            | Excepción que indica que la clave de funcionalidad solicitada no se ha encontrado en la configuración interna del SDK. Esto normalmente significa que el feature flag no está activado en la aplicación de Kameleoon (pero el código que implementa la funcionalidad ya está desplegado en la aplicación). |
| `FeatureEnvironmentDisabled` | Excepción que indica que el feature flag está desactivado para el entorno actual del visitante (por ejemplo, production, staging o development).                                                                                                                                                           |
| `FeatureEvaluationBlocked`   | Excepción que indica que la evaluación de la funcionalidad está bloqueada. La razón se describe en el mensaje de error. Esto normalmente ocurre debido a restricciones de RGPD cuando el visitante no ha proporcionado el consentimiento legal.                                                            |

#### get\_variations()

* 📨 *Envía datos de seguimiento a Kameleoon (dependiendo del parámetro `track`)*

Recupera un mapa de objetos [`Variation`](#variation) asignados a un visitante determinado en todos los feature flags.

Este método itera sobre todos los feature flags disponibles y devuelve la `Variation` asignada para cada flag asociado al visitante especificado. Toma `visitor_code` como argumento obligatorio, mientras que `only_active` y `track` son opcionales.

* Si `only_active` se establece en `true`, el método `Client.get_variations` devolverá las variaciones de feature flags siempre que el usuario no esté asignado a la variación `off`.
* El parámetro `track` controla si el método rastreará o no las asignaciones de variaciones. De forma predeterminada, está establecido en `true`. Si se establece en `false`, el seguimiento se desactivará.

El mapa devuelto consta de las claves de los feature flags como claves y sus correspondientes `Variation` como valores. Si no se asigna ninguna variación para un feature flag, el método devuelve la `Variation` predeterminada para ese flag.

Debe implementarse un manejo de errores adecuado para gestionar las posibles excepciones.

<Note>
  La variación predeterminada se refiere a la variación asignada a un visitante cuando este no coincide con ninguna regla de entrega predefinida para un feature flag. En otras palabras, es la variación de respaldo aplicada a todos los usuarios que no están segmentados por reglas específicas. Se representa como la variación en la sección "Then, for everyone else..." en una interfaz de gestión.
</Note>

```elixir theme={null}
alias Kameleoon.Client

# Recupera todas las variaciones asignadas al visitante (con las opciones predeterminadas)
{:ok, variations} = Client.get_variations(client, visitor_code)

# Recupera solo las variaciones activas para el visitante
{:ok, only_active_variations} = Client.get_variations(client, visitor_code, only_active: true)

# Recupera variaciones sin enviar datos de seguimiento
{:ok, variations_without_tracking} = Client.get_variations(client, visitor_code, track: false)
```

##### Argumentos

| Nombre                        | Tipo         | Descripción                                                                                                                  | Valor predeterminado |
| ----------------------------- | ------------ | ---------------------------------------------------------------------------------------------------------------------------- | -------------------- |
| visitor\_code (*obligatorio*) | `String.t()` | Identificador único del visitante.                                                                                           |                      |
| only\_active (*opcional*)     | `boolean()`  | Un parámetro opcional que indica si se devuelven las variaciones para feature flags activos (`true`) o para todos (`false`). | `false`              |
| track (*opcional*)            | `boolean()`  | Un parámetro opcional para activar o desactivar el seguimiento de la evaluación de la funcionalidad.                         | `true`               |

##### Valor devuelto

| Tipo                                                                                           | Descripción                                                                                                                                                                                    |
| ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `\{:ok, %\{String.t() => Kameleoon.Types.Variation.t()\}\} \| \{:error, Kameleoon.Error.t()\}` | Mapa que contiene los objetos [`Variation`](#variation) asignados de los feature flags utilizando las claves de las funcionalidades correspondientes si tiene éxito, de lo contrario un error. |

##### Errores

| Tipo                 | Descripción                                                                                                           |
| -------------------- | --------------------------------------------------------------------------------------------------------------------- |
| `Initialization`     | Indica que el SDK aún no está totalmente inicializado.                                                                |
| `VisitorCodeInvalid` | Excepción que indica que el código de visitante proporcionado no es válido. Está vacío o tiene más de 255 caracteres. |

#### set\_forced\_variation()

El método le permite asignar mediante programación una [`Variation`](#variation) específica a un usuario, omitiendo el proceso de evaluación estándar. Esto es especialmente valioso para experimentos controlados donde la lógica de evaluación habitual no es necesaria o debe omitirse. También puede ser útil en escenarios como depuración o pruebas personalizadas.

Cuando se establece una variación **forzada**, anula la lógica de evaluación en tiempo real de Kameleoon. Procesos como la segmentación, las condiciones de segmentación y los cálculos algorítmicos se omiten. Para preservar la segmentación y las condiciones de segmentación durante un experimento, establezca `force_targeting=false` en su lugar.

<Info>
  Las variaciones **simuladas** siempre tienen prioridad en el orden de ejecución. Si se activa un cálculo de variación **simulada**, este se procesará y completará primero en su totalidad.
</Info>

Una variación forzada se trata igual que una variación evaluada. Se rastrea en la analítica y se almacena en el contexto del usuario como cualquier variación evaluada estándar, lo que garantiza la coherencia en los informes.

El método puede lanzar excepciones en determinadas condiciones (por ejemplo, parámetros no válidos, contexto del usuario o problemas internos). Un manejo adecuado de excepciones es esencial para garantizar que su aplicación se mantenga estable y resistente.

<Warning>
  Es importante distinguir las variaciones **forzadas** de las variaciones **[simuladas](#get_visitor_code)**:

  * **Variaciones forzadas**: Son específicas para un experimento individual.
  * **Variaciones simuladas**: Afectan al resultado global del **feature flag**.
</Warning>

```elixir theme={null}
alias Kameleoon.Client

experiment_id = 202_387

# Fuerza al visitante a la "variation_2" para el experimento dado
:ok = Client.set_forced_variation(client, visitor_code, experiment_id, "variation_2")

# Elimina cualquier variación forzada previamente para el visitante en este experimento
:ok = Client.set_forced_variation(client, visitor_code, experiment_id, nil)

# Fuerza al visitante a la "variation_2" con opciones personalizadas.
# En este caso, se respetan las reglas de segmentación (force_targeting = false).
:ok =
  Client.set_forced_variation(
    client,
    visitor_code,
    experiment_id,
    "variation_2",
    force_targeting: false
  )
```

##### Argumentos

| Nombre                         | Tipo                | Descripción                                                                                                                                                                | Valor predeterminado |
| ------------------------------ | ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- |
| visitor\_code (*obligatorio*)  | `String.t()`        | Identificador único del visitante.                                                                                                                                         |                      |
| experiment\_id (*obligatorio*) | `non_neg_integer()` | **Experiment Id** que se segmentará y seleccionará durante el proceso de evaluación.                                                                                       |                      |
| variation\_key (*obligatorio*) | `String.t() \| nil` | **Variation Key** correspondiente a una `Variation` que debe forzarse como valor devuelto para el experimento. Si el valor es `nil`, la variación forzada se restablecerá. |                      |
| force\_targeting (*opcional*)  | `boolean()`         | Indica si la segmentación del experimento debe forzarse y omitirse (`true`) o aplicarse como en el proceso de evaluación estándar (`false`).                               | `true`               |

##### Valor devuelto

| Tipo  | Descripción                      |                                                                                  |
| ----- | -------------------------------- | -------------------------------------------------------------------------------- |
| \`:ok | \{:error, Kameleoon.Error.t()}\` | Indica si la variación forzada se estableció con éxito o si se produjo un error. |

##### Errores

| Tipo                        | Descripción                                                                                                                                                                                                                                                       |
| --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Initialization`            | Indica que el SDK aún no está totalmente inicializado.                                                                                                                                                                                                            |
| `VisitorCodeInvalid`        | Excepción que indica que el código de visitante proporcionado no es válido. Está vacío o tiene más de 255 caracteres.                                                                                                                                             |
| `FeatureExperimentNotFound` | Excepción que indica que el id del experimento solicitado no se ha encontrado en la configuración interna del SDK. Esto normalmente es normal y significa que el experimento correspondiente a la regla aún no ha sido activado en el lado de Kameleoon.          |
| `FeatureVariationNotFound`  | Excepción que indica que la clave (id) de variación solicitada no se ha encontrado en la configuración interna del SDK. Esto normalmente es normal y significa que el experimento correspondiente a la variación aún no ha sido activado en el lado de Kameleoon. |

#### evaluate\_audiences()

* 📨 *Envía datos de seguimiento a Kameleoon*

Este método evalúa a los visitantes frente a todos los segmentos disponibles del Audiences Explorer y rastrea aquellos que coinciden.

`Client.evaluate_audiences` debe llamarse **después de que todos los datos relevantes del visitante hayan sido establecidos o actualizados**, y **justo antes** de obtener la variación de una funcionalidad o comprobar un feature flag. Este enfoque garantiza que el visitante se evalúe con los datos más actuales disponibles, permitiendo una asignación precisa de audiencias en función de todos los criterios.

Después de llamar a este método, puede realizar un análisis detallado del rendimiento del segmento en el Audiences Explorer.

```elixir theme={null}
:ok = Kameleoon.Client.evaluate_audiences(client, visitor_code)
```

##### Argumentos

| Nombre                        | Tipo         | Descripción                        |
| ----------------------------- | ------------ | ---------------------------------- |
| visitor\_code (*obligatorio*) | `String.t()` | Identificador único del visitante. |

##### Valor devuelto

| Tipo  | Descripción                      |                                                                            |
| ----- | -------------------------------- | -------------------------------------------------------------------------- |
| \`:ok | \{:error, Kameleoon.Error.t()}\` | Indica si la evaluación de audiencias tuvo éxito o si se produjo un error. |

##### Errores

| Tipo                 | Descripción                                                                                                           |
| -------------------- | --------------------------------------------------------------------------------------------------------------------- |
| `VisitorCodeInvalid` | Excepción que indica que el código de visitante proporcionado no es válido. Está vacío o tiene más de 255 caracteres. |

#### get\_datafile()

<Tip>
  Para evaluar todos los feature flags, utilice [`Client.get_variations`](#get_variations). Este método es más eficiente que llamar a `DataFile` e iterar sobre los flags con [`Client.get_variation`](#get_variation).
</Tip>

Devuelve la configuración actual del SDK como un objeto [`DataFile`](#datafile).

```elixir theme={null}
{:ok, datafile} = Kameleoon.Client.get_datafile(client)
```

##### Valor devuelto

| Tipo                                                                       | Descripción                                                                                                |
| -------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| `\{:ok, Kameleoon.Types.DataFile.t()\} \| \{:error, Kameleoon.Error.t()\}` | El [`DataFile`](#datafile) que contiene la configuración del SDK si tiene éxito, de lo contrario un error. |

##### Errores

| Tipo             | Descripción                                            |
| ---------------- | ------------------------------------------------------ |
| `Initialization` | Indica que el SDK aún no está totalmente inicializado. |

### Datos del visitante

#### get\_visitor\_code()

Utilice `get_visitor_code()` para obtener el `visitor_code` actual de Kameleoon del visitante. El método funciona con cualquier almacén de cookies que implemente el behaviour `Kameleoon.CookieAccessor`.

La lógica de implementación es la siguiente:

1. El SDK comprueba si ya hay una cookie `kameleoonVisitorCode` disponible a través del accessor proporcionado.
2. Si la cookie está ausente, el SDK utiliza `default_visitor_code` cuando se proporciona uno.
3. De lo contrario, el SDK genera un nuevo código de visitante y lo almacena a través del accessor.

Para más información, consulte [Experimentación híbrida](/developer-docs/feature-experimentation/get-started/hybrid-experimentation/).

<Warning>
  Si proporciona su propio `visitor_code`, su unicidad debe garantizarse por su parte. Tenga en cuenta también que la longitud del `visitor_code` está limitada a `255` caracteres.
</Warning>

<Info>
  El método `Client.get_visitor_code` le permite establecer variaciones **simuladas** para un visitante. Cuando las cookies (de una **solicitud** o **documento**) contienen la clave `kameleoonSimulationFFData`, se omite el proceso de evaluación estándar. En su lugar, el método devuelve directamente una [`Variation`](#variation) basada en los datos proporcionados.

  Puede aplicar simulaciones de dos maneras:

  * **Automáticamente (recomendado):** Si utiliza Kameleoon Web Experimentation o el SDK en [modo híbrido](/developer-docs/feature-experimentation/get-started/hybrid-experimentation#linking-feature-experiments-with-front-end-tracking-code), la cookie se crea automáticamente al simular la visualización de una variante mediante el [Simulation Panel](/user-manual/experimentation/feature-experimentation/using-the-rollout-planner/validation-and-rollback/using-simulation-mode).
  * **Manualmente:** Establezca la cookie `kameleoonSimulationFFData` manualmente.

  Es importante distinguir las variaciones **simuladas** de las variaciones **[forzadas](#set_forced_variation)**:

  * **Variaciones simuladas**: Afectan al resultado global del **feature flag**.
  * **Variaciones forzadas**: Son específicas para un experimento individual.

  ⚙️ **Configuración manual**

  Asegúrese de que la cookie `kameleoonSimulationFFData` siga este formato:

  * `kameleoonSimulationFFData={"featureKey":{"expId":10,"varId":20}}`: Simula la variación con `varId` del experimento `expId` para la `featureKey` dada.
  * `kameleoonSimulationFFData={"featureKey":{"expId":0}}`: Simula la variación predeterminada (definida en la sección **Then, for everyone else in Production, serve**) para la `featureKey` dada.

  ⚠️ Para garantizar el funcionamiento correcto, el valor de la cookie debe codificarse como un componente URI mediante un método como [`encodeURIComponent`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent).
</Info>

<Tabs>
  <Tab title="Map">
    ```elixir theme={null}
    defmodule MemoryCookies do
      @behaviour Kameleoon.CookieAccessor

      @impl true
      def get(cookies, key), do: Map.get(cookies, key)

      @impl true
      def set(cookies, key, value, _max_age, _top_level_domain) do
        Map.put(cookies, key, value)
      end
    end

    cookies = {MemoryCookies, %{}}

    # Genera o recupera un código de visitante utilizando un valor autogenerado.
    {:ok, visitor_code, cookies} = Kameleoon.Client.get_visitor_code(client, cookies)

    # Genera o recupera un código de visitante utilizando un ID de usuario predefinido.
    {:ok, visitor_code, cookies} = Kameleoon.Client.get_visitor_code(client, {MemoryCookies, cookies}, "user_id")
    ```
  </Tab>

  <Tab title="Plug.Conn">
    ```elixir theme={null}
    defmodule PlugConnCookies do
      @behaviour Kameleoon.CookieAccessor

      @impl true
      def get(conn, key), do: conn.req_cookies[key]

      @impl true
      def set(conn, key, value, max_age, top_level_domain) do
        opts = [path: "/", max_age: max_age]
        opts = if top_level_domain, do: Keyword.put(opts, :domain, top_level_domain), else: opts

        Plug.Conn.put_resp_cookie(conn, key, value, opts)
      end
    end

    def get_visitor_code(conn, client) do
      cookies = {PlugConnCookies, conn}

      with {:ok, visitor_code, conn} <- Kameleoon.Client.get_visitor_code(client, cookies) do
        {:ok, visitor_code, conn}
      end
    end
    ```
  </Tab>
</Tabs>

##### Argumentos

| Nombre                              | Tipo                   | Descripción                                                                                                           |                                                               |
| ----------------------------------- | ---------------------- | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- |
| `cookies` (*obligatorio*)           | `\{module(), term()\}` | Módulo accessor de cookies y estado específico del framework utilizado para leer y almacenar la cookie del visitante. |                                                               |
| `default_visitor_code` (*opcional*) | \`String.t()           | nil\`                                                                                                                 | Código de visitante a utilizar cuando no hay cookie presente. |

El módulo accessor debe implementar `get` y `set`. `get` lee un valor de cookie desde el estado del accessor, y `set` devuelve el estado actualizado tras recibir `key`, `value`, `max_age` y `top_level_domain`.

##### Valor devuelto

| Tipo                         | Descripción                      |                                                                                                                  |
| ---------------------------- | -------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
| \`\{:ok, String.t(), term()} | \{:error, Kameleoon.Error.t()}\` | Cadena que representa un código de visitante único utilizado en el SDK si tiene éxito, de lo contrario un error. |

#### add\_data()

El método `Client.add_data` añade [datos de segmentación](#tipos-de-datos) al almacenamiento para que otros métodos puedan usar los datos para decidir si segmentar o no al visitante actual.

El método `Client.add_data` no devuelve ningún valor y no interactúa por sí solo con los servidores back-end de Kameleoon. En su lugar, todos los datos declarados se guardan para su transmisión futura mediante el método [`Client.flush`](#flush). Este enfoque reduce el número de llamadas al servidor realizadas, ya que los datos normalmente se agrupan en una sola llamada al servidor que se desencadena con `Client.flush`.

El método [`Client.track_conversion`](#track_conversion) también envía los datos previamente asociados, al igual que `Client.flush`. Lo mismo ocurre con los métodos [`Client.get_variation`](#get_variation) y [`Client.get_variations`](#get_variations) si se activa una regla de experimentación.

<Tip>
  Cada visitante solo puede tener una instancia de datos asociados para la mayoría de los tipos de datos. Sin embargo, [`CustomData`](#customdata) es una excepción. Los visitantes pueden tener una instancia de `CustomData` asociada por índice.
</Tip>

```elixir theme={null}
alias Kameleoon.Client
alias Kameleoon.Data.Browser
alias Kameleoon.Data.PageView
alias Kameleoon.Data.UserAgent

:ok = Client.add_data(client, visitor_code, Browser.new!(:chrome, version: 123.0))

:ok =
  Client.add_data(client, visitor_code, [
    PageView.new!("https://example.com/pricing", title: "Pricing", referrers: [3]),
    UserAgent.new!("Mozilla/5.0")
  ])

:ok =
  Client.add_data(
    client,
    visitor_code,
    PageView.new!("https://example.com/checkout", title: "Checkout"),
    track: false
  )
```

##### Argumentos

| Nombre                        | Tipo                     | Descripción                                                                                                                                                                                                                              | Valor predeterminado |
| ----------------------------- | ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- |
| visitor\_code (*obligatorio*) | `String.t()`             | Identificador único del visitante.                                                                                                                                                                                                       |                      |
| data (*obligatorio*)          | `struct() \| [struct()]` | Colección de tipos de datos de Kameleoon.                                                                                                                                                                                                |                      |
| track (*opcional*)            | `boolean()`              | Especifica si los datos añadidos son elegibles para el seguimiento. Cuando se establece en `false`, los datos se almacenan localmente y se utilizan solo para la evaluación de la segmentación; no se envían a la Data API de Kameleoon. | `true`               |

##### Valor devuelto

| Tipo  | Descripción                      |                                                                      |
| ----- | -------------------------------- | -------------------------------------------------------------------- |
| \`:ok | \{:error, Kameleoon.Error.t()}\` | Indica si los datos se añadieron con éxito o si se produjo un error. |

##### Errores

| Tipo                 | Descripción                                                                                                           |
| -------------------- | --------------------------------------------------------------------------------------------------------------------- |
| `Initialization`     | Indica que el SDK aún no está totalmente inicializado.                                                                |
| `VisitorCodeInvalid` | Excepción que indica que el código de visitante proporcionado no es válido. Está vacío o tiene más de 255 caracteres. |

#### flush()

* *📨 Envía datos de seguimiento a Kameleoon*

El método `flush()` agrega todos los datos de Kameleoon asociados a un visitante y envía una solicitud de seguimiento al servidor. Esta solicitud incluye cualquier dato añadido previamente mediante el método [`add_data`](#add_data) que aún no se haya transmitido a través de otros mecanismos de seguimiento (consulte los métodos referenciados para más detalles). La operación `flush()` no es bloqueante, ya que la llamada al servidor se realiza de forma asíncrona.

Este método proporciona control sobre cuándo se transmiten los datos vinculados a un `visitor_code` específico. Por ejemplo, si `add_data()` se llama varias veces, enviar una solicitud después de cada invocación sería ineficiente. En su lugar, puede agrupar estas actualizaciones y llamar a `flush()` una vez para enviar todos los datos acumulados en una sola solicitud.

El método `flush()` utiliza el `visitor_code` proporcionado como identificador único del visitante.

<Tip>
  * `flush()` — Pone en cola una operación de flush según el intervalo de seguimiento configurado.
  * `flush_instant()` — Envía los datos de seguimiento inmediatamente sin esperar al intervalo.
</Tip>

```elixir theme={null}
# Pone en cola una operación de flush para el visitor_code dado.
# Los datos se enviarán según el intervalo de seguimiento configurado.
:ok = Kameleoon.Client.flush(client, visitor_code)

# Envía inmediatamente todos los datos de seguimiento pendientes para el visitor_code dado.
:ok = Kameleoon.Client.flush_instant(client, visitor_code)
```

##### Argumentos

| Nombre                         | Tipo         | Descripción                        |
| ------------------------------ | ------------ | ---------------------------------- |
| `visitor_code` (*obligatorio*) | `String.t()` | Identificador único del visitante. |

##### Valor devuelto

| Tipo  | Descripción                      |                                                                                   |
| ----- | -------------------------------- | --------------------------------------------------------------------------------- |
| \`:ok | \{:error, Kameleoon.Error.t()}\` | Indica si la operación se programó o ejecutó con éxito, o si se produjo un error. |

##### Errores

| Tipo                 | Descripción                                                                                                           |
| -------------------- | --------------------------------------------------------------------------------------------------------------------- |
| `Initialization`     | Indica que el SDK aún no está totalmente inicializado.                                                                |
| `VisitorCodeInvalid` | Excepción que indica que el código de visitante proporcionado no es válido. Está vacío o tiene más de 255 caracteres. |

#### get\_remote\_data()

El método `get_remote_data()` le permite recuperar datos remotos almacenados en los servidores de Kameleoon para la `key` especificada. En la mayoría de las configuraciones, estos datos se escriben a través de la Data API de Kameleoon y luego pueden ser obtenidos por su servicio Elixir cuando necesite contexto adicional de la aplicación.

Este método es útil cuando desea mantener información estructurada en la infraestructura remota de Kameleoon y reutilizarla desde su back-end sin mantener un mecanismo de recuperación independiente.

```elixir theme={null}
{:ok, data} = Kameleoon.Client.get_remote_data(client, "test-key")
```

##### Argumentos

| Nombre                | Tipo         | Descripción                                             |
| --------------------- | ------------ | ------------------------------------------------------- |
| `key` (*obligatorio*) | `String.t()` | Clave asociada a los datos remotos que desea recuperar. |

##### Valor devuelto

| Tipo                 | Descripción                      |                                                                                                                                                            |
| -------------------- | -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| \`\{:ok, String.t()} | \{:error, Kameleoon.Error.t()}\` | Payload asociado a la `key` especificada si tiene éxito, de lo contrario un error. En la mayoría de los casos, el payload es JSON serializado como cadena. |

##### Errores

| Tipo             | Descripción                                                                                                             |
| ---------------- | ----------------------------------------------------------------------------------------------------------------------- |
| `Initialization` | Indica que el SDK aún no está totalmente inicializado.                                                                  |
| `Network`        | Se devuelve cuando la solicitud de datos remotos falla o el servidor responde con un código de estado no satisfactorio. |

#### get\_remote\_visitor\_data()

`get_remote_visitor_data()` recupera los datos de visita de Kameleoon para el `visitor_code` proporcionado. El método añade los datos al almacenamiento local del visitante para que otros métodos del SDK puedan usarlos para tomar decisiones de segmentación.

Los datos obtenidos con este método son especialmente útiles cuando desea:

* utilizar datos recopilados desde otros dispositivos.
* acceder al historial de un visitante, como las páginas vistas previamente en visitas pasadas.
* utilizar datos que solo están disponibles en el lado del cliente, como variables del datalayer y conversiones de objetivos de front-end.

Lea [este artículo](/developer-docs/feature-experimentation/targeting-and-segmentation/native-segmentation) para comprender mejor los posibles casos de uso.

<Warning>
  De forma predeterminada, `get_remote_visitor_data()` recupera automáticamente los datos personalizados más recientes almacenados con `scope=Visitor` y los adjunta al visitante sin necesidad de llamar a [`add_data()`](#add_data). Esto es especialmente útil para [sincronizar datos personalizados entre varios dispositivos](/developer-docs/cross-device-experimentation/).
</Warning>

```elixir theme={null}
alias Kameleoon.Client
alias Kameleoon.Types.RemoteVisitorDataFilter

# Obtener datos remotos del visitante sin ningún filtro.
# Esto devolverá todos los datos disponibles para el visitante dado.
:ok = Client.get_remote_visitor_data(client, visitor_code)

# Crear un filtro para limitar los datos devueltos.
filter = %RemoteVisitorDataFilter{
  previous_visit_amount: 5,
  conversions: true,
  page_views: true
}

# Obtener datos remotos del visitante utilizando el filtro especificado.
# Esto devolverá solo los datos que coincidan con los criterios del filtro.
:ok = Client.get_remote_visitor_data(client, visitor_code, filter: filter)
```

##### Argumentos

| Nombre                         | Tipo                                          | Descripción                                      | Valor predeterminado                                                   |                                |
| ------------------------------ | --------------------------------------------- | ------------------------------------------------ | ---------------------------------------------------------------------- | ------------------------------ |
| `visitor_code` (*obligatorio*) | `String.t()`                                  | Código de visitante cuyos datos deben obtenerse. |                                                                        |                                |
| `filter` (*opcional*)          | \`Kameleoon.Types.RemoteVisitorDataFilter.t() | nil\`                                            | Filtro que describe qué datos remotos del visitante deben recuperarse. | `%RemoteVisitorDataFilter\{\}` |

##### Valor devuelto

| Tipo  | Descripción                      |                                                                                                   |
| ----- | -------------------------------- | ------------------------------------------------------------------------------------------------- |
| \`:ok | \{:error, Kameleoon.Error.t()}\` | Se devuelve con éxito cuando los datos se obtienen y añaden localmente, de lo contrario un error. |

##### Errores

| Tipo                 | Descripción                                                                                                                                                 |
| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Initialization`     | Indica que el SDK aún no está totalmente inicializado.                                                                                                      |
| `VisitorCodeInvalid` | Excepción que indica que el código de visitante proporcionado no es válido. Está vacío o tiene más de 255 caracteres.                                       |
| `Network`            | Se devuelve cuando la solicitud de datos remotos del visitante falla, no se puede analizar o el servidor responde con un código de estado no satisfactorio. |

##### Uso de parámetros en get\_remote\_visitor\_data()

El método `get_remote_visitor_data()` le permite controlar qué datos se recuperan para un visitante. El mismo enfoque de filtrado funciona para objetivos, experimentos, variaciones y otros datos del visitante.

Por ejemplo, si quiere segmentar a los usuarios que convirtieron en un objetivo durante sus últimas cinco visitas, puede establecer `previous_visit_amount` en `5` y `conversions` en `true`.

La flexibilidad mostrada en este ejemplo no se limita a los datos de objetivos. Puede utilizar el filtro para recuperar muchos comportamientos diferentes del visitante y ponerlos a disposición de la lógica de segmentación y de informes en su aplicación Elixir.

##### Campos de `RemoteVisitorDataFilter`

| Nombre                  | Tipo                | Descripción                                                               | Valor predeterminado |
| ----------------------- | ------------------- | ------------------------------------------------------------------------- | -------------------- |
| `previous_visit_amount` | `non_neg_integer()` | Número de visitas anteriores de las que recuperar datos.                  | `1`                  |
| `current_visit`         | `boolean()`         | Si es `true`, se recuperarán los datos de la visita actual.               | `true`               |
| `custom_data`           | `boolean()`         | Si es `true`, se recuperarán los datos personalizados.                    | `true`               |
| `visitor_code`          | `boolean()`         | Si es `true`, se reutilizará el código de visitante más reciente.         | `true`               |
| `page_views`            | `boolean()`         | Si es `true`, se recuperarán los datos de páginas vistas.                 | `false`              |
| `geolocation`           | `boolean()`         | Si es `true`, se recuperarán los datos de geolocalización.                | `false`              |
| `device`                | `boolean()`         | Si es `true`, se recuperarán los datos del dispositivo.                   | `false`              |
| `browser`               | `boolean()`         | Si es `true`, se recuperarán los datos del navegador.                     | `false`              |
| `operating_system`      | `boolean()`         | Si es `true`, se recuperarán los datos del sistema operativo.             | `false`              |
| `conversions`           | `boolean()`         | Si es `true`, se recuperarán los datos de conversiones.                   | `false`              |
| `experiments`           | `boolean()`         | Si es `true`, se recuperarán los datos de los experimentos.               | `false`              |
| `kcs`                   | `boolean()`         | Si es `true`, se recuperarán los datos del Kameleoon Conversion Score.    | `false`              |
| `personalizations`      | `boolean()`         | Si es `true`, se recuperarán los datos de personalización.                | `false`              |
| `cbs`                   | `boolean()`         | Si es true, se recuperarán los datos de puntuación del Contextual Bandit. | `false`              |

#### get\_visitor\_warehouse\_audience()

Este método recupera los datos de audiencia asociados a un visitante en su integración de warehouse utilizando el `visitor_code` especificado y, opcionalmente, una `warehouse_key`. La `warehouse_key` suele ser su ID de usuario interno. El parámetro `custom_data_index` corresponde a los datos personalizados de Kameleoon que Kameleoon utiliza para segmentar a sus visitantes.

Cuando la llamada tiene éxito, el SDK convierte la lista de audiencias devuelta en [`CustomData`](#customdata), la añade al visitante localmente y la pone a disposición para fines de segmentación. Para más contexto, consulte la [documentación de segmentación de warehouse](/user-manual/integrations/data-warehouses/bigquery/use-bigquery-as-a-source-audience-targeting).

```elixir theme={null}
alias Kameleoon.Client

# Obtener datos de audiencia para un visitante usando solo el visitor_code.
:ok = Client.get_visitor_warehouse_audience(client, visitor_code, 98)

# Obtener datos de audiencia para un visitante usando tanto visitor_code como warehouse_key.
# Útil cuando su warehouse utiliza un identificador diferente al visitor_code.
:ok = Client.get_visitor_warehouse_audience(client, visitor_code, 98, warehouse_key: "internal-user-id")
```

##### Argumentos

| Nombre                              | Tipo                | Descripción                                                                                                   | Valor predeterminado                                                |                |
| ----------------------------------- | ------------------- | ------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- | -------------- |
| `visitor_code` (*obligatorio*)      | `String.t()`        | Visitante cuyas audiencias de warehouse deben recuperarse.                                                    |                                                                     |                |
| `custom_data_index` (*obligatorio*) | `non_neg_integer()` | Índice de los datos personalizados configurados en Kameleoon para la segmentación de audiencias de warehouse. |                                                                     |                |
| `warehouse_key` (*opcional*)        | \`String.t()        | nil\`                                                                                                         | Clave externa del warehouse, generalmente su ID de usuario interno. | `visitor_code` |

##### Valor devuelto

| Tipo  | Descripción                      |                                                                                                          |
| ----- | -------------------------------- | -------------------------------------------------------------------------------------------------------- |
| \`:ok | \{:error, Kameleoon.Error.t()}\` | Éxito cuando los datos de audiencia del warehouse se recuperan y almacenan localmente como `CustomData`. |

##### Errores

| Tipo                 | Descripción                                                                                                                                             |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Initialization`     | Indica que el SDK aún no está totalmente inicializado.                                                                                                  |
| `VisitorCodeInvalid` | Excepción que indica que el código de visitante proporcionado no es válido. Está vacío o tiene más de 255 caracteres.                                   |
| `Network`            | Se devuelve cuando la solicitud de audiencia del warehouse falla, no se puede analizar o el servidor responde con un código de estado no satisfactorio. |

#### set\_legal\_consent()

Debe utilizar este método para especificar si el visitante ha dado su consentimiento legal para el uso de sus datos personales. Establecer `legal_consent` en `false` limita los tipos de datos que se pueden incluir en las solicitudes de seguimiento. Esto le ayuda a cumplir con los requisitos legales y reglamentarios al tiempo que gestiona de forma responsable los datos del visitante. Para más información, consulte la [política de gestión del consentimiento](/user-manual/project-management/consent-management-policy).

El SDK de Elixir actualiza las cookies del visitante a través del adaptador `Kameleoon.CookieAccessor` requerido y devuelve el estado actualizado del adaptador.

```elixir theme={null}
cookies = {PlugConnCookies, conn}

# Establecer el consentimiento y actualizar las cookies.
{:ok, conn} = Kameleoon.Client.set_legal_consent(client, visitor_code, true, cookies)
```

##### Argumentos

| Nombre                         | Tipo                   | Descripción                                                                                                                                                     | Valor predeterminado |
| ------------------------------ | ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- |
| `visitor_code` (*obligatorio*) | `String.t()`           | Identificador único del usuario.                                                                                                                                |                      |
| `consent` (*obligatorio*)      | `boolean()`            | `true` indica que el visitante ha dado el consentimiento legal, `false` indica que el visitante nunca ha proporcionado, o ha retirado, el consentimiento legal. |                      |
| `cookies` (*obligatorio*)      | `\{module(), term()\}` | Módulo accessor de cookies y estado específico del framework utilizado para actualizar las cookies.                                                             |                      |

##### Valor devuelto

| Tipo             | Descripción                      |                                                                                                                                                      |
| ---------------- | -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| \`\{:ok, term()} | \{:error, Kameleoon.Error.t()}\` | Devuelve el estado actualizado de las cookies cuando el estado de consentimiento del visitante se actualizó correctamente, de lo contrario un error. |

##### Errores

| Tipo                 | Descripción                                                                                                           |
| -------------------- | --------------------------------------------------------------------------------------------------------------------- |
| `Initialization`     | Indica que el SDK aún no está totalmente inicializado.                                                                |
| `VisitorCodeInvalid` | Excepción que indica que el código de visitante proporcionado no es válido. Está vacío o tiene más de 255 caracteres. |

##### Comportamiento de revocación del consentimiento

Cuando llama a `Client.set_legal_consent` con `legal_consent=false`, el SDK no elimina la cookie `kameleoonVisitorCode`. En su lugar, deja de extender la fecha de caducidad de la cookie, permitiendo que la cookie persista hasta que caduque de forma natural.

Si sus requisitos de cumplimiento exigen la eliminación inmediata del archivo de cookies tras la exclusión voluntaria, debe eliminarlo manualmente utilizando los métodos nativos de gestión de cookies de su framework. El SDK no eliminará el archivo automáticamente.

### Objetivos y analítica de terceros

#### track\_conversion()

* 📨 *Envía datos de seguimiento a Kameleoon*

Utilice este método para realizar el seguimiento de una conversión para un [objetivo](/user-manual//assets/goals/create-a-goal) y un usuario específicos. Este método requiere `visitor_code` y `goal_id`. Además, este método también acepta los argumentos opcionales `revenue`, `negative` y `metadata`. El `visitor_code` suele ser idéntico al que se utilizó al activar el experimento.

<Tip>
  Este método no es bloqueante ya que la llamada al servidor se realiza de forma asíncrona.
</Tip>

```elixir theme={null}
alias Kameleoon.Client
alias Kameleoon.Data.CustomData

# Hacer seguimiento de un objetivo.
:ok = Client.track_conversion(client, visitor_code, goal_id)

# Hacer seguimiento de un objetivo con ingresos.
:ok = Client.track_conversion(client, visitor_code, goal_id, revenue: 100.0)

# Hacer seguimiento de un objetivo con ingresos negativos.
:ok = Client.track_conversion(client, visitor_code, goal_id, revenue: 100.0, negative: true)

# Hacer seguimiento de un objetivo con metadatos personalizados.
:ok =
  Client.track_conversion(
    client,
    visitor_code,
    goal_id,
    metadata: [CustomData.new!(4, ["true"])]
  )
```

##### Argumentos

| Nombre                         | Tipo                              | Descripción                                                                                                                                    | Valor predeterminado |
| ------------------------------ | --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- |
| `visitor_code` (*obligatorio*) | `String.t()`                      | Identificador único del visitante.                                                                                                             |                      |
| `goal_id` (*obligatorio*)      | `non_neg_integer()`               | ID del objetivo.                                                                                                                               |                      |
| `revenue` (*opcional*)         | `number() \| nil`                 | Ingresos de la conversión.                                                                                                                     | `0`                  |
| `negative` (*opcional*)        | `boolean()`                       | Define si los ingresos son positivos o negativos.                                                                                              | `false`              |
| `metadata` (*opcional*)        | `[Kameleoon.Data.CustomData.t()]` | Metadatos de la conversión. [Deben definirse previamente en la aplicación de Kameleoon](/es/user-manual/assets/goals/create-a-goal#metadatos). | `[]`                 |

<Note>
  Los valores de metadata son accesibles a través de las [exportaciones de datos en bruto](/user-manual/experiment-analytics/analyze-results/results-page/results-page-actions#Export) y [la página de resultados](/user-manual/experiment-analytics/analyze-results/data-and-metrics/goal-metadata).

  Si se proporciona el parámetro `metadata`, Kameleoon utilizará estos valores especificados para la conversión actual en lugar de lo que se haya recopilado previamente con el método [`Client.add_data`](#add_data). Si se omite el parámetro, Kameleoon utilizará los últimos valores rastreados para esos [`CustomData`](#customdata) antes de la conversión y dentro de la misma visita.

  Kameleoon solo tendrá en cuenta los valores de metadata que se pasen explícitamente como parámetros al método `Client.track_conversion`.

  En el ejemplo siguiente, Kameleoon asociará la conversión solo con el valor del dato personalizado proporcionado explícitamente como parámetro (aquí: índice 5 con el valor 'Amex Credit Card').

  ```elixir theme={null}
  :ok =
    Client.add_data(client, visitor_code, [
      CustomData.new!(5, ["Credit Card"]),
      CustomData.new!(9, ["Express Delivery"])
    ])

  :ok =
    Client.track_conversion(
      client,
      visitor_code,
      goal_id,
      metadata: [CustomData.new!(5, ["Amex Credit Card"])]
    )
  ```
</Note>

##### Valor devuelto

| Tipo  | Descripción                      |                                                                                                            |
| ----- | -------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| \`:ok | \{:error, Kameleoon.Error.t()}\` | Indica si la conversión se puso en cola con éxito para el seguimiento asíncrono, de lo contrario un error. |

##### Errores

| Tipo                 | Descripción                                                                                                           |
| -------------------- | --------------------------------------------------------------------------------------------------------------------- |
| `Initialization`     | Indica que el SDK aún no está totalmente inicializado.                                                                |
| `VisitorCodeInvalid` | Excepción que indica que el código de visitante proporcionado no es válido. Está vacío o tiene más de 255 caracteres. |

#### get\_engine\_tracking\_code()

Kameleoon se integra con varias soluciones de analítica, incluidas Mixpanel, Google Analytics 4 y Segment. Para realizar correctamente el seguimiento de experimentos del lado del servidor, llame al método `Client.get_engine_tracking_code` después de que el visitante active un experimento. El SDK devuelve comandos de cola JavaScript para los experimentos que el visitante activó durante los cinco segundos anteriores. Cuando inserta este código en la página, Engine.js procesa los comandos y envía los eventos de exposición a través de la integración de analítica activa.

Consulte [experimentación híbrida](/developer-docs/feature-experimentation/get-started/hybrid-experimentation) para más información sobre la implementación de este método.

```elixir theme={null}
{:ok, tracking_code} = Kameleoon.Client.get_engine_tracking_code(client, visitor_code)
```

<Note>
  * Para utilizar esta funcionalidad, implemente tanto el SDK de Elixir como [Engine.js](/developer-docs/web-experimentation/implementation-and-deployment/standard-implementation) de Kameleoon. Dado que Engine.js solo se utiliza para el seguimiento en este flujo, puede instalar la etiqueta asíncrona antes de la etiqueta de cierre `</body>`.
  * Si solo desea realizar el seguimiento de experimentos en Kameleoon y no necesita enviar eventos de exposición a herramientas de analítica de terceros, utilice el [SDK de JavaScript / TypeScript](/developer-docs/sdks/web-sdks/js-sdk). Esta opción funciona bien para [plataformas serverless de edge compute](/developer-docs/feature-experimentation/implementation-and-deployment/serverless-edge-compute-starter-kits). El SDK de JavaScript / TypeScript rastrea automáticamente las variaciones cuando llama a [`getVisitorCode`](/developer-docs/sdks/web-sdks/js-sdk#getvisitorcode), siempre que añada las asignaciones de experimentos correspondientes a `window.kameleoonQueue`.
  * Puede insertar el código de seguimiento devuelto directamente en una etiqueta HTML `<script>`.

  ```html theme={null}
  <html lang="en">
    <body>
      <script>
        const engineTrackingCode = `
          window.kameleoonQueue = window.kameleoonQueue || [];
          window.kameleoonQueue.push(['Experiments.assignVariation', 123456, 7890, true]);
          window.kameleoonQueue.push(['Experiments.trigger', 123456, true]);
          window.kameleoonQueue.push(['Experiments.assignVariation', 234567, 8901, true]);
          window.kameleoonQueue.push(['Experiments.trigger', 234567, true]);
        `;
        const script = document.createElement('script');

        script.textContent = engineTrackingCode;
        document.body.appendChild(script);
      </script>

    </body>
  </html>
  ```

  En este ejemplo, `123456` y `234567` son IDs de experimentos, y `7890` y `8901` son IDs de variaciones. En su implementación, el SDK genera estos valores en el código de seguimiento devuelto.
</Note>

##### Argumentos

| Nombre                        | Tipo         | Descripción                        |
| ----------------------------- | ------------ | ---------------------------------- |
| visitor\_code (*obligatorio*) | `String.t()` | Identificador único del visitante. |

##### Valor devuelto

| Tipo                 | Descripción                      |                                                                                         |
| -------------------- | -------------------------------- | --------------------------------------------------------------------------------------- |
| \`\{:ok, String.t()} | \{:error, Kameleoon.Error.t()}\` | Código JavaScript para insertar en la página si tiene éxito; de lo contrario, un error. |

##### Errores

| Tipo                 | Descripción                                                                                                           |
| -------------------- | --------------------------------------------------------------------------------------------------------------------- |
| `Initialization`     | Indica que el SDK aún no está totalmente inicializado.                                                                |
| `VisitorCodeInvalid` | Excepción que indica que el código de visitante proporcionado no es válido. Está vacío o tiene más de 255 caracteres. |

### Eventos

#### on\_datafile\_update()

El método `Client.on_datafile_update` le permite gestionar el evento que se produce cuando la configuración ha actualizado los datos. Toma un parámetro de entrada, **handler**. El manejador que se llamará cuando la configuración se actualice mediante un evento de configuración en tiempo real.

```elixir theme={null}
:ok =
  Kameleoon.Client.on_datafile_update(client, fn ->
    IO.puts("Kameleoon datafile updated")
  end)

:ok = Kameleoon.Client.on_datafile_update(client, nil)
```

##### Argumentos

| Nombre  | Tipo                   | Descripción                                                                                                          |
| ------- | ---------------------- | -------------------------------------------------------------------------------------------------------------------- |
| handler | `(() -> any()) \| nil` | El manejador que se llamará cuando la configuración se actualice mediante un evento de configuración en tiempo real. |

### Tipos de datos

Esta sección lista los tipos de datos de Elixir disponibles bajo `Kameleoon.Data`.

#### ApplicationVersion

`ApplicationVersion` representa el número de versión semántica de su aplicación.

<Tip>
  Un **visitante** solo puede tener un `ApplicationVersion`. Añadir una segunda instancia sobrescribirá la primera.
</Tip>

| Nombre                  | Tipo         | Descripción                                                                                                                                           |
| ----------------------- | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| version (*obligatorio*) | `String.t()` | La versión de la aplicación. Este campo debe seguir el versionado semántico. Los formatos aceptados son `major`, `major.minor` o `major.minor.patch`. |

```elixir theme={null}
alias Kameleoon.Client
alias Kameleoon.Data.ApplicationVersion

# major
:ok = Client.add_data(client, visitor_code, ApplicationVersion.new!("10"))
# major.minor
:ok = Client.add_data(client, visitor_code, ApplicationVersion.new!("10.20"))
# major.minor.patch
:ok = Client.add_data(client, visitor_code, ApplicationVersion.new!("10.20.30"))
```

#### Browser

El conjunto de datos `Browser` almacenado aquí puede utilizarse para filtrar los informes de experimentos y personalización por cualquier valor asociado.

| Nombre               | Tipo              | Descripción                                                                                          |
| -------------------- | ----------------- | ---------------------------------------------------------------------------------------------------- |
| type (*obligatorio*) | `atom()`          | Lista de navegadores: `:chrome`, `:internet_explorer`, `:firefox`, `:safari`, `:opera`, `:other`.    |
| version (*opcional*) | `number() \| nil` | Versión del navegador, el número en coma flotante representa la versión mayor y menor del navegador. |

```elixir theme={null}
alias Kameleoon.Client
alias Kameleoon.Data.Browser

# Datos del navegador con versión
:ok = Client.add_data(client, visitor_code, Browser.new!(:safari, version: 26.4))
# Datos del navegador sin versión
:ok = Client.add_data(client, visitor_code, Browser.new!(:chrome))
```

#### Conversion

El conjunto de datos `Conversion` almacenado aquí puede utilizarse para filtrar los informes de experimentos y personalización por cualquier objetivo asociado.

<Tip>
  * Cada visitante puede tener varios objetos `Conversion`.
  * Puede encontrar el `goal_id` en la aplicación de Kameleoon.
</Tip>

| Nombre                   | Tipo                              | Descripción                                       | Valor predeterminado |
| ------------------------ | --------------------------------- | ------------------------------------------------- | -------------------- |
| goal\_id (*obligatorio*) | `non_neg_integer()`               | ID del objetivo.                                  |                      |
| revenue (*opcional*)     | `number() \| nil`                 | Ingresos de la conversión.                        | `nil`                |
| negative (*opcional*)    | `boolean()`                       | Define si los ingresos son positivos o negativos. | `false`              |
| metadata (*opcional*)    | `[Kameleoon.Data.CustomData.t()]` | Metadatos de la conversión.                       | `[]`                 |

```elixir theme={null}
alias Kameleoon.Client
alias Kameleoon.Data.Conversion
alias Kameleoon.Data.CustomData

# Añadir una conversión simple con ID 32
:ok = Client.add_data(client, visitor_code, Conversion.new!(32))

# Añadir conversión con ID 33 incluyendo ingresos y marcada como negativa
:ok = Client.add_data(client, visitor_code, Conversion.new!(33, revenue: 10.0, negative: true))

# Añadir conversión con ID 34 incluyendo ingresos, marca de negativo y metadatos personalizados
:ok =
  Client.add_data(
    client,
    visitor_code,
    Conversion.new!(34,
      revenue: 10.0,
      negative: true,
      metadata: [
        CustomData.new!(3, ["metadata1", "md2"]),
        CustomData.new!(5, ["md3"])
      ]
    )
  )
```

#### Cookie

`Cookie` contiene información sobre las cookies almacenadas en el dispositivo del visitante.

| Nombre  | Tipo                            | Descripción                                                          |
| ------- | ------------------------------- | -------------------------------------------------------------------- |
| cookies | `%\{String.t() => String.t()\}` | Un mapa de cadenas que contiene las claves y valores de las cookies. |

<Tip>
  Cada visitante solo puede tener una `Cookie`. Añadir una segunda `Cookie` sobrescribe la primera.
</Tip>

```elixir theme={null}
alias Kameleoon.Client
alias Kameleoon.Data.Cookie

:ok = Client.add_data(client, visitor_code, Cookie.new!(%{"segment" => "vip"}))
```

#### CustomData

`CustomData` permite la asociación de cualquier tipo de datos con cada visitante, convirtiéndolo en una herramienta eficaz para las condiciones de segmentación en [segmentos](/user-manual/assets/segments/create-a-segment/). Además, puede utilizarse como filtro o desglose en los informes de experimentos. Para más información sobre datos personalizados, consulte este [artículo](/developer-docs/custom-data).

Defina los tipos de datos personalizados en la aplicación de Kameleoon o en la Data API y utilícelos desde el SDK.

| Nombre                     | Tipo                             | Descripción                                                                                                                                                                                            | Valor predeterminado |
| -------------------------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------- |
| index/name (*obligatorio*) | `non_neg_integer()`/`String.t()` | Índice o nombre del dato personalizado. **Debe proporcionarse `index` o `name`** para identificar el dato.                                                                                             |                      |
| values (*obligatorio*)     | `[String.t()]`                   | Valores del dato personalizado que se almacenarán.                                                                                                                                                     |                      |
| overwrite (*opcional*)     | `boolean()`                      | Bandera para controlar explícitamente cómo se almacenan los valores y cómo aparecen en los informes. [Ver más](/developer-docs/custom-data#default-logic-when-overwrite-parameter-is-false-or-omitted) | `true`               |

<Note>
  * Cada visitante solo puede tener un `CustomData` por cada `index`(`name`) único. Añadir otro `CustomData` con el mismo `index`(`name`) reemplazará al existente.

  * El 'index' del dato personalizado se encuentra en el [panel de Custom Data](/user-manual/assets/custom-data/manage-custom-data) en la columna "INDEX".

  * Para evitar que el SDK envíe datos con el índice seleccionado a los servidores de Kameleoon por razones de privacidad, active la opción: **Use this data only locally for targeting purposes** al crear el dato personalizado.

  * Añadir una instancia de `CustomData` creada con un nombre cuando la instancia del SDK no esté inicializada o el nombre no esté registrado, hará que los datos sean ignorados.
</Note>

```elixir theme={null}
alias Kameleoon.Client
alias Kameleoon.Data.CustomData

:ok = Client.add_data(client, visitor_code, CustomData.new!(1, ["value"]))

# Con varios valores
:ok = Client.add_data(client, visitor_code, CustomData.new!(1, ["value1", "value2"]))

# Para establecer la bandera `overwrite` en false
:ok = Client.add_data(client, visitor_code, CustomData.new!(1, ["value"], overwrite: false))

# Para usar un nombre en lugar del índice
:ok = Client.add_data(client, visitor_code, CustomData.new_with_name!("my-custom-data", ["value"]))

# Para usar un nombre en lugar del índice y establecer la bandera `overwrite` en false
:ok =
  Client.add_data(
    client,
    visitor_code,
    CustomData.new_with_name!("my-custom-data", ["value"], overwrite: false)
  )
```

#### Device

Puede usar los datos del dispositivo para filtrar los informes de experimentos y personalización por cualquier valor asociado.

| Nombre | Tipo     | Descripción |            |                      |
| ------ | -------- | ----------- | ---------- | -------------------- |
| type   | \`:phone | :tablet     | :desktop\` | Tipo de dispositivo. |

```elixir theme={null}
alias Kameleoon.Client
alias Kameleoon.Data.Device

:ok = Client.add_data(client, visitor_code, Device.new!(:desktop))
```

#### Geolocation

`Geolocation` contiene los detalles de geolocalización del visitante.

| Nombre                    | Tipo                             | Descripción                                                                                                               |
| ------------------------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| country (*obligatorio*)   | `String.t()`                     | El país del visitante.                                                                                                    |
| region (*opcional*)       | <nobr>`String.t() \| nil`</nobr> | La región del visitante.                                                                                                  |
| city (*opcional*)         | <nobr>`String.t() \| nil`</nobr> | La ciudad del visitante.                                                                                                  |
| postal\_code (*opcional*) | <nobr>`String.t() \| nil`</nobr> | El código postal del visitante.                                                                                           |
| latitude (*opcional*)     | `number() \| nil`                | La coordenada de latitud que representa la ubicación del visitante. El número de coordenada representa grados decimales.  |
| longitude (*opcional*)    | `number() \| nil`                | La coordenada de longitud que representa la ubicación del visitante. El número de coordenada representa grados decimales. |

<Tip>
  * Cada visitante solo puede tener una `Geolocation`. Añadir una segunda `Geolocation` sobrescribe la primera.
</Tip>

```elixir theme={null}
alias Kameleoon.Client
alias Kameleoon.Data.Geolocation

geolocation =
  Geolocation.new!("France",
    region: "Ile-de-France",
    city: "Paris",
    postal_code: "75009",
    latitude: 48.8720171,
    longitude: 2.3338352
  )

:ok = Client.add_data(client, visitor_code, geolocation)
```

#### OperatingSystem

`OperatingSystem` contiene información sobre el sistema operativo del dispositivo del visitante.

| Nombre | Tipo       | Descripción |      |        |          |                   |                                |
| ------ | ---------- | ----------- | ---- | ------ | -------- | ----------------- | ------------------------------ |
| type   | \`:windows | :mac        | :ios | :linux | :android | :windows\_phone\` | Familia del sistema operativo. |

<Tip>
  Cada visitante solo puede tener un `OperatingSystem`. Añadir un segundo `OperatingSystem` sobrescribe el primero.
</Tip>

```elixir theme={null}
alias Kameleoon.Client
alias Kameleoon.Data.OperatingSystem

:ok = Client.add_data(client, visitor_code, OperatingSystem.new!(:windows))
```

#### PageView

Almacena eventos de visualización de páginas.

| Nombre    | Tipo          | Descripción                                                | Valor predeterminado       |       |
| --------- | ------------- | ---------------------------------------------------------- | -------------------------- | ----- |
| url       | `String.t()`  | URL de la página vista.                                    |                            |       |
| title     | \`String.t()  | nil\`                                                      | Título de la página vista. | `nil` |
| referrers | `[integer()]` | Índices de referencia de las páginas vistas anteriormente. | `[]`                       |       |

<Note>
  El índice del referrer está disponible en la aplicación de Kameleoon en la página de [configuración del canal de adquisición](/user-manual/assets/advanced-targeting-tools/create-an-acquisition-channel). Tenga cuidado: el índice empieza en `0`, así que el primer canal de adquisición que cree tendrá el ID `0`, no `1`.
</Note>

```elixir theme={null}
alias Kameleoon.Client
alias Kameleoon.Data.PageView

# Constructor completo con url, título opcional y referrers.
:ok = Client.add_data(client, visitor_code, PageView.new!("https://example.com", title: "Homepage", referrers: [3]))

# Constructor mínimo, solo requiere una URL.
:ok = Client.add_data(client, visitor_code, PageView.new!("https://example.com"))
```

#### UniqueIdentifier

Si no añade `UniqueIdentifier` para un visitante, se utiliza `visitor_code` como identificador único del visitante, lo que es útil para la [experimentación entre dispositivos](/developer-docs/cross-device-experimentation/). Cuando añade `UniqueIdentifier(true)`, el SDK vincula los datos transmitidos (flushed) con el visitante asociado al identificador especificado.

Esto puede ser útil en situaciones en las que no puede acceder al `visitor_code` anónimo asignado originalmente a un visitante, pero sí tiene acceso a un identificador interno conectado con ese visitante a través de la fusión de sesiones.

| Nombre  | Tipo        | Descripción                                                            |
| ------- | ----------- | ---------------------------------------------------------------------- |
| `value` | `boolean()` | Si el `visitor_code` actual debe tratarse como un identificador único. |

```elixir theme={null}
alias Kameleoon.Client
alias Kameleoon.Data.UniqueIdentifier

:ok = Client.add_data(client, visitor_code, UniqueIdentifier.new!(true))
```

#### UserAgent

Los experimentos del lado del servidor son más propensos a verse afectados por el tráfico de bots que los del lado del cliente. Kameleoon utiliza la IAB/ABC International Spiders and Bots List para reconocer bots y spiders conocidos, y también utiliza el campo `UserAgent` para filtrar otro tráfico no deseado que pueda distorsionar sus métricas de conversión. Para más información, consulte el artículo de ayuda sobre [filtrado de bots](/user-manual/faq#how-does-kameleoon-filter-bot-traffic-from-my-results).

Si utiliza bots internos, recomendamos enviar el valor de user-agent `curl/8.0` para excluirlos de la analítica.

| Nombre | Tipo         | Descripción                                                     |
| ------ | ------------ | --------------------------------------------------------------- |
| value  | `String.t()` | Valor de User-Agent enviado con las solicitudes de seguimiento. |

```elixir theme={null}
alias Kameleoon.Client
alias Kameleoon.Data.UserAgent

:ok = Client.add_data(client, visitor_code, UserAgent.new!("Mozilla/5.0"))
```

### Tipos devueltos

#### DataFile

El `DataFile` contiene los detalles de configuración del SDK.

Puede ampliarse con información adicional si los clientes lo requieren. Si necesita más detalles, póngase en contacto con su Customer Success Manager.

| Nombre         | Tipo                                                 | Descripción                                                                                      |
| -------------- | ---------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
| feature\_flags | `%\{String.t() => Kameleoon.Types.FeatureFlag.t()\}` | Un mapa de objetos [`FeatureFlag`](#featureflag), indexados por las claves de los feature flags. |
| date\_modified | `non_neg_integer() \| nil`                           | La marca de tiempo (en milisegundos) que indica cuándo se modificó por última vez el `DataFile`. |

```elixir theme={null}
# Recupera el mapa de feature flags del DataFile.
# El mapa está indexado por los identificadores de los feature flags, siendo cada valor un struct FeatureFlag.
feature_flags = datafile.feature_flags

# Recupera la marca de tiempo de la última modificación del DataFile.
# El valor es un entero que representa milisegundos desde la época Unix.
date_modified = datafile.date_modified
```

#### FeatureFlag

El `FeatureFlag` representa un conjunto de propiedades que definen un feature flag en sí — por ejemplo, sus [`Variations`](#variation), [`Rules`](#rule), estado del entorno y otros detalles relacionados.

Puede ampliarse con información adicional si los clientes lo requieren. Si necesita más detalles, póngase en contacto con su Customer Success Manager.

| Nombre                  | Tipo                                               | Descripción                                                                  |
| ----------------------- | -------------------------------------------------- | ---------------------------------------------------------------------------- |
| environment\_enabled    | `boolean()`                                        | Indica si el feature flag está habilitado en el entorno actual.              |
| default\_variation\_key | `String.t()`                                       | La clave de la variación predeterminada asociada al feature flag.            |
| variations              | `%\{String.t() => Kameleoon.Types.Variation.t()\}` | Un mapa de objetos `Variation`, indexados por las claves de las variaciones. |
| rules                   | `[Kameleoon.Types.Rule.t()]`                       | Una lista de objetos `Rule`.                                                 |

```elixir theme={null}

# Comprobar si el feature flag está habilitado en el entorno actual.
environment_enabled = feature_flag.environment_enabled

# Recuperar la clave de la variación predeterminada.
default_variation_key = feature_flag.default_variation_key

# Recuperar el struct de la variación predeterminada.
default_variation = Kameleoon.Types.FeatureFlag.default_variation(feature_flag)

# Recuperar todas las variaciones del feature flag como un mapa (clave = clave de variación, valor = struct Variation).
variations = feature_flag.variations

# Recuperar todas las reglas de segmentación asociadas al feature flag.
rules = feature_flag.rules
```

#### Rule

`Rule` representa un conjunto de propiedades que definen una regla en sí — por ejemplo, sus [`Variations`](#variation).

Puede ampliarse con información adicional si los clientes lo requieren. Si necesita más detalles, póngase en contacto con su Customer Success Manager.

| Nombre     | Tipo                                               | Descripción                                                                  |
| ---------- | -------------------------------------------------- | ---------------------------------------------------------------------------- |
| variations | `%\{String.t() => Kameleoon.Types.Variation.t()\}` | Un mapa de objetos `Variation`, indexados por las claves de las variaciones. |

```elixir theme={null}
# Recuperar todas las variaciones de la regla como un mapa (clave = clave de variación, valor = struct Variation).
variations = rule.variations
```

#### Variation

`Variation` contiene información sobre la variación asignada al visitante, o la variación predeterminada cuando no existe una asignación específica.

| Nombre         | Tipo                             | Descripción                                                                                            |                                                                                           |
| -------------- | -------------------------------- | ------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------- |
| name           | \`String.t()                     | nil\`                                                                                                  | El nombre de la variación.                                                                |
| key            | \`String.t()                     | nil\`                                                                                                  | La clave única que identifica la variación.                                               |
| id             | \`non\_neg\_integer()            | nil\`                                                                                                  | El ID de la variación asignada, o `nil` para una variación predeterminada.                |
| experiment\_id | \`non\_neg\_integer()            | nil\`                                                                                                  | El ID del experimento asociado a la variación, o `nil` para una variación predeterminada. |
| variables      | `[Kameleoon.Types.Variable.t()]` | Variables asociadas a la variación. Esta colección puede estar vacía cuando no hay variables adjuntas. |                                                                                           |

<Note>
  * `Variation` describe la variación asignada o predeterminada, mientras que [`Variable`](#variable) contiene los detalles de cada variable individual.
  * `id` y `experiment_id` pueden ser `nil`, lo que indica una variación predeterminada que no está ligada a una asignación específica de experimento.
</Note>

Métodos auxiliares adicionales:

| Método                              | Tipo devuelto | Descripción                               |
| ----------------------------------- | ------------- | ----------------------------------------- |
| `Kameleoon.Types.Variation.active?` | `boolean()`   | Devuelve `false` para la variación `off`. |

```elixir theme={null}
# Recuperando el nombre de la variación.
variation_name = variation.name

# Recuperando la clave de la variación.
variation_key = variation.key

# Recuperando el id de la variación.
variation_id = variation.id

# Recuperando el id del experimento.
experiment_id = variation.experiment_id

# Recuperando la lista de variables.
variables = variation.variables

# Comprobando si la variación está activa (es decir, se está sirviendo actualmente a los visitantes).
active? = Kameleoon.Types.Variation.active?(variation)

# Recuperando una variable por su clave, devolviendo nil si no se encuentra.
variable = Enum.find(variation.variables, &(&1.key == "title"))
```

#### Variable

`Variable` contiene información sobre una variable asociada a la variación asignada.

| Nombre | Tipo                                  | Descripción                                                                                                |                                                                                                                                                                       |
| ------ | ------------------------------------- | ---------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| key    | `String.t() \| nil`                   | La clave única que identifica la variable.                                                                 |                                                                                                                                                                       |
| kind   | `String.t() \| nil`                   | El tipo de la variable. Los valores posibles incluyen `BOOLEAN`, `NUMBER`, `STRING`, `JSON`, `JS` y `CSS`. |                                                                                                                                                                       |
| value  | \`boolean() \| number() \| String.t() | nil\`                                                                                                      | El valor de la variable. Dependiendo de `kind`, puede contener un booleano, un número, una cadena, una cadena JSON, un fragmento de JavaScript o un fragmento de CSS. |

```elixir theme={null}
# Recuperar la lista de variables asociadas a la variación.
variables = variation.variables

# Acceder al tipo de variable (kind) para un manejo condicional.
kind = variable.kind

# Extraer el valor como número.
number = variable.value

# Extraer el valor como booleano.
apply_discount? = variable.value

# Extraer el valor como cadena.
title = variable.value
```
