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

# Eventos de Webhook de Reglas

> Reciba notificaciones en tiempo real cuando se activan reglas de cumplimiento — con eventos webhook de gu1 para integración downstream en tiempo real.

## Descripción General

Los eventos de webhook de reglas le permiten recibir notificaciones en tiempo real cuando se activan reglas de cumplimiento o negocio para entidades en la plataforma Gu1. Estos eventos le permiten automatizar acciones de cumplimiento, alertar a su equipo y mantener registros de auditoría cuando se detectan condiciones de riesgo.

## ¿Por Qué Usar Eventos de Reglas?

<CardGroup cols={2}>
  <Card title="Cumplimiento en Tiempo Real" icon="gavel">
    Reciba alertas instantáneas cuando se activen reglas de riesgo
  </Card>

  <Card title="Acciones Automatizadas" icon="robot">
    Bloquee, marque o escale entidades automáticamente
  </Card>

  <Card title="Registro de Auditoría" icon="clipboard-list">
    Rastree todas las activaciones de reglas para informes de cumplimiento
  </Card>

  <Card title="Gestión de Riesgos" icon="shield-halved">
    Responda a condiciones de alto riesgo inmediatamente
  </Card>
</CardGroup>

## Eventos Disponibles

### rule.triggered

El evento `rule.triggered` se dispara cuando una regla de cumplimiento o negocio se evalúa como verdadera para una entidad.

**Cuándo se dispara**:

* Se cumple una condición de regla durante creación o actualización de entidad
* La evaluación periódica de reglas detecta una coincidencia
* Las reglas de monitoreo de transacciones identifican actividad sospechosa
* Las verificaciones de cumplimiento (PEP, sanciones, medios adversos) devuelven coincidencias positivas

**Filtros disponibles**:

* `ruleIds`: Solo recibe eventos para reglas específicas
* `ruleSeverity`: Filtrar por nivel de severidad (low, medium, high, critical)
* `entityTypes`: Filtrar por tipo de entidad

## Payload del Evento

### Payload de rule.triggered

```json theme={null}
{
  "event": "rule.triggered",
  "timestamp": "2025-01-07T14:00:00.000Z",
  "payload": {
    "ruleId": "550e8400-e29b-41d4-a716-446655440000",
    "rule": {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "High Risk Country Check",
      "description": "Flags entities from high-risk countries",
      "severity": "high",
      "category": "geographic_risk",
      "isActive": true
    },
    "entityId": "123e4567-e89b-12d3-a456-426614174000",
    "entity": {
      "id": "123e4567-e89b-12d3-a456-426614174000",
      "externalId": "customer_xyz789",
      "name": "John Doe",
      "type": "person",
      "countryCode": "KP",
      "status": "blocked"
    },
    "evaluationId": "eval_abc123",
    "triggerData": {
      "countryCode": "KP",
      "riskLevel": "critical",
      "matchedCriteria": [
        "sanctioned_country",
        "high_risk_jurisdiction"
      ],
      "additionalInfo": {
        "sanctionList": ["OFAC", "UN"],
        "riskScore": 95
      }
    },
    "action": {
      "type": "block",
      "reason": "Entity from sanctioned country",
      "automaticAction": true,
      "previousStatus": "under_review",
      "newStatus": "blocked"
    },
    "triggeredAt": "2025-01-07T14:00:00.000Z"
  }
}
```

### Campos Clave del Payload

<ResponseField name="ruleId" type="string">
  Identificador único de la regla activada
</ResponseField>

<ResponseField name="rule" type="object">
  Información completa de la regla incluyendo nombre, descripción, severidad y categoría
</ResponseField>

<ResponseField name="rule.severity" type="string">
  Nivel de severidad: `low`, `medium`, `high`, o `critical`
</ResponseField>

<ResponseField name="entityId" type="string">
  La entidad que activó la regla
</ResponseField>

<ResponseField name="entity" type="object">
  Información completa de la entidad incluyendo su `externalId`
</ResponseField>

<ResponseField name="evaluationId" type="string">
  Identificador único para esta evaluación de regla
</ResponseField>

<ResponseField name="triggerData" type="object">
  Datos que causaron que la regla se activara, incluyendo criterios coincidentes y puntuaciones de riesgo
</ResponseField>

<ResponseField name="action" type="object">
  Acción tomada como resultado de la activación de regla (opcional)
</ResponseField>

<ResponseField name="action.type" type="string">
  Tipo de acción: `block`, `flag`, `review`, `alert`, o `none`
</ResponseField>

<ResponseField name="action.automaticAction" type="boolean">
  Si la acción fue tomada automáticamente por Gu1
</ResponseField>

## Categorías de Reglas y Ejemplos

### Reglas de Riesgo Geográfico

Se activan cuando las entidades son de países o jurisdicciones de alto riesgo:

