Integración de Webhooks con TSplus Remote Support
Resumen
Webhooks te permiten conectar TSplus Remote Support a tus propios sistemas (ticketing, CRM, SIEM, herramientas internas). Cuando ocurre un evento en tu suscripción, Remote Support envía un HTTP
PUBLICAR
solicitud — que contiene una carga útil JSON que describe el evento — a una URL que controlas.
Cada solicitud es firmado criptográficamente para que su servidor pueda verificar que realmente proviene de Remote Support y no ha sido alterado.
Casos de uso típicos:
- Crear o actualizar automáticamente un ticket cuando finaliza una sesión de soporte.
- Archiva las transcripciones de chat de sesión en tu propio almacenamiento.
- Disparar notificaciones internas o flujos de trabajo de automatización.
Requisitos
Para configurar webhooks, asegúrate de tener:
- Una suscripción administrador cuenta.
-
Unreachable públicamente
HTTPS
punto final capaz de recibir
PUBLICARsolicitudes. - La capacidad de leer los encabezados de las solicitudes HTTP y el cuerpo de la solicitud en bruto en su servidor (requerido para verificar la firma).
Configurando un webhook
-
Abrir el TSplus Remote Support consola de administración.
-
En el menú de la izquierda, expanda Integración y haga clic Webhooks .
-
Haga clic Agregar un webhook .
-
Complete el formulario:
- URL — el punto final HTTPS que recibirá los eventos.
- Descripción opcional — una etiqueta para ayudarte a identificar este punto final.
- Eventos — seleccione al menos un tipo de evento al que suscribirse.
-
Haga clic Guardar .
-
A secreto se genera y se muestra una vez Cópialo ahora y guárdalo de forma segura; se utiliza para verificar la firma de las solicitudes entrantes y no se mostrará de nuevo.
Seguridad: Para su protección, la URL se valida cuando la guarda. Los puntos finales que apuntan a
localhosto las direcciones IP privadas/internas son rechazadas.
Gestionando tus webhooks
Desde la lista de Webhooks puedes:
- Enviar un evento de prueba (icono de frasco) — encola una entrega de muestra para que puedas confirmar que tu endpoint recibe y acepta solicitudes.
- Editar (icono de lápiz) — cambia la URL, la descripción, los eventos suscritos o habilita/deshabilita el endpoint.
- Eliminar (icono de papelera) — eliminar permanentemente el endpoint.
Cada punto final muestra un estado :
- Activo — el endpoint está habilitado y recibiendo eventos.
- Deshabilitado — el punto final fue deshabilitado manualmente.
- Auto-deshabilitado — El soporte remoto desactivó automáticamente el endpoint después de 10 entregas fallidas consecutivas Arregla el endpoint y vuelve a habilitarlo desde el formulario de edición.
Formato de carga
Cada evento se entrega como un
PUBLICAR
solicitud con un cuerpo JSON y los siguientes encabezados:
| Encabezado | Descripción |
|---|---|
Tipo de contenido
|
aplicación/json
|
X-Firma-WebHook
|
firma HMAC-SHA256 del cuerpo sin procesar, precedida por
sha256=
|
X-Webhook-Id
|
Identificador de evento único (úselo para la idempotencia de su lado) |
X-Webhook-Timestamp
|
marca de tiempo ISO 8601 de la entrega |
Agente de usuario
|
RemoteSupport-Webhook/1.0
|
Todos los eventos comparten un sobre común. Solo el contenido de
datos
cambios dependiendo del tipo de evento:
{ "id": "evt_abc123def456", "type": "session.ended", "created_at": "2026-07-10T15:00:00Z", "subscription_key": "XXXX-XXXX-XXXX", "data": { }}
sesión.terminada
Enviado cuando una sesión de soporte termina (todos los participantes desconectados). La carga útil incluye la transcripción completa del chat recopilada durante la sesión.
{ "id": "evt_xyz789ghi012", "type": "session.ended", "created_at": "2026-07-10T15:00:00Z", "subscription_key": "XXXX-XXXX-XXXX", "data": { "remote_support_id": "ABC123", "computer_name": "Front-desk PC", "started_at": "2026-07-10T14:30:00Z", "ended_at": "2026-07-10T15:00:00Z", "duration_seconds": 1800, "is_abnormal_closure": false, "chat_transcript": [ { "timestamp": "2026-07-10T14:31:00Z", "sender": "agent", "user_id": 42, "message": "Hello, how can I help you?" }, { "timestamp": "2026-07-10T14:31:30Z", "sender": "client", "message": "My screen is black" } ] }}
es_cierre_anormalesverdaderosolo cuando una sesión es cerrada por la plataforma después de un reinicio inesperado del relé. En ese caso, eltranscripción_de_chatestá vacío.
Verificando la firma
Tu endpoint siempre debe verificar la firma antes de confiar en una solicitud. Cualquiera que conozca tu URL podría enviar eventos falsos; sin el secreto, no pueden producir una firma válida.
Para verificar una solicitud:
- Lee el cuerpo de solicitud sin procesar los bytes exactos recibidos — no re-serializar el JSON).
-
Calcular
HMAC-SHA256(rawBody, yourSecret)y lo codifica en hexadecimal. -
Prefíjalo con
sha256=y compáralo con elX-Firma-WebHookencabezado utilizando una comparación de tiempo constante.
Node.js
const crypto = require('crypto');
function verifyWebhook(rawBody, signatureHeader, secret) { const expected = 'sha256=' + crypto .createHmac('sha256', secret) .update(rawBody, 'utf8') .digest('hex');
const a = Buffer.from(expected); const b = Buffer.from(signatureHeader || ''); return a.length === b.length && crypto.timingSafeEqual(a, b);}
Python
import hmacimport hashlib
def verify_webhook(raw_body: bytes, signature_header: str, secret: str) -> bool: expected = "sha256=" + hmac.new( secret.encode("utf-8"), raw_body, hashlib.sha256 ).hexdigest() return hmac.compare_digest(expected, signature_header or "")
Entrega y reintentos
- Su punto final debe responder con un 2xx código de estado lo más rápido posible. La solicitud se agota después de 10 segundos .
- Si una entrega falla, el Soporte Remoto reintenta con un programa de retroceso exponencial: 10s, 30s, 1min, 5min, 15min, 1h, 4h, 24h (hasta 8 intentos en 24 horas).
-
Los reintentos ocurren en errores de conexión, HTTP
429y5xxrespuestas. Otro4xxlas respuestas se consideran fallos permanentes y son no reintentado. - Después 10 entregas fallidas consecutivas , el punto final es automáticamente deshabilitado .
Para evitar procesar el mismo evento dos veces (por ejemplo, después de un reintento), utilice el
X-Webhook-Id
encabezado (o el
id
campo en la carga útil) como una clave de idempotencia.
Eventos disponibles
| Evento | Descripción |
|---|---|
sesión.terminada
|
Una sesión de soporte ha terminado. Incluye la duración y la transcripción completa del chat. |
Se agregarán más tipos de eventos en versiones futuras.