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

# Cómo construir una función de XP

> Aprende a usar Trophy para añadir una función de XP a tu aplicación web o móvil.

La guía describe el proceso completo para añadir una función de XP a tu aplicación web o móvil usando Trophy.

Con fines ilustrativos, usaremos el ejemplo de una plataforma de estudio que utiliza XP para recompensar a los usuarios por realizar diferentes interacciones.

<Tip>
  Para ver un ejemplo completamente funcional de esto en la práctica, consulta la [demostración
  en vivo](https://examples.trophy.so) o el [repositorio de
  github](https://github.com/trophyso/example-study-platform/tree/demo).
</Tip>

<h2 id="pre-requisites">
  Requisitos previos
</h2>

* Una cuenta de [Trophy](https://app.trophy.so/sign-up)
* Aproximadamente 10 minutos

<h2 id="trophy-setup">
  Configuración de Trophy
</h2>

En Trophy, las [Métricas](/es/features/metrics) son los bloques de construcción de la gamificación y modelan las diferentes interacciones que los usuarios tienen con tu producto.

En esta guía, la interacción que nos interesa es `flashcards-viewed`, pero puedes crear cualquier número de métricas que mejor representen las interacciones por las que deseas recompensar XP.

En el panel de Trophy, dirígete a la [página de métricas](https://app.trophy.so/metrics) y crea una métrica.

<Frame>
  <video autoPlay muted loop playsInline className="w-full aspect-video" src="https://mintcdn.com/trophy/2khPIyZFxPyE7xgA/assets/guides/achievements-feature/create_new_metric.mp4?fit=max&auto=format&n=2khPIyZFxPyE7xgA&q=85&s=8e66d7276d9648d449c4556340febf45" data-path="assets/guides/achievements-feature/create_new_metric.mp4" />
</Frame>

Una vez que hayas creado tu métrica, dirígete a la [página de puntos](https://app.trophy.so/points) y crea un nuevo sistema de puntos llamado 'XP'.

<Frame>
  <video autoPlay muted loop playsInline className="w-full aspect-video" src="https://mintcdn.com/trophy/2khPIyZFxPyE7xgA/assets/guides/xp-feature/create_system.mp4?fit=max&auto=format&n=2khPIyZFxPyE7xgA&q=85&s=95e4d131e3a694719a536227c9f8fc61" data-path="assets/guides/xp-feature/create_system.mp4" />
</Frame>

Una vez creado, serás redirigido a la página de configuración del sistema de XP donde puedes crear 'disparadores' para cada una de las formas en que deseas recompensar a los usuarios con XP.

<Frame>
  <video autoPlay muted loop playsInline className="w-full aspect-video" src="https://mintcdn.com/trophy/2khPIyZFxPyE7xgA/assets/guides/xp-feature/create_trigger.mp4?fit=max&auto=format&n=2khPIyZFxPyE7xgA&q=85&s=493a23cbed41c5636992827448c366c0" data-path="assets/guides/xp-feature/create_trigger.mp4" />
</Frame>

En Trophy rastrear las interacciones de los usuarios se hace enviando [Eventos](/es/features/events) desde tu código a las APIs de Trophy contra una métrica específica.

Cuando se registran eventos para un usuario específico, Trophy verificará automáticamente si el evento está asociado a una métrica configurada como parte de algún disparador de XP.

Si es así, Trophy otorgará al usuario la cantidad apropiada de XP según la configuración del disparador.

Esto es lo que hace que construir experiencias gamificadas con Trophy sea tan fácil: hace todo el trabajo por ti detrás de escena.

<Tip>
  El XP también puede otorgarse a los usuarios en base a logros, rachas y otros
  disparadores. Consulta la [documentación de puntos](/es/features/points#points-triggers) dedicada
  para más información.
</Tip>

<h2 id="installing-trophy-sdk">
  Instalación del SDK de Trophy
</h2>

Para interactuar con Trophy desde tu código utilizarás el SDK de Trophy disponible en los principales [lenguajes de programación](/es/api-reference/client-libraries).

Instala el SDK de Trophy:

<CodeGroup>
  ```bash Node theme={null}
  npm install @trophyso/node
  ```

  ```bash Ruby theme={null}
  gem install trophy_api_client
  ```

  ```bash Python theme={null}
  pip install trophy
  ```

  ```bash PHP theme={null}
  composer require trophyso/php
  ```

  ```bash Java (Gradle) theme={null}
  implementation 'so.trophy:trophy-java:1.0.0'
  ```

  ```bash Java (Maven) theme={null}
  <dependency>
    <groupId>so.trophy</groupId>
    <artifactId>trophy-java</artifactId>
    <version>1.0.0</version>
  </dependency>
  ```

  ```bash Go theme={null}
  go get github.com/trophy-so/trophy-go
  ```

  ```bash .NET (C#) theme={null}
  // .NET Core CLI
  dotnet add package Trophy

  // Nuget Package Manager
  nuget install Trophy

  // Visual Studio
  Install-Package Trophy
  ```
</CodeGroup>

A continuación, obtén tu clave API desde la [página de integración](https://app.trophy.so/integration) de Trophy y agrégala como una variable de entorno **exclusivamente del lado del servidor**.

```bash theme={null}
TROPHY_API_KEY='*******'
```

<Warning>
  Asegúrate de **no** exponer tu clave API en código del lado del cliente.
</Warning>

<h2 id="tracking-user-interactions">
  Rastreo de Interacciones de Usuario
</h2>

Para rastrear un evento (interacción de usuario) contra tu métrica, utiliza la [API de cambio de métrica](/es/api-reference/endpoints/metrics/send-a-metric-change-event).

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://app.trophy.so/api/metrics/flashcards-flipped/event \
       -H "X-API-KEY: <apiKey>" \
       -H "Content-Type: application/json" \
       -d '{
    "user": {
      "id": "18",
      "email": "user@example.com",
      "tz": "Europe/London"
    },
    "value": 750
  }'
  ```

  ```typescript Node theme={null}
  trophy.metrics.event("flashcards-flipped", {
    user: {
      id: "18",
      email: "user@example.com",
      tz: "Europe/London",
    },
    value: 750,
  });
  ```

  ```python Python theme={null}
  client.metrics.event(
      key="flashcards-flipped",
      user=EventRequestUser(
          id="18",
          email="user@example.com",
          tz="Europe/London",
      ),
      value=750.0,
  )
  ```

  ```php PHP theme={null}
  $user = new EventRequestUser([
      'id' => '18',
      'email' => 'user@example.com'
  ]);

  $request = new MetricsEventRequest([
      'user' => $user,
      'value' => 750
  ]);

  $trophy->metrics->event("flashcards-flipped", $request);
  ```

  ```java Java theme={null}
  MetricsEventRequest request = MetricsEventRequest.builder()
        .user(
          EventRequestUser.builder()
            .id("18")
            .email("user@example.com")
            .build()
        )
        .value(750)
        .build();

  EventResponse response = client.metrics().event("flashcards-flipped", request);
  ```

  ```go Go theme={null}
  response, err := client.Metrics.Event(
      "flashcards-flipped",
      &api.MetricsEventRequest{
          User: &api.EventRequestUser{
              Id: "18",
              Email: "user@example.com",
          },
          Value: 750,
      },
  )
  ```

  ```csharp C# theme={null}
  var user = new EventRequestUser {
     Id = "18",
     Email = "user@example.com"
  };

  var request = new MetricsEventRequest {
     User = user,
     Value = 750
  };

  await trophy.Metrics.EventAsync("flashcards-flipped", request);
  ```

  ```ruby Ruby theme={null}
  result = client.metrics.event(
    :key => 'flashcards-flipped',
    :user => {
      :id => '18',
      :email => 'user@example.com'
    },
    :value => 750
  )
  ```
</CodeGroup>

La respuesta a esta llamada API es el conjunto completo de cambios en cualquier característica que hayas construido con Trophy, incluyendo cualquier XP que se haya otorgado al usuario como resultado del evento, y desde qué disparadores se otorgó.

<Note>
  Si utilizas [Niveles de Puntos](/es/features/points#points-levels), el objeto `xp` puede incluir un campo **`level`** **solo cuando** el nivel del usuario cambió en esta solicitud; puede omitirse cuando su nivel permaneció igual. Consulta la [referencia de la API de cambio de métrica](/es/api-reference/endpoints/metrics/send-a-metric-change-event) para el esquema completo de respuesta.
</Note>

```json Response [expandable] theme={null}
{
  "metricId": "d01dcbcb-d51e-4c12-b054-dc811dcdc623",
  "eventId": "0040fe51-6bce-4b44-b0ad-bddc4e123534",
  "total": 900,
  ...,
  "points": {
    "xp": {
      "id": "0040fe51-6bce-4b44-b0ad-bddc4e123534",
      "key": "xp",
      "name": "XP",
      "description": null,
      "badgeUrl": null,
      "maxPoints": null,
      "total": 450,
      "added": 50,
      "awards": [
        {
          "id": "0040fe51-6bce-4b44-b0ad-bddc4e123534",
          "awarded": 50,
          "date": "2021-01-01T00:00:00Z",
          "total": 450,
          "trigger": {
            "id": "0040fe51-6bce-4b44-b0ad-bddc4e123534",
            "type": "metric",
            "metricName": "Flashcards Flipped",
            "metricThreshold": 100,
            "points": 50
          }
        }
      ]
    }
  },
  ...
}
```

Valida que esto esté funcionando revisando el [panel de control](https://app.trophy.so) de Trophy.

<h2 id="displaying-xp">
  Mostrar XP
</h2>

Tienes varias opciones para mostrar XP en tu aplicación. Aquí veremos las opciones más comunes.

<h3 id="pop-up-notifications">
  Notificaciones Emergentes
</h3>

Podemos usar la respuesta de la [API de cambio de métrica](/es/api-reference/endpoints/metrics/send-a-metric-change-event) para mostrar a los usuarios notificaciones emergentes cuando se les otorga nuevo XP.

Aquí hay un ejemplo de esto en acción:

```ts XP Pop-ups theme={null}
// Sends event to Trophy
const response = await viewFlashcard();

if (!response) {
  return;
}

const xp = response.points.xp;

// Show toast if user was awarded XP
if (xp.awards.length > 0) {
  const trigger = xp.awards[0].trigger;

  toast({
    title: `You gained ${xp.added} XP`,

    // e.g. "+20 XP for 10 flashcards flipped"
    description: `+${trigger.points} XP for ${
      trigger.metricThreshold
    } ${trigger.metricName.toLowercase()}`,
  });
}
```

<Tip>
  Si deseas reproducir efectos de sonido, usa la [API de Audio
  HTML5](https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API) y siéntete
  libre de usar estos [archivos de
  audio](https://github.com/trophyso/example-study-platform/tree/demo/public/sounds)
  que recomendamos.
</Tip>

<h3 id="displaying-user-xp">
  Mostrar XP del Usuario
</h3>

Para obtener el XP de un usuario, utiliza la [API de Puntos del usuario](/es/api-reference/endpoints/users/get-a-users-points).

<CodeGroup>
  ```bash cURL theme={null}
  curl --request GET \
    --url https://api.trophy.so/v1/users/{id}/points/{key} \
    --header 'X-API-KEY: <api-key>'
  ```

  ```typescript Node theme={null}
  trophy.users.points("user-id", "points-system-key");
  ```

  ```python Python theme={null}
  client.users.points(
      id="user-id",
      key="points-system-key",
  )
  ```

  ```php PHP theme={null}
  $trophy->users->points("user-id", "points-system-key");
  ```

  ```java Java theme={null}
  client.users().points("user-id","points-system-key");
  ```

  ```go Go theme={null}
  response, err := client.Users.Points(
      "user-id",
      "points-system-key"
  )
  ```

  ```csharp C# theme={null}
  trophy.Users.PointsAsync("user-id", "points-system-key");
  ```

  ```ruby Ruby theme={null}
  result = client.users.points(
    :id => 'user-id',
    :key => "points-system-key"
  )
  ```
</CodeGroup>

Esta API devuelve datos sobre el XP total del usuario, pero puede configurarse para devolver también entre 1 y 100 de las recompensas de XP más recientes del usuario mediante el parámetro de consulta `awards`.

```json Response [expandable] theme={null}
{
  "id": "0040fe51-6bce-4b44-b0ad-bddc4e123534",
  "key": "xp",
  "name": "XP",
  "description": null,
  "badgeUrl": null,
  "maxPoints": null,
  "total": 100,
  "level": {
    "id": "1140fe51-6bce-4b44-b0ad-bddc4e123534",
    "key": "silver",
    "name": "Silver",
    "description": "Mid-tier level",
    "badgeUrl": null,
    "points": 50
  },
  "awards": [
    {
      "id": "0040fe51-6bce-4b44-b0ad-bddc4e123534",
      "awarded": 10,
      "date": "2021-01-01T00:00:00Z",
      "total": 100,
      "trigger": {
        "id": "0040fe51-6bce-4b44-b0ad-bddc4e123534",
        "type": "metric",
        "points": 10,
        "metricName": "Flashcards Flipped",
        "metricThreshold": 1000
      }
    }
  ]
}
```

Aquí hay un ejemplo de una interfaz que muestra a los usuarios una lista de sus recompensas más recientes basada en los datos devueltos por la API de Puntos del usuario.

<Frame>
  <img height="200" width="100%" noZoom src="https://mintcdn.com/trophy/2khPIyZFxPyE7xgA/assets/guides/xp-feature/awards.png?fit=max&auto=format&n=2khPIyZFxPyE7xgA&q=85&s=c879729849ddd5bc32439ce56119a78c" data-path="assets/guides/xp-feature/awards.png" />
</Frame>

<h3 id="user-xp-chart">
  Gráfico de XP del Usuario
</h3>

La [API de resumen de Puntos del usuario](/es/api-reference/endpoints/users/get-a-users-points-summary) devuelve datos históricos listos para graficar que muestran cómo ha cambiado el XP de un usuario a lo largo del tiempo.

<CodeGroup>
  ```bash cURL theme={null}
  curl --request GET \
    --url https://api.trophy.so/v1/users/{id}/points/{key}/event-summary \
    --header 'X-API-KEY: <api-key>'
  ```

  ```typescript Node theme={null}
  trophy.users.pointsEventSummary("user-id", "points-system-key", {
    aggregation: "daily",
    start_date: "2025-01-01",
    end_date: "2025-01-07"
  });
  ```

  ```python Python theme={null}
  client.users.points_event_summary(
    id="user-id",
    key="points-system-key",
    aggregation="daily",
    start_date="2025-01-01",
    end_date="2025-01-07"
  )
  ```

  ```php PHP theme={null}
  $trophy->users->pointsEventSummary("user-id", "points-system-key");
  ```

  ```java Java theme={null}
  client.users().pointsEventSummary("user-id","points-system-key");
  ```

  ```go Go theme={null}
  response, err := client.Users.PointsEventSummary(
      "user-id",
      "points-system-key"
  )
  ```

  ```csharp C# theme={null}
  trophy.Users.PointsEventSummaryAsync("user-id", "points-system-key");
  ```

  ```ruby Ruby theme={null}
  result = client.users.pointsEventSummary(
    :id => 'user-id',
    :key => "points-system-key"
  )
  ```
</CodeGroup>

Utiliza los parámetros de consulta `aggregation`, `start_date` y `end_date` para controlar los datos devueltos. Aquí hay un ejemplo de datos de XP agregados diariamente:

```json GET /users/{id}/points/{key}/event-summary — 200 response [expandable] theme={null}
[
  {
    "date": "2024-01-01",
    "total": 100,
    "change": 100
  },
  {
    "date": "2024-01-02",
    "total": 300,
    "change": 200
  },
  {
    "date": "2024-01-03",
    "total": 600,
    "change": 300
  }
]
```

Y aquí hay un ejemplo de los tipos de gráficos que puedes construir con estos datos:

<Frame>
  <img height="200" width="100%" noZoom src="https://mintcdn.com/trophy/2khPIyZFxPyE7xgA/assets/guides/xp-feature/chart.png?fit=max&auto=format&n=2khPIyZFxPyE7xgA&q=85&s=e187337549c5cd48b6f79e6bdfc677e3" data-path="assets/guides/xp-feature/chart.png" />
</Frame>

<h2 id="analytics">
  Analíticas
</h2>

En Trophy, tu [página del sistema de xp](https://app.trophy.so/points) incluye gráficos de analíticas que muestran datos sobre el total de XP ganado y un desglose exacto de qué desencadenadores otorgan la mayor cantidad de XP.

<Frame>
  <img height="200" width="100%" noZoom src="https://mintcdn.com/trophy/2khPIyZFxPyE7xgA/assets/guides/xp-feature/analytics.png?fit=max&auto=format&n=2khPIyZFxPyE7xgA&q=85&s=5fc92abbc99696e17ed3451d931abdd7" data-path="assets/guides/xp-feature/analytics.png" />
</Frame>

<h2 id="get-support">
  Obtener Soporte
</h2>

¿Quieres contactar con el equipo de Trophy? Comunícate con nosotros por [correo electrónico](mailto:support@trophy.so). ¡Estamos aquí para ayudarte!