```json theme={null}
{
  "rule": {
    "name": "Sanctioned Country Check",
    "category": "geographic_risk",
    "severity": "critical"
  },
  "triggerData": {
    "countryCode": "IR",
    "sanctionList": ["OFAC", "EU"],
    "riskLevel": "critical"
  },
  "action": {
    "type": "block",
    "automaticAction": true
  }
}
```

### Reglas PEP (Persona Políticamente Expuesta)

Se activan cuando la entidad coincide con bases de datos PEP:

```json theme={null}
{
  "rule": {
    "name": "PEP Screening",
    "category": "pep_check",
    "severity": "high"
  },
  "triggerData": {
    "pepStatus": "confirmed",
    "position": "Former Government Official",
    "country": "XX",
    "matchConfidence": 0.95,
    "source": "World-Check"
  },
  "action": {
    "type": "review",
    "automaticAction": true
  }
}
```

### Reglas de Detección de Sanciones

Se activan cuando la entidad aparece en listas de sanciones:

```json theme={null}
{
  "rule": {
    "name": "OFAC Sanctions Screening",
    "category": "sanctions",
    "severity": "critical"
  },
  "triggerData": {
    "matchType": "exact",
    "sanctionList": "OFAC SDN",
    "matchedName": "John Doe",
    "listingDate": "2020-01-15",
    "program": "Counter Terrorism"
  },
  "action": {
    "type": "block",
    "automaticAction": true
  }
}
```

## Configuración de Filtros

### Filtrar por ID de Regla

Solo reciba eventos para reglas específicas:

```json theme={null}
{
  "eventTypes": ["rule.triggered"],
  "filters": {
    "ruleIds": [
      "rule_sanctions_ofac",
      "rule_high_risk_country"
    ]
  }
}
```

### Filtrar por Severidad

Solo reciba alertas de severidad alta y crítica:

```json theme={null}
{
  "eventTypes": ["rule.triggered"],
  "filters": {
    "ruleSeverity": ["high", "critical"]
  }
}
```

### Filtrar por Tipo de Entidad

Solo reciba reglas activadas para personas:

```json theme={null}
{
  "eventTypes": ["rule.triggered"],
  "filters": {
    "entityTypes": ["person"]
  }
}
```

## Ejemplos de Código

### Node.js - Manejo de Eventos de Reglas

```javascript theme={null}
const express = require('express');
const app = express();

app.use(express.json({
  verify: (req, res, buf) => {
    req.rawBody = buf.toString('utf8');
  }
}));

app.post('/webhooks/rules', async (req, res) => {
  try {
    // Verificar firma (ver guía de seguridad)
    if (!verifySignature(req.rawBody, req.headers['x-webhook-signature'])) {
      return res.status(401).json({ error: 'Invalid signature' });
    }

    const { event, payload } = req.body;

    if (event === 'rule.triggered') {
      await handleRuleTriggered(payload);
    }

    res.status(200).json({ success: true });
  } catch (error) {
    console.error('Webhook error:', error);
    res.status(500).json({ error: error.message });
  }
});

async function handleRuleTriggered(payload) {
  const { rule, entity, triggerData, action, evaluationId } = payload;

  console.log(`Rule triggered: ${rule.name} for ${entity.name}`);

  // Registrar activación de regla
  await db.ruleTriggers.create({
    data: {
      ruleId: rule.id,
      ruleName: rule.name,
      entityId: entity.id,
      externalId: entity.externalId,
      severity: rule.severity,
      triggerData,
      evaluationId,
      triggeredAt: new Date()
    }
  });

  // Manejar según severidad
  switch (rule.severity) {
    case 'critical':
      await handleCriticalRule(rule, entity, triggerData, action);
      break;

    case 'high':
      await handleHighSeverityRule(rule, entity, triggerData, action);
      break;

    case 'medium':
      await handleMediumSeverityRule(rule, entity, triggerData, action);
      break;

    case 'low':
      await handleLowSeverityRule(rule, entity, triggerData, action);
      break;
  }

  // Manejar según tipo de acción
  if (action) {
    switch (action.type) {
      case 'block':
        await handleBlockAction(entity, action);
        break;

      case 'review':
        await handleReviewAction(entity, rule, action);
        break;

      case 'flag':
        await handleFlagAction(entity, rule, action);
        break;

      case 'alert':
        await handleAlertAction(entity, rule, action);
        break;
    }
  }
}

async function handleCriticalRule(rule, entity, triggerData, action) {
  console.log(`🚨 CRITICAL: ${rule.name} triggered for ${entity.name}`);

  // Bloquear entidad inmediatamente si aún no está bloqueada
  if (entity.status !== 'blocked') {
    await blockEntity(entity.id, rule.name);
  }

  // Alertar al equipo de cumplimiento inmediatamente
  await slack.send({
    channel: '#compliance-critical',
    priority: 'critical',
    message: `🚨 CRITICAL RULE TRIGGERED`,
    fields: {
      'Rule': rule.name,
      'Entity': entity.name,
      'External ID': entity.externalId,
      'Severity': rule.severity,
      'Action Taken': action?.type || 'none',
      'Details': JSON.stringify(triggerData, null, 2)
    }
  });

  // Crear caso de alta prioridad
  await compliance.createCase({
    entityId: entity.id,
    ruleId: rule.id,
    priority: 'critical',
    type: 'rule_trigger',
    data: { rule, entity, triggerData, action },
    assignTo: 'compliance-lead'
  });
}

app.listen(3000);
```

