Wiki
Webhooks
Notifications sortantes par dépôt (Discord, Slack, Teams, custom) sur les check-in et les résumés d'activité. Création, format des messages, variables de template, garde SSRF.
Introduction
Un webhook envoie une notification sortante vers un service externe (Discord, Slack, Microsoft Teams, ou une URL de votre choix) chaque fois qu'un événement se produit dans un dépôt (un projet versionné sur le serveur) : un check-in, ou un résumé d'activité périodique. C'est le moyen le plus simple de tenir une équipe au courant sans qu'elle ouvre le client : un message tombe dans votre canal quand quelqu'un soumet du travail.
Les webhooks sont configurés par dépôt, dans le panneau d'administration du client desktop, onglet Webhooks. Un dépôt peut avoir plusieurs webhooks (par exemple un vers Discord pour toute l'équipe, un vers un Slack privé pour les leads).
Accès et rôles
La gestion des webhooks est réservée aux administrateurs du dépôt : un super admin
(rôle admin) sur n'importe quel dépôt, ou un project_admin sur les dépôts
qu'il administre. Les autres rôles ne voient pas cet onglet.
Créer un webhook
1. Ouvrir l'onglet Webhooks
Dans le panneau d'administration, choisissez d'abord le dépôt dans le sélecteur de la rangée PROJECT, puis ouvrez l'onglet Webhooks de cette même rangée : un webhook appartient à un dépôt. Un dépôt qui n'en a aucun affiche No webhooks configured.
2. Ouvrir le formulaire
Cliquez sur Add Webhook, en haut à droite de l'onglet. La fenêtre Create Webhook s'ouvre, vide.
3. Renseigner les champs
Deux champs sont obligatoires, Name et URL, et au moins un événement doit être sélectionné dans Events (ce sont des pastilles cliquables, pas une liste déroulante). Le Type doit correspondre au service que l'URL désigne.
| Champ | Valeur |
|---|---|
| Name | Un libellé pour vous y retrouver (ex. Discord équipe). Requis. |
| URL | L'URL du webhook fournie par le service cible. Requise. Voir Sécurité pour les URLs refusées. |
| Type | discord, slack, teams ou custom. |
| Events | Au moins un est obligatoire. En pratique : checkin et activity_summary. Voir Événements au sujet de checkout. |
| Enabled | Interrupteur d'activation (visible à l'édition, et depuis la liste). |
Pour obtenir l'URL côté Discord : Paramètres du salon → Intégrations → Webhooks → Nouveau webhook → Copier l'URL, détaillé dans le tutoriel ci-dessous. Côté Slack : créez une Incoming Webhook dans les réglages de l'application Slack. Côté Teams : Connecteurs → Incoming Webhook sur le canal.
4. Valider, puis envoyer un test
Cliquez sur Create Webhook. Le webhook apparaît dans la liste, actif. Sur sa ligne, cliquez l'icône avion Send test : uVersion envoie une notification de test au service et affiche le résultat au bout de la ligne, une coche verte ou une croix avec le code HTTP renvoyé. Faites-le maintenant : c'est le seul moyen de savoir que l'URL et le type sont bons avant de compter sur ce webhook.
Tutoriel : webhook Discord
C'est le cas le plus courant. La partie « obtenir l'URL » se passe entièrement dans Discord, une seule fois.
Côté Discord : obtenir l'URL
- Ouvrez Discord et allez sur votre serveur. Choisissez (ou créez) le salon texte qui recevra les notifications, par exemple
#uversion. - Passez la souris sur le nom du salon et cliquez sur l'icône roue dentée (« Modifier le salon »).
- Dans le menu de gauche, ouvrez l'onglet Intégrations.
- Cliquez sur Webhooks, puis sur Nouveau webhook. Discord en crée un automatiquement, rattaché à ce salon.
- Cliquez sur le webhook créé pour l'ouvrir. Donnez-lui un nom (par exemple
uVersion), et vérifiez que le salon cible est le bon. Une image d'avatar est facultative. - Cliquez sur Copier l'URL du webhook. L'URL ressemble à
https://discord.com/api/webhooks/123456789/AbCdEf....
Côté uVersion : brancher l'URL
Déroulez la procédure Créer un webhook ci-dessus avec ces valeurs :
Name un libellé pour vous (ex. Discord équipe), URL celle que vous
venez de copier, Type discord (indispensable pour que le message parte en embed
Discord), Events checkin. Terminez par Send test : un message doit
apparaître dans le salon Discord en quelques secondes.
Si le test échoue avec un code HTTP 401 ou 404, l'URL est mauvaise ou le webhook a été
supprimé côté Discord : recopiez l'URL. Si rien n'arrive alors que le test est vert, vérifiez que vous regardez
le bon salon et que le webhook n'a pas été désactivé dans Discord.
Types et formats
Le Type détermine comment uVersion met en forme le message avant de l'envoyer. Choisissez celui qui correspond au service pointé par l'URL, sinon le message arrivera mal formaté (ou sera rejeté par le service).
| Type | Format envoyé |
|---|---|
discord | Embed Discord (titre, couleur, champs). |
slack | Payload Slack (blocs de message). |
teams | Carte Microsoft Teams (MessageCard). |
custom | Corps JSON entièrement défini par vous : voir Webhooks personnalisés. |
Événements
Deux événements sont réellement émis par le serveur :
| Événement | Se déclenche quand… |
|---|---|
checkin | Un utilisateur soumet un commit dans le dépôt. |
activity_summary | Un résumé d'activité périodique est produit par le planificateur du serveur (quotidien / hebdomadaire). |
checkout : case présente, événement jamais émis
Le formulaire propose une troisième case, checkout, censée signaler le verrouillage d'un fichier
(un verrou est la réservation qu'un utilisateur pose sur un fichier pendant qu'il le modifie).
Elle est déclarée mais jamais émise à ce jour : la cocher ne provoquera aucune notification.
Ne comptez pas dessus, et ne l'utilisez pas comme seule sélection : un webhook n'ayant que cet événement coché
restera silencieux pour toujours.
Cochez uniquement ce dont votre canal a besoin. En pratique, la combinaison utile est checkin pour
le fil de travail de l'équipe, et activity_summary pour un point périodique.
Webhooks personnalisés
Avec le type custom, deux champs supplémentaires apparaissent : Custom Headers (JSON)
et Custom Template (JSON). Ils permettent d'intégrer n'importe quel service qui accepte un POST JSON.
Template
Le template est le corps JSON envoyé. uVersion y remplace les variables entre doubles accolades par les valeurs de l'événement. Exemple :
{"text": "{{event_type}} par {{username}} dans {{repository}}"}
Variables disponibles :
| Variable | Contenu |
|---|---|
{{event_type}} | Type d'événement (checkin ou activity_summary). |
{{repository}} | Nom du dépôt. |
{{username}} | Utilisateur à l'origine de l'événement. |
{{message}} | Message de commit (pour un check-in). |
{{file_count}} | Nombre de fichiers concernés. |
{{commit_hash}} | Hash du commit. |
{{timestamp}} | Horodatage de l'événement. |
Headers
Un objet JSON d'en-têtes HTTP à joindre à la requête, par exemple un jeton d'authentification :
{"Authorization": "Bearer VOTRE_JETON"}
Par défaut {} (aucun en-tête). Les en-têtes réservés au transport
(host, content-length, transfer-encoding, connection)
sont retirés automatiquement et ne peuvent pas être surchargés.
Tester, activer, supprimer
Chaque webhook de la liste propose les actions suivantes :
- Send test (icône avion) : envoie une notification de test au service et affiche un résultat en ligne (coche verte ou croix). Utile pour vérifier l'URL et le type avant de compter dessus.
- Interrupteur : active / désactive le webhook sans le supprimer.
- Edit : modifier n'importe quel champ.
- Delete : suppression définitive (confirmation demandée).
Sécurité : garde SSRF
Un webhook fait émettre une requête HTTP par le serveur. Pour éviter qu'une URL malveillante ne serve à sonder le réseau interne du serveur (attaque SSRF), uVersion applique une garde stricte à la création, à la modification et au test :
- Le schéma doit être
httpouhttps. Tout autre schéma est refusé. - Le nom d'hôte est résolu en DNS, et chaque adresse IP obtenue est vérifiée. Le webhook
est refusé si l'une pointe vers une adresse non publique : loopback, réseaux privés (RFC1918), link-local,
broadcast, plage CGNAT
100.64.0.0/10, métadonnées cloud169.254.169.254, ULA / link-local IPv6, et leurs équivalents IPv4-mapped-IPv6. - Les redirections HTTP ne sont pas suivies (une 307 vers un hôte interne ne peut donc pas contourner la garde).
- Le corps de la réponse amont n'est jamais renvoyé au client (pas d'oracle SSRF).
En pratique : une URL de webhook doit pointer vers un service public (Discord, Slack, Teams, ou
votre propre endpoint accessible depuis Internet). Une URL vers localhost, une IP privée
(10.x, 192.168.x, 172.16-31.x) ou un service interne est refusée avec un
message « Webhook URL refused: … ».
Pièges courants
Le type ne correspond pas au service
Envoyer un format Discord à une URL Slack (ou l'inverse) produit un message mal formaté ou un rejet côté service. Le champ Type doit correspondre à l'URL. Dans le doute, faites un Send test.
Aucun événement coché
Un webhook sans événement ne se déclenche jamais. Le client bloque la sauvegarde tant qu'aucun événement n'est sélectionné (« At least one event is required »).
URL interne refusée
Si vous testez contre un service sur votre propre machine ou votre LAN, la garde SSRF le refuse. Exposez le service sur une URL publique (ou un tunnel) pour l'utiliser comme cible de webhook.
Webhook désactivé oublié
Un webhook désactivé reste dans la liste mais n'envoie rien. Si les notifications se sont tues, vérifiez d'abord l'interrupteur d'activation avant de suspecter l'URL.