Wiki
Webhooks
Notificaciones salientes por repositorio (Discord, Slack, Teams, custom) en check-in, check-out y resúmenes de actividad. Creación, formato de los mensajes, variables de plantilla, protección SSRF.
Introducción
Un webhook envía una notificación saliente a un servicio externo (Discord, Slack, Microsoft Teams, o una URL de tu elección) cada vez que ocurre un evento en un repositorio: un check-in, un check-out, o un resumen de actividad periódico. Es la forma más sencilla de mantener a un equipo al tanto sin que abra el cliente: un mensaje cae en tu canal cuando alguien envía trabajo.
Los webhooks se configuran por repositorio, en el panel de administración del cliente de escritorio, en la pestaña Webhooks. Un repositorio puede tener varios webhooks (por ejemplo uno a Discord para todo el equipo, uno a un Slack privado para los leads).
Acceso y roles
La gestión de los webhooks está reservada a los administradores del repositorio: un super admin
(rol admin) en cualquier repositorio, o un project_admin en los repositorios
que administra. Los demás roles no ven esta pestaña.
Crear un webhook
- Abre el panel de administración, selecciona el repositorio y luego la pestaña Webhooks.
- Haz clic en Add Webhook.
- Completa los campos y luego Create.
| Campo | Valor |
|---|---|
| Name | Una etiqueta para reconocerlo (p. ej. Discord équipe). Obligatorio. |
| URL | La URL del webhook proporcionada por el servicio de destino. Obligatoria. Consulta Seguridad para las URL rechazadas. |
| Type | discord, slack, teams o custom. |
| Events | Uno o varios de checkin, checkout, activity_summary. Al menos uno es obligatorio. |
| Enabled | Interruptor de activación (visible al editar y desde la lista). |
Para obtener la URL en el lado de Discord: Configuración del canal → Integraciones → Webhooks → Nuevo webhook → Copiar URL del webhook. En el lado de Slack: crea un Incoming Webhook en los ajustes de la aplicación de Slack. En el lado de Teams: Conectores → Incoming Webhook en el canal.
Tutorial: webhook de Discord
Es el caso más común. La parte de «obtener la URL» ocurre íntegramente dentro de Discord, una sola vez.
En el lado de Discord: obtener la URL
- Abre Discord y ve a tu servidor. Elige (o crea) el canal de texto que recibirá las notificaciones, por ejemplo
#uversion. - Pasa el ratón sobre el nombre del canal y haz clic en el icono de engranaje («Editar canal»).
- En el menú de la izquierda, abre la pestaña Integraciones.
- Haz clic en Webhooks y luego en Nuevo webhook. Discord crea uno automáticamente, vinculado a este canal.
- Haz clic en el webhook creado para abrirlo. Ponle un nombre (por ejemplo
uVersion) y comprueba que el canal de destino es el correcto. La imagen de avatar es opcional. - Haz clic en Copiar URL del webhook. La URL se parece a
https://discord.com/api/webhooks/123456789/AbCdEf....
En el lado de uVersion: conectar la URL
- En el cliente de escritorio, abre el panel de administración, selecciona el repositorio y luego la pestaña Webhooks.
- Haz clic en Add Webhook.
- Name: una etiqueta para ti (p. ej.
Discord équipe). - URL: pega la URL copiada desde Discord.
- Type: elige
discord(imprescindible para que el mensaje se formatee como embed de Discord). - Events: marca los eventos deseados, por ejemplo
checkin. - Haz clic en Create.
- En la fila del webhook, haz clic en Send test: un mensaje de prueba debería aparecer en el canal de Discord en unos segundos.
Si la prueba falla con un código HTTP 401 o 404, la URL es incorrecta o el webhook se
eliminó en el lado de Discord: vuelve a copiar la URL. Si no llega nada aunque la prueba esté en verde, comprueba que estás mirando
el canal correcto y que el webhook no ha sido desactivado en Discord.
Tipos y formatos
El Type determina cómo uVersion formatea el mensaje antes de enviarlo. Elige el que corresponda al servicio al que apunta la URL, de lo contrario el mensaje llegará mal formateado (o será rechazado por el servicio).
| Type | Formato enviado |
|---|---|
discord | Embed de Discord (título, color, campos). |
slack | Payload de Slack (bloques de mensaje). |
teams | Tarjeta de Microsoft Teams (MessageCard). |
custom | Cuerpo JSON definido íntegramente por ti: consulta Webhooks personalizados. |
Eventos
| Evento | Se dispara cuando… |
|---|---|
checkin | Un usuario envía un commit al repositorio. |
checkout | Un usuario bloquea (check-out) uno o varios archivos. |
activity_summary | El planificador del servidor produce un resumen de actividad periódico (diario / semanal). |
Marca solo lo que tu canal necesita. En un estudio grande, checkout puede ser ruidoso:
muchos equipos solo conservan checkin y activity_summary.
Webhooks personalizados
Con el tipo custom aparecen dos campos adicionales: Custom Headers (JSON)
y Custom Template (JSON). Permiten integrar cualquier servicio que acepte un POST JSON.
Template
La plantilla es el cuerpo JSON enviado. uVersion reemplaza en ella las variables entre dobles llaves por los valores del evento. Ejemplo:
{"text": "{{event_type}} par {{username}} dans {{repository}}"}
Variables disponibles:
| Variable | Contenido |
|---|---|
{{event_type}} | Tipo de evento (checkin, checkout, activity_summary). |
{{repository}} | Nombre del repositorio. |
{{username}} | Usuario que originó el evento. |
{{message}} | Mensaje de commit (para un check-in). |
{{file_count}} | Número de archivos afectados. |
{{commit_hash}} | Hash del commit. |
{{timestamp}} | Marca de tiempo del evento. |
Headers
Un objeto JSON de encabezados HTTP para adjuntar a la solicitud, por ejemplo un token de autenticación:
{"Authorization": "Bearer VOTRE_JETON"}
Por defecto {} (ningún encabezado). Los encabezados reservados al transporte
(host, content-length, transfer-encoding, connection)
se eliminan automáticamente y no pueden sobrescribirse.
Probar, activar, eliminar
Cada webhook de la lista ofrece las siguientes acciones:
- Send test (icono de avión): envía una notificación de prueba al servicio y muestra un resultado en línea (marca verde o cruz). Útil para verificar la URL y el tipo antes de depender de él.
- Interruptor: activa / desactiva el webhook sin eliminarlo.
- Edit: modificar cualquier campo.
- Delete: eliminación definitiva (se pide confirmación).
Seguridad: protección SSRF
Un webhook hace que sea el servidor quien emita una solicitud HTTP. Para evitar que una URL maliciosa sirva para sondear la red interna del servidor (ataque SSRF), uVersion aplica una protección estricta en la creación, en la modificación y en la prueba:
- El esquema debe ser
httpohttps. Cualquier otro esquema se rechaza. - El nombre de host se resuelve por DNS, y se verifica cada dirección IP obtenida. El webhook
se rechaza si alguna apunta a una dirección no pública: loopback, redes privadas (RFC1918), link-local,
broadcast, rango CGNAT
100.64.0.0/10, metadatos de nube169.254.169.254, ULA / link-local IPv6, y sus equivalentes IPv4-mapped-IPv6. - No se siguen las redirecciones HTTP (por lo que un 307 a un host interno no puede eludir la protección).
- El cuerpo de la respuesta de origen nunca se devuelve al cliente (sin oráculo SSRF).
En la práctica: una URL de webhook debe apuntar a un servicio público (Discord, Slack, Teams, o
tu propio endpoint accesible desde Internet). Una URL a localhost, una IP privada
(10.x, 192.168.x, 172.16-31.x) o un servicio interno se rechaza con un
mensaje «Webhook URL refused: …».
Errores frecuentes
El tipo no corresponde al servicio
Enviar un formato de Discord a una URL de Slack (o al revés) produce un mensaje mal formateado o un rechazo en el lado del servicio. El campo Type debe corresponder a la URL. En caso de duda, haz un Send test.
Ningún evento marcado
Un webhook sin evento nunca se dispara. El cliente bloquea el guardado mientras no haya ningún evento seleccionado («At least one event is required»).
URL interna rechazada
Si pruebas contra un servicio en tu propia máquina o tu LAN, la protección SSRF lo rechaza. Expón el servicio en una URL pública (o un túnel) para usarlo como destino de webhook.
Webhook desactivado olvidado
Un webhook desactivado permanece en la lista pero no envía nada. Si las notificaciones se han quedado en silencio, comprueba primero el interruptor de activación antes de sospechar de la URL.