### Python - Manejo de Eventos de Reglas

```python theme={null}
from flask import Flask, request, jsonify
import logging

app = Flask(__name__)

@app.route('/webhooks/rules', methods=['POST'])
def rules_webhook():
    try:
        # Verificar firma (ver guía de seguridad)
        signature = request.headers.get('X-Webhook-Signature')
        raw_body = request.get_data(as_text=True)

        if not verify_signature(raw_body, signature):
            return jsonify({'error': 'Invalid signature'}), 401

        # Analizar webhook
        payload = request.json
        event = payload['event']
        data = payload['payload']

        if event == 'rule.triggered':
            handle_rule_triggered(data)

        return jsonify({'success': True}), 200

    except Exception as e:
        logging.error(f'Webhook error: {e}')
        return jsonify({'error': str(e)}), 500

def handle_rule_triggered(data):
    rule = data['rule']
    entity = data['entity']
    trigger_data = data['triggerData']
    action = data.get('action')

    logging.info(f"Rule triggered: {rule['name']} for {entity['name']}")

    # Registrar activación
    db.rule_triggers.insert({
        'rule_id': rule['id'],
        'rule_name': rule['name'],
        'entity_id': entity['id'],
        'external_id': entity['externalId'],
        'severity': rule['severity'],
        'trigger_data': trigger_data,
        'evaluation_id': data['evaluationId']
    })

    # Manejar según severidad
    severity_handlers = {
        'critical': handle_critical_rule,
        'high': handle_high_severity_rule,
        'medium': handle_medium_severity_rule,
        'low': handle_low_severity_rule
    }

    handler = severity_handlers.get(rule['severity'])
    if handler:
        handler(rule, entity, trigger_data, action)

def handle_critical_rule(rule, entity, trigger_data, action):
    logging.critical(f"CRITICAL: {rule['name']} triggered for {entity['name']}")

    # Bloquear entidad
    if entity['status'] != 'blocked':
        block_entity(entity['id'], rule['name'])

    # Alertar equipo
    slack.send({
        'channel': '#compliance-critical',
        'message': f"🚨 CRITICAL RULE TRIGGERED: {rule['name']}",
        'fields': {
            'Entity': entity['name'],
            'External ID': entity['externalId'],
            'Severity': rule['severity']
        }
    })

if __name__ == '__main__':
    app.run(port=3000)
```

## Mejores Prácticas

<AccordionGroup>
  <Accordion title="Almacene Activaciones de Reglas para Auditoría">
    Siempre registre activaciones de reglas para registros de auditoría de cumplimiento:

    ```javascript theme={null}
    await db.ruleTriggers.create({
      data: {
        ruleId: rule.id,
        entityId: entity.id,
        evaluationId: evaluationId,
        triggerData,
        triggeredAt: new Date(),
        webhook: req.body
      }
    });
    ```
  </Accordion>

  <Accordion title="Maneje la Severidad Apropiadamente">
    Implemente diferentes flujos de trabajo según la severidad:

    * **Critical**: Bloqueo inmediato + alertas urgentes
    * **High**: Marcar para revisión + notificar equipo de cumplimiento
    * **Medium**: Cola para revisión periódica
    * **Low**: Solo registrar + informes agregados
  </Accordion>

  <Accordion title="Implemente Idempotencia">
    Use ID de evaluación para prevenir procesamiento duplicado:

    ```javascript theme={null}
    const processed = await db.webhookLog.findUnique({
      where: { evaluationId: payload.evaluationId }
    });

    if (processed) {
      return; // Omitir duplicado
    }
    ```
  </Accordion>
</AccordionGroup>

## Próximos Pasos

<CardGroup cols={2}>
  <Card title="Eventos de Entidades" icon="user" href="/es/webhooks/events/entity-events">
    Maneje eventos del ciclo de vida de entidades
  </Card>

  <Card title="Eventos KYC" icon="id-card" href="/es/webhooks/events/kyc-events">
    Procese eventos de verificación KYC
  </Card>

  <Card title="Seguridad de Webhooks" icon="shield" href="/es/webhooks/security">
    Asegure sus endpoints de webhook
  </Card>

  <Card title="Configuración" icon="gear" href="/es/webhooks/configuration">
    Configure ajustes de webhook
  </Card>
</CardGroup>
