> ## 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.

# Eventos

> Los eventos son objetos de datos que representan interacciones individuales de usuarios contra métricas en Trophy.

<h2 id="what-are-events">
  ¿Qué son los eventos?
</h2>

Los eventos representan interacciones individuales de usuarios contra [Métricas](/es/features/metrics) en Trophy. Un evento corresponde a una única interacción realizada por un único usuario.

Cuando [integras métricas](#tracking-metric-events) en tu plataforma, estás configurando tu plataforma para transmitir continuamente eventos a tus métricas de Trophy para cada interacción de usuario. Estas interacciones luego impulsan todas las funcionalidades de gamificación que configures alrededor de estas métricas.

<h2 id="key-attributes">
  Atributos clave
</h2>

<h3 id="event-value">
  Valor del evento
</h3>

El `value` de un evento es la cantidad numérica que se añadirá al recuento total de la métrica del usuario como resultado de la interacción del usuario a la que se refiere.

<Tip>
  El valor de un evento puede ser positivo o negativo, y puede ser un número entero o un decimal.
</Tip>

<h2 id="custom-event-attributes">
  Atributos personalizados de eventos
</h2>

<Note>
  Esta funcionalidad está disponible en el plan [Pro](/es/account/billing#pro-plan)
</Note>

<Frame>
  <img height="200" noZoom src="https://mintcdn.com/trophy/rGjOHIeZYrVU9hOo/assets/features/events/custom_event_attributes.png?fit=max&auto=format&n=rGjOHIeZYrVU9hOo&q=85&s=1d3b4c0b39fe1991f62a654aca9e10de" data-path="assets/features/events/custom_event_attributes.png" />
</Frame>

Puedes especificar varios atributos personalizados de eventos para ayudarte a rastrear información adicional relevante para tu caso de uso contra los eventos que envías a Trophy.

Por ejemplo, una aplicación de aprendizaje de idiomas podría tener una métrica de 'Preguntas completadas' y usar un atributo personalizado de evento para almacenar si la respuesta a cada pregunta fue correcta.

De manera similar, una aplicación de fitness podría usar una métrica de 'Ejercicios completados' y usar un atributo personalizado de evento para almacenar el peso que se utilizó en cada ejercicio y otro atributo personalizado de evento para almacenar cuánto duró el ejercicio.

Usar atributos de eventos personalizados de esta manera te permite enriquecer eventos en Trophy con contexto adicional relevante para tu caso de uso y utilizarlo para impulsar características de gamificación aún más atractivas.

<h3 id="creating-attributes">
  Crear Atributos
</h3>

Para crear un nuevo atributo de evento personalizado, dirígete a la página de métricas en el panel de Trophy y haz clic en el botón *Agregar Atributo de Evento*.

Asigna un nombre y una clave única al atributo; usarás la clave cuando hagas referencia al atributo en las llamadas a la API.

<Frame>
  <video autoPlay muted loop playsInline className="w-full aspect-15/4" src="https://mintcdn.com/trophy/rGjOHIeZYrVU9hOo/assets/features/events/create_custom_event_attribute.mp4?fit=max&auto=format&n=rGjOHIeZYrVU9hOo&q=85&s=780eb5cb9b9d33afaa22ba2fb01f55e5" data-path="assets/features/events/create_custom_event_attribute.mp4" />
</Frame>

<h3 id="setting-attributes">
  Establecer Atributos
</h3>

Para establecer el valor de un atributo personalizado en un evento, pasa su valor en el objeto `attributes` en tu código de seguimiento de métricas.

<Warning>
  Trophy solo establecerá valores de atributos que primero hayan sido creados
  en el panel. Hacemos esto para ayudarte a mantener un conjunto limpio de atributos y
  prevenir sobrescrituras accidentales.

  Si recibes un error similar al siguiente, es posible que hayas escrito mal la clave del atributo en la solicitud, o necesites crear el atributo primero en el panel de Trophy:

  ```json theme={null}
  {
    "error": "Invalid attribute keys: device. Please ensure all attribute keys match those set up at https://app.trophy.so/metrics."
  }
  ```
</Warning>

Aquí hay un ejemplo de un payload de evento donde se establecen los valores de dos atributos, `device` y `duration`:

```json {7-10} theme={null}
{
  "user": {
    "id": "18",
    "tz": "Europe/London"
  },
  "value": 25,
  "attributes": {
    "device": "ios",
    "duration": "120"
  }
}
```

<h3 id="using-attributes">
  Usar Atributos
</h3>

Los atributos de eventos personalizados pueden utilizarse para impulsar desencadenadores más avanzados para logros y puntos, y pueden usarse en plantillas de correo electrónico para personalizar el texto y controlar los datos mostrados en gráficos.

<h4 id="advanced-feature-triggers">
  Desencadenadores Avanzados de Características
</h4>

Los atributos de eventos personalizados pueden utilizarse para configurar desencadenadores de logros o puntos que solo rastreen eventos con valores de atributos específicos. Sigue los enlaces a las páginas relevantes a continuación para obtener más información.

<CardGroup>
  <Card title="Disparadores de Logros" icon="trophy" href="/es/features/achievements#creating-achievements">
    Configura logros que solo se pueden desbloquear mediante eventos con ciertos
    valores de atributos.
  </Card>

  <Card title="Disparadores de Puntos" icon="sparkle" href="/es/features/points#points-triggers">
    Configura disparadores de puntos para otorgar puntos solo desde eventos con
    valores de atributos específicos.
  </Card>
</CardGroup>

<h4 id="email-customization">
  Personalización de correos electrónicos
</h4>

Si utilizas cualquier [correo electrónico](/es/features/emails) de Trophy, los atributos de eventos se pueden usar para personalizar los datos mostrados en ciertos bloques de correo electrónico.

En primer lugar, cuando utilices variables basadas en métricas en el texto del correo electrónico, puedes usar atributos de eventos para controlar con mayor precisión a qué datos hace referencia la variable.

Por ejemplo, aquí hay un caso donde usamos una variable de correo electrónico para informar a los usuarios sobre su número total de entrenamientos realizados en diferentes equipos de gimnasio, utilizando una métrica 'Workouts' y un atributo 'Equipment':

<Frame>
  <video autoPlay muted loop playsInline className="w-full aspect-15/4" src="https://mintcdn.com/trophy/rGjOHIeZYrVU9hOo/assets/features/events/using_attributes_in_emails.mp4?fit=max&auto=format&n=rGjOHIeZYrVU9hOo&q=85&s=4f6b6b16c3bb80da1e91b891e812a529" data-path="assets/features/events/using_attributes_in_emails.mp4" />
</Frame>

En segundo lugar, aquí hay un ejemplo donde agregamos un gráfico a un correo electrónico que muestra a los usuarios cuántos entrenamientos han realizado en bicicleta a lo largo del tiempo:

<Frame>
  <video autoPlay muted loop playsInline className="w-full aspect-15/4" src="https://mintcdn.com/trophy/rGjOHIeZYrVU9hOo/assets/features/events/using_attributes_in_email_charts.mp4?fit=max&auto=format&n=rGjOHIeZYrVU9hOo&q=85&s=bb0c76651b0a627c83b14424cf2764c0" data-path="assets/features/events/using_attributes_in_email_charts.mp4" />
</Frame>

Hay un gran número de posibilidades aquí, ¡así que sé creativo!

<h2 id="tracking-metric-events">
  Seguimiento de eventos de Métricas
</h2>

Cada métrica tiene un `key` único que puedes usar para referenciar y rastrear eventos en tu código. Puedes encontrar el `key` en la página de configuración de la métrica.

Para comenzar a rastrear las interacciones de usuarios como eventos en tus Métricas de Trophy, usa la [API de Métricas](/es/api-reference/endpoints/metrics/send-a-metric-change-event) o una de nuestras [Bibliotecas cliente](/es/api-reference/client-libraries) con tipos seguros, compatibles con la mayoría de los principales lenguajes de programación.

Aquí hay un ejemplo donde una plataforma de estudio ficticia utiliza una métrica para rastrear el número de tarjetas de estudio volteadas por cada estudiante. Cada vez que un estudiante interactúa, la plataforma envía un evento a Trophy indicándole cuántas tarjetas de estudio vieron:

<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>

Cualquier [Logro](/es/features/achievements), [Racha](/es/features/streaks), [Puntos](/es/features/points) o [Clasificación](/es/features/leaderboards) que se haya configurado para esta métrica se procesará automáticamente, y la respuesta contendrá cualquier actualización del progreso del usuario que sea un resultado directo del evento ocurrido:

```json Response [expandable] theme={null}
{
  "metricId": "d01dcbcb-d51e-4c12-b054-dc811dcdc623",
  "eventId": "0040fe51-6bce-4b44-b0ad-bddc4e123534",
  "total": 750,
  "achievements": [
    {
      "id": "5100fe51-6bce-6j44-b0hs-bddc4e123682",
      "trigger": "metric",
      "metricId": "5100fe51-6bce-6j44-b0hs-bddc4e123682",
      "metricName": "Flashcards Flipped",
      "metricValue": 500,
      "name": "500 Flashcards Flipped",
      "description": "Write 500 words in the app.",
      "achievedAt": "2020-01-01T00:00:00Z"
    }
  ],
  "currentStreak": {
    "length": 1,
    "frequency": "daily",
    "started": "2025-04-02",
    "periodStart": "2025-03-31",
    "periodEnd": "2025-04-05",
    "expires": "2025-04-12"
  },
  "points": {
    "xp": {
      "id": "0040fe51-6bce-4b44-b0ad-bddc4e123534",
      "key": "xp",
      "name": "XP",
      "description": null,
      "badgeUrl": null,
      "maxPoints": null,
      "total": 10,
      "level": {
        "id": "1140fe51-6bce-4b44-b0ad-bddc4e123534",
        "key": "bronze",
        "name": "Bronze",
        "description": "Starting level",
        "badgeUrl": null,
        "points": 0
      },
      "added": 10,
      "awards": [
        {
          "id": "0040fe51-6bce-4b44-b0ad-bddc4e123534",
          "awarded": 10,
          "date": "2021-01-01T00:00:00Z",
          "total": 10,
          "trigger": {
            "id": "0040fe51-6bce-4b44-b0ad-bddc4e123534",
            "type": "metric",
            "metricName": "Flashcards Flipped",
            "metricThreshold": 100,
            "points": 10
          }
        }
      ]
    }
  },
  "leaderboards": {
    "daily_champions": {
      "id": "0040fe51-6bce-4b44-b0ad-bddc4e123535",
      "key": "daily_champions",
      "name": "Daily Champions",
      "description": null,
      "rankBy": "metric",
      "runUnit": null,
      "runInterval": 0,
      "maxParticipants": 100,
      "metricName": "Flashcards Flipped",
      "metricKey": "flashcards-flipped",
      "threshold": 10,
      "start": "2025-01-01",
      "end": null,
      "previousRank": 50,
      "rank": 12
    }
  }
}
```

En este ejemplo, la respuesta incluye lo siguiente:

* Los logros recién desbloqueados del usuario como resultado del evento
* La racha más reciente del usuario como resultado del evento
* Los puntos más recientes del usuario para cada sistema de puntos que cambió como resultado del evento
* Los datos de clasificación más recientes del usuario para cada clasificación que cambió como resultado del evento

Con un poco de código personalizado, estos datos de respuesta se pueden utilizar para impulsar cualquier experiencia dentro de la aplicación que desees, incluyendo:

* Activar notificaciones dentro de la aplicación
* Efectos de sonido
* Animaciones

Observa cómo Charlie integra el seguimiento de métricas en una aplicación simple de NextJS usando el SDK de Trophy para [Node.js](/es/api-reference/client-libraries):

<Frame>
  <iframe width="560" height="315" src="https://www.youtube.com/embed/ZxbOylQ6kQU?si=2C8IvN0trlIzLeO7" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen />
</Frame>

<h3 id="idempotent-events">
  Eventos Idempotentes
</h3>

Trophy permite garantizar la unicidad en los eventos para que los usuarios no puedan aumentar una métrica realizando la misma acción exacta una y otra vez.

Por ejemplo, una aplicación de aprendizaje de idiomas podría especificar que los usuarios solo pueden aumentar la métrica `lessons-completed` en 1 por cada lección única completada, por lo que si completan la misma lección dos veces, solo la primera cuenta.

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

  ```typescript Node {9} theme={null}
  trophy.metrics.event("lessons-completed",
    {
      user: {
        id: "18",
        email: "user@example.com",
        tz: "Europe/London",
      },
      value: 1,
      idempotencyKey: "lesson-123",
    }
  );
  ```

  ```python Python {9} theme={null}
  client.metrics.event(
      key="lessons-completed",
      user=EventRequestUser(
          id="18",
          email="user@example.com",
          tz="Europe/London",
      ),
      value=1,
      idempotencyKey="lesson-123"
  )
  ```

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

  $request = new MetricsEventRequest([
      'user' => $user,
      'value' => 1,
      'idempotencyKey' => 'lesson-123'
  ]);

  $trophy->metrics->event("lessons-completed", $request);
  ```

  ```java Java {9} theme={null}
  MetricsEventRequest request = MetricsEventRequest.builder()
        .user(
          EventRequestUser.builder()
            .id("18")
            .email("user@example.com")
            .build()
        )
        .value(1)
        .idempotencyKey("lesson-123")
        .build();

  EventResponse response = client.metrics().event("lessons-completed", request);
  ```

  ```go Go {10} theme={null}
  response, err := client.Metrics.Event(
      "lessons-completed",
      &api.MetricsEventRequest{
          User: &api.EventRequestUser{
              Id: "18",
              Email: "user@example.com",
          },
          Value: 1,
          IdempotencyKey: "lesson-123"
      },
  )
  ```

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

  var request = new MetricsEventRequest {
     User = user,
     Value = 1,
     IdempotencyKey = "lesson-123"
  };

  await trophy.Metrics.EventAsync("lessons-completed", request);
  ```

  ```ruby Ruby {8} theme={null}
  result = client.metrics.event(
    :key => 'lessons-completed',
    :user => {
      :id => '18',
      :email => 'user@example.com'
    },
    :value => 1,
    :idempotencyKey => 'lesson-123'
  )
  ```
</CodeGroup>

Esto ayuda a mantener tu código libre de lógica que verifique si los usuarios han completado acciones anteriormente, y en su lugar puedes confiar en que Trophy mantendrá las restricciones que necesitas.

Para usar eventos idempotentes, utiliza el encabezado `Idempotency-Key` en la [API de eventos de métricas](/es/api-reference/endpoints/metrics/send-a-metric-change-event).

[Más información sobre idempotencia](/es/api-reference/idempotency).

<h3 id="parallel-events">
  Eventos Paralelos
</h3>

Trophy no admite eventos paralelos para la misma métrica del mismo usuario. En su lugar, utiliza el parámetro `value` para incrementar la métrica por la cantidad total de todos los eventos individuales que necesitas rastrear.

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

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

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

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

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

  $trophy->metrics->event("lessons-completed", $request);
  ```

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

  EventResponse response = client.metrics().event("lessons-completed", request);
  ```

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

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

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

  await trophy.Metrics.EventAsync("lessons-completed", request);
  ```

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

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

¿Quieres ponerte en contacto con el equipo de Trophy? Contáctanos por [correo electrónico](mailto:support@trophy.so). ¡Estamos aquí para ayudarte!
