> ## Índice de la documentación
> Consulta el índice completo de la documentación en: https://developer.rhombus.com/llms.txt
> Úsalo para descubrir todas las páginas disponibles antes de seguir explorando.

# Webhooks de Rhombus

> Configura los webhooks de Rhombus para recibir notificaciones HTTP POST en tiempo real de alertas de cámaras, eventos de puertas, umbrales de sensores y pulsaciones de botones sin necesidad de sondeo.

> **Note**: Esta página se tradujo automáticamente. Si encuentras errores o tienes sugerencias, [escríbenos](mailto:support@rhombus.com).

Los webhooks de Rhombus entregan notificaciones HTTP POST en tiempo real a tu servidor cuando ocurren eventos: apertura de puertas, alertas de cámaras, superación de umbrales de sensores, pulsaciones de botones y más. En lugar de sondear la API, tu aplicación recibe los eventos a medida que suceden.

## Cómo funcionan los webhooks

1. **Agrega un webhook**

   Agrega una URL de webhook en la consola (**Configuración → Integraciones y recursos para desarrolladores → Webhooks**, con **Tipo de activador** **Actividad** o **Diagnóstico**) o agrega una acción de webhook a una regla.

2. **Ocurren los eventos**

   Cuando ocurre un evento suscrito en tu entorno de Rhombus (por ejemplo, una puerta se abre a la fuerza), el sistema genera una carga útil del evento.

3. **Recibe notificaciones**

   Rhombus envía una solicitud HTTP POST a tu URL registrada con los detalles del evento como una carga útil JSON.

4. **Procesa y responde**

   Tu servidor devuelve `200 OK` en pocos segundos y procesa el evento después. Rhombus no reintenta una entrega fallida; consulta [Entrega](https://developer.rhombus.com/es/webhooks#entrega).

## Tipos de eventos

Rhombus admite notificaciones por webhook para una amplia variedad de eventos en toda tu infraestructura de seguridad:

- **Eventos de cámaras**: Detección de movimiento, alertas de analítica, clips de video guardados, detecciones impulsadas por IA
- **Eventos de control de acceso**: Apertura/cierre de puertas, entrada forzada, acceso concedido/denegado, escaneos de credenciales
- **Eventos de sensores**: Alertas de umbral de temperatura, humedad y calidad del aire
- **Eventos de dispositivos**: Pulsaciones de botones, cambios de estado en línea/fuera de línea de dispositivos

## Ejemplo de carga útil de webhook

Cuando un evento dispara un webhook, Rhombus envía una solicitud POST a tu URL con una carga útil JSON. El cuerpo depende del tipo de webhook.

### Acción de webhook de una regla

```json
{
  "uuid": "event-uuid-here",
  "orgUuid": "org-uuid-here",
  "ruleUuid": "rule-uuid-here",
  "triggeredTimestampMs": 1712678400000,
  "deviceEvents": [
    {
      "eventUuid": "device-event-uuid-here",
      "deviceUuid": "camera-uuid-here",
      "deviceType": "CAMERA",
      "locationUuid": "location-uuid-here",
      "timestampMs": 1712678400000,
      "activities": ["MOTION_HUMAN"]
    }
  ],
  "ruleTriggers": [
    {
      "type": "DEVICE_ACTIVITY_EVENT"
    }
  ]
}
```

> **Note**: Esta es la carga útil de una acción de webhook en una regla. Identifica la regla que se activó (`ruleUuid`), los disparadores que coincidieron (`ruleTriggers`) y los eventos de dispositivo subyacentes (`deviceEvents`). Los campos específicos presentes dependen del tipo de evento que la activó, así que configura un endpoint de webhook de prueba para inspeccionar la carga útil completa de tus reglas.

### Webhook de organización (Actividad y Diagnóstico)

```json
{
  "version": "2",
  "activityTrigger": "MOTION_HUMAN",
  "summary": "One-line summary of the event",
  "deviceUuid": "camera-uuid-here",
  "location": "location-uuid-here",
  "deviceType": "CAMERA",
  "timestampMs": 1712678400000,
  "alertUuid": "alert-uuid-here",
  "durationSec": 10,
  "thumbnailLocation": "storage-region-here",
  "clipLocationMap": {
    "camera-uuid-here": "storage-region-here"
  }
}
```

> **Note**: Los webhooks de organización envían un objeto plano por notificación. Un webhook de Actividad incluye `activityTrigger` (separado por comas cuando se activaron varias actividades) y `alertUuid`; un webhook de Diagnóstico incluye `diagnosticTrigger` y `diagnosticUuid` en su lugar. Los campos del dispositivo, `durationSec`, `thumbnailLocation` y `clipLocationMap` solo aparecen cuando corresponden al evento.

## Entrega

Los dos tipos de webhook se entregan de forma distinta:

|                        | Acción de webhook de una regla    | Webhook de organización (Actividad o Diagnóstico)                                                                                                  |
| ---------------------- | --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| Se configura en        | La acción de webhook de una regla | **Configuración → Integraciones y recursos para desarrolladores → Webhooks**, hasta cuatro URLs por tipo de activador                              |
| Se envía cuando        | La regla se activa                | Rhombus envía una notificación de ese tipo de activador. No hay filtro de eventos por webhook: cada URL recibe todas las notificaciones de su tipo |
| Encabezados de firma   | `x-rhombus-signature-sha256`      | `x-rhombus-signature-sha256`, y también `x-rhombus-signature-sha1`                                                                                 |
| Se considera entregado | `200` o `202`                     | Cualquier `2xx`                                                                                                                                    |
| Límites de tiempo      | 2 segundos para conectar          | 5 segundos para conectar, 60 segundos para responder                                                                                               |
| Reintentos             | Ninguno                           | Ninguno                                                                                                                                            |

Rhombus hace **un solo intento de entrega**. Una entrega que falla (tu servidor no está disponible, tarda en conectar o responde con otro código) no se vuelve a enviar, y un webhook de regla fallido queda registrado como un evento de diagnóstico `EXTERNAL_WEBHOOK_FAILURE` en tu organización. Prepara tu receptor para eso:

- **Confirma primero y trabaja después.** Devuelve `200` en cuanto la firma sea válida y procesa el evento en una cola o tarea en segundo plano.
- **Concilia después de una interrupción.** Los webhooks son una vía rápida, no un registro. Si tu endpoint estuvo fuera de servicio, lee lo que te perdiste con la API, por ejemplo las alertas de políticas con [`getPolicyAlerts`](https://developer.rhombus.com/api-reference/event-webservice/get-recent-policy-alerts-for-organization) (consulta [Paginación](https://developer.rhombus.com/es/pagination#alertas-de-políticas)).
- **Elimina duplicados y ordena según la carga útil.** Usa los IDs del cuerpo (`alertUuid`, el `uuid` del evento) para ignorar repeticiones, y `timestampMs` en lugar del orden de llegada para ordenar los eventos.
- **Usa HTTPS** con un certificado de una autoridad de certificación pública.

## Verificación de firmas de webhooks

Rhombus firma las entregas de webhooks para que puedas confirmar que la solicitud proviene de Rhombus y que el cuerpo no se modificó en tránsito. Cada entrega firmada incluye `x-rhombus-signature-sha256`: el HMAC-SHA256 del cuerpo sin procesar de la solicitud, con el secreto de ese webhook como clave, en hexadecimal en minúsculas. Verifica ese encabezado.

| Tipo de webhook                                       | Dónde se configura                                                                                                                                                                                                                                                 | Encabezados de firma                                                                         |
| ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------- |
| Webhooks de la organización (Actividad y Diagnóstico) | Consola: **Configuración → Integraciones y recursos para desarrolladores → Webhooks**, o [`POST /api/integrations/webhooks/updateWebhookIntegrationV2`](https://developer.rhombus.com/api-reference/webhook-integrations-webservice/update-webhook-integration-v2) | `x-rhombus-signature-sha256` (HMAC-SHA256), y también `x-rhombus-signature-sha1` (HMAC-SHA1) |
| Acciones de webhook de reglas                         | La acción de webhook de una regla ([`POST /api/rules/createRule`](https://developer.rhombus.com/api-reference/rules-webservice/create-rule), [`POST /api/rules/updateRule`](https://developer.rhombus.com/api-reference/rules-webservice/update-rule))             | `x-rhombus-signature-sha256` (HMAC-SHA256)                                                   |

El encabezado `x-rhombus-signature-sha1` de los webhooks de la organización es un HMAC-SHA1 del mismo cuerpo con el mismo secreto. No lo necesitas si verificas `x-rhombus-signature-sha256`.

En ambos casos:

- **Contenido firmado:** los bytes exactos del cuerpo de la solicitud HTTP (JSON en UTF-8). Verifica la firma antes de analizar o volver a serializar el cuerpo.
- **Clave:** la cadena del secreto del webhook, tal cual (sus bytes en UTF-8). Los secretos son cadenas base64url de 22 caracteres. No los decodifiques.
- **Codificación:** hexadecimal en minúsculas.
- **Alcance:** solo se firma el cuerpo. No hay una marca de tiempo firmada, así que elimina entregas duplicadas con los identificadores del payload, como `alertUuid` o el `uuid` del evento.
- **Un secreto por URL:** cada URL de webhook tiene su propio secreto. Si registras varias URL, guarda el secreto de cada una.

### Encuentra tu secreto

**Webhooks de la organización.** Rhombus crea un secreto al agregar una URL de webhook, y todas las entregas de webhooks de la organización van firmadas.

- En la consola, abre **Configuración → Integraciones y recursos para desarrolladores → Webhooks** y copia el valor de la columna **Secreto del webhook**.
- Con la API, [`POST /api/integrations/webhooks/updateWebhookIntegrationV2`](https://developer.rhombus.com/api-reference/webhook-integrations-webservice/update-webhook-integration-v2) devuelve `webhookSecret` cuando agregas una `webhookUrl`.
- [`POST /api/integrations/webhooks/getWebhookIntegration`](https://developer.rhombus.com/api-reference/webhook-integrations-webservice/get-webhook-integration) devuelve el `webhookSecret` de cada URL en `orgIntegrationV2.activityWebhooksV2` y `orgIntegrationV2.diagnosticWebhooksV2`.

**Acciones de webhook de reglas.** Al crear o actualizar una regla con acciones de webhook, la respuesta incluye `webhookSecrets`, un mapa de cada URL de webhook a su secreto. Guárdalo de forma segura.

- Actualizar una regla conserva el secreto de las URL que ya tienen uno y crea un secreto para las URL nuevas.
- Rhombus siempre genera estos secretos. Un secreto enviado en la solicitud se ignora.
- Una acción de webhook sin secreto se entrega sin encabezado de firma. Actualiza la regla para asignarle uno.

### Verifica una solicitud

1. Lee el cuerpo sin procesar de la solicitud como bytes, antes de analizar el JSON.
2. Lee el encabezado `x-rhombus-signature-sha256`.
3. Calcula el HMAC-SHA256 del cuerpo sin procesar con tu secreto, codifícalo en hexadecimal en minúsculas y compáralo con el encabezado **en tiempo constante**.
4. Si falta el encabezado o no coincide, responde `401` y descarta la solicitud. Si coincide, procesa el evento y devuelve `200 OK` rápidamente. Las acciones de webhook de reglas solo consideran entregados los códigos `200` y `202`.

```python Python (Flask)
import hashlib
import hmac
import os

from flask import Flask, abort, request

app = Flask(__name__)
WEBHOOK_SECRET = os.environ["RHOMBUS_WEBHOOK_SECRET"]


def rhombus_signature_is_valid(raw_body: bytes, signature: str, secret: str) -> bool:
    expected = hmac.new(secret.encode("utf-8"), raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, signature.strip().lower())  # tiempo constante


@app.post("/rhombus-webhook")
def rhombus_webhook():
    raw_body = request.get_data()  # bytes sin procesar, tal como se enviaron
    signature = request.headers.get("x-rhombus-signature-sha256", "")  # vacío si no hay firma
    if not rhombus_signature_is_valid(raw_body, signature, WEBHOOK_SECRET):
        abort(401)
    event = request.get_json()
    # ... procesa el evento ...
    return "", 200
```

```javascript Node.js (Express)
const crypto = require("crypto");
const express = require("express");

const app = express();
const WEBHOOK_SECRET = process.env.RHOMBUS_WEBHOOK_SECRET;

function rhombusSignatureIsValid(rawBody, signature, secret) {
  if (!signature) return false; // solicitud sin firma
  const expected = Buffer.from(crypto.createHmac("sha256", secret).update(rawBody).digest("hex"), "utf8");
  const received = Buffer.from(signature.trim().toLowerCase(), "utf8");
  return expected.length === received.length && crypto.timingSafeEqual(expected, received); // tiempo constante
}

// express.raw conserva el cuerpo como Buffer para que los bytes coincidan con lo que firmó Rhombus.
app.post("/rhombus-webhook", express.raw({ type: "application/json" }), (req, res) => {
  if (!rhombusSignatureIsValid(req.body, req.get("x-rhombus-signature-sha256"), WEBHOOK_SECRET)) {
    return res.sendStatus(401);
  }
  const event = JSON.parse(req.body.toString("utf8"));
  // ... procesa el evento ...
  res.sendStatus(200);
});

app.listen(8080);
```

> **Tip**: Para probar tu implementación, usa el secreto `AAAAAAAAAAAAAAAAAAAAAA` y el cuerpo `{"version":"2","summary":"Test webhook"}`. El `x-rhombus-signature-sha256` esperado es `5d3808f7c72ed8b6e52c12cf3ae13e72667d316178c6110081d58282828b2482` y el `x-rhombus-signature-sha1` esperado es `7c67f32d7b1320f76fa6d171a1a54dd6808570b6`.

## Administrar webhooks vía la API

Los webhooks de la organización se administran con las operaciones de Webhook Integrations:

- [`getWebhookIntegration`](https://developer.rhombus.com/api-reference/webhook-integrations-webservice/get-webhook-integration) lee las URLs configuradas.
- [`updateWebhookIntegrationV2`](https://developer.rhombus.com/api-reference/webhook-integrations-webservice/update-webhook-integration-v2) define las URLs de cada tipo de activador (Actividad o Diagnóstico).
- [`deleteWebhookIntegrationV2`](https://developer.rhombus.com/api-reference/webhook-integrations-webservice/delete-webhook-integration-v2) las elimina.

Cada URL recibe todas las notificaciones de su tipo de activador; no hay filtro que configurar. Las acciones de webhook de reglas pertenecen a su regla y se administran con las operaciones de Rules de la [referencia de la API](https://developer.rhombus.com/api-reference/overview) (en inglés).

## Guía de implementación

[Receptores de webhooks](https://developer.rhombus.com/es/implementations/webhook-listener) construye un receptor completo: verificación de la firma sobre el cuerpo sin procesar, encolado, acceso a sistemas de una red privada sin abrirla a internet y pruebas locales.

## Alternativas sin código

Si prefieres un creador de flujos de trabajo visual en lugar de escribir manejadores de webhook personalizados, Rhombus se integra con:

- [Zapier](https://developer.rhombus.com/es/low-code-no-code/zapier) — disparadores instantáneos para eventos de reglas, pulsaciones de botones, eventos de puertas y alertas de sensores
- [Make.com](https://developer.rhombus.com/es/low-code-no-code/make) — disparadores de webhook con enrutamiento avanzado de datos
- [n8n](https://developer.rhombus.com/es/low-code-no-code/n8n) — procesamiento de webhooks autoalojado con capacidades de agente de IA
