Wiki
Webhook
Notifiche in uscita per repository (Discord, Slack, Teams, custom) su check-in e riepiloghi di attività. Creazione, formato dei messaggi, variabili di template, protezione SSRF.
Introduzione
Un webhook invia una notifica in uscita a un servizio esterno (Discord, Slack, Microsoft Teams, o un URL a tua scelta) ogni volta che si verifica un evento in un repository (un progetto versionato sul server): un check-in, o un riepilogo di attività periodico. È il modo più semplice per tenere aggiornata una squadra senza che apra il client: un messaggio arriva nel tuo canale quando qualcuno invia del lavoro.
I webhook sono configurati per repository, nel pannello di amministrazione del client desktop, nella scheda Webhooks. Un repository può avere più webhook (per esempio uno verso Discord per tutta la squadra, uno verso uno Slack privato per i lead).
Accesso e ruoli
La gestione dei webhook è riservata agli amministratori del repository: un super admin
(ruolo admin) su qualsiasi repository, o un project_admin sui repository
che amministra. Gli altri ruoli non vedono questa scheda.
Creare un webhook
1. Aprire la scheda Webhooks
Nel pannello di amministrazione, scegli prima il repository nel selettore della riga PROJECT, poi apri la scheda Webhooks di quella stessa riga: un webhook appartiene a un repository. Un repository che non ne ha nessuno mostra No webhooks configured.
2. Aprire il modulo
Fai clic su Add Webhook, in alto a destra nella scheda. La finestra Create Webhook si apre, vuota.
3. Compilare i campi
Due campi sono obbligatori, Name e URL, e almeno un evento deve essere selezionato in Events (sono pillole cliccabili, non un menu a discesa). Il Type deve corrispondere al servizio a cui punta l'URL.
| Campo | Valore |
|---|---|
| Name | Un'etichetta per ritrovarlo (es. Discord équipe). Obbligatorio. |
| URL | L'URL del webhook fornito dal servizio di destinazione. Obbligatorio. Vedi Sicurezza per gli URL rifiutati. |
| Type | discord, slack, teams o custom. |
| Events | Almeno uno è obbligatorio. In pratica: checkin e activity_summary. Vedi Eventi a proposito di checkout. |
| Enabled | Interruttore di attivazione (visibile in modifica e dalla lista). |
Per ottenere l'URL lato Discord: Impostazioni del canale → Integrazioni → Webhook → Nuovo webhook → Copia URL, dettagliato nel tutorial qui sotto. Lato Slack: crea un Incoming Webhook nelle impostazioni dell'app Slack. Lato Teams: Connettori → Incoming Webhook sul canale.
4. Confermare, poi inviare un test
Fai clic su Create Webhook. Il webhook compare nella lista, attivo. Sulla sua riga, fai clic sull'icona aereo Send test: uVersion invia una notifica di test al servizio e mostra il risultato alla fine della riga, una spunta verde o una croce con il codice HTTP restituito. Fallo ora: è l'unico modo per sapere che l'URL e il tipo sono corretti prima di fare affidamento su questo webhook.
Tutorial: webhook Discord
È il caso più comune. La parte «ottenere l'URL» avviene interamente in Discord, una sola volta.
Lato Discord: ottenere l'URL
- Apri Discord e vai sul tuo server. Scegli (o crea) il canale testuale che riceverà le notifiche, per esempio
#uversion. - Passa il mouse sul nome del canale e fai clic sull'icona a forma di ingranaggio («Modifica canale»).
- Nel menu di sinistra, apri la scheda Integrazioni.
- Fai clic su Webhook, poi su Nuovo webhook. Discord ne crea uno automaticamente, collegato a questo canale.
- Fai clic sul webhook creato per aprirlo. Dagli un nome (per esempio
uVersion) e verifica che il canale di destinazione sia quello giusto. Un'immagine avatar è facoltativa. - Fai clic su Copia URL webhook. L'URL somiglia a
https://discord.com/api/webhooks/123456789/AbCdEf....
Lato uVersion: collegare l'URL
Segui la procedura Creare un webhook qui sopra con questi valori: Name
un'etichetta per te (es. Discord équipe), URL quello che hai appena copiato,
Type discord (indispensabile affinché il messaggio parta come embed Discord),
Events checkin. Termina con Send test: un messaggio dovrebbe
comparire nel canale Discord in pochi secondi.
Se il test fallisce con un codice HTTP 401 o 404, l'URL è errato o il webhook è stato
eliminato lato Discord: ricopia l'URL. Se non arriva nulla anche se il test è verde, verifica di stare guardando
il canale giusto e che il webhook non sia stato disattivato in Discord.
Tipi e formati
Il Type determina come uVersion formatta il messaggio prima di inviarlo. Scegli quello che corrisponde al servizio puntato dall'URL, altrimenti il messaggio arriverà mal formattato (o sarà rifiutato dal servizio).
| Type | Formato inviato |
|---|---|
discord | Embed Discord (titolo, colore, campi). |
slack | Payload Slack (blocchi di messaggio). |
teams | Scheda Microsoft Teams (MessageCard). |
custom | Corpo JSON interamente definito da te: vedi Webhook personalizzati. |
Eventi
Due eventi sono realmente emessi dal server:
| Evento | Si attiva quando… |
|---|---|
checkin | Un utente invia un commit nel repository. |
activity_summary | Un riepilogo di attività periodico è prodotto dallo scheduler del server (giornaliero / settimanale). |
checkout: casella presente, evento mai emesso
Il modulo propone una terza casella, checkout, destinata a segnalare il blocco di un file
(un blocco è la prenotazione che un utente pone su un file mentre lo modifica).
È dichiarata ma mai emessa a oggi: spuntarla non provocherà alcuna notifica.
Non farci affidamento, e non usarla come unica selezione: un webhook che ha spuntato solo questo evento
resterà silenzioso per sempre.
Spunta solo ciò di cui il tuo canale ha bisogno. In pratica, la combinazione utile è checkin per il
flusso di lavoro della squadra, e activity_summary per un riepilogo periodico.
Webhook personalizzati
Con il tipo custom compaiono due campi aggiuntivi: Custom Headers (JSON)
e Custom Template (JSON). Permettono di integrare qualsiasi servizio che accetti un POST JSON.
Template
Il template è il corpo JSON inviato. uVersion vi sostituisce le variabili tra doppie parentesi graffe con i valori dell'evento. Esempio:
{"text": "{{event_type}} par {{username}} dans {{repository}}"}
Variabili disponibili:
| Variabile | Contenuto |
|---|---|
{{event_type}} | Tipo di evento (checkin o activity_summary). |
{{repository}} | Nome del repository. |
{{username}} | Utente all'origine dell'evento. |
{{message}} | Messaggio di commit (per un check-in). |
{{file_count}} | Numero di file interessati. |
{{commit_hash}} | Hash del commit. |
{{timestamp}} | Marca temporale dell'evento. |
Headers
Un oggetto JSON di header HTTP da allegare alla richiesta, per esempio un token di autenticazione:
{"Authorization": "Bearer VOTRE_JETON"}
Per impostazione predefinita {} (nessun header). Gli header riservati al trasporto
(host, content-length, transfer-encoding, connection)
vengono rimossi automaticamente e non possono essere sovrascritti.
Testare, attivare, eliminare
Ogni webhook della lista propone le seguenti azioni:
- Send test (icona aereo): invia una notifica di test al servizio e mostra un risultato in linea (spunta verde o croce). Utile per verificare l'URL e il tipo prima di farci affidamento.
- Interruttore: attiva / disattiva il webhook senza eliminarlo.
- Edit: modificare qualsiasi campo.
- Delete: eliminazione definitiva (conferma richiesta).
Sicurezza: protezione SSRF
Un webhook fa emettere una richiesta HTTP dal server. Per evitare che un URL malevolo serva a sondare la rete interna del server (attacco SSRF), uVersion applica una protezione rigorosa alla creazione, alla modifica e al test:
- Lo schema deve essere
httpohttps. Qualsiasi altro schema è rifiutato. - Il nome host è risolto tramite DNS, e ogni indirizzo IP ottenuto è verificato. Il webhook
è rifiutato se uno punta a un indirizzo non pubblico: loopback, reti private (RFC1918), link-local,
broadcast, intervallo CGNAT
100.64.0.0/10, metadati cloud169.254.169.254, ULA / link-local IPv6, e i loro equivalenti IPv4-mapped-IPv6. - I redirect HTTP non vengono seguiti (quindi un 307 verso un host interno non può aggirare la protezione).
- Il corpo della risposta a monte non viene mai restituito al client (nessun oracolo SSRF).
In pratica: un URL di webhook deve puntare a un servizio pubblico (Discord, Slack, Teams, o
il tuo endpoint accessibile da Internet). Un URL verso localhost, un IP privato
(10.x, 192.168.x, 172.16-31.x) o un servizio interno è rifiutato con un
messaggio «Webhook URL refused: …».
Errori frequenti
Il tipo non corrisponde al servizio
Inviare un formato Discord a un URL Slack (o viceversa) produce un messaggio mal formattato o un rifiuto lato servizio. Il campo Type deve corrispondere all'URL. Nel dubbio, fai un Send test.
Nessun evento spuntato
Un webhook senza evento non si attiva mai. Il client blocca il salvataggio finché nessun evento è selezionato («At least one event is required»).
URL interno rifiutato
Se testi verso un servizio sulla tua macchina o sulla tua LAN, la protezione SSRF lo rifiuta. Esponi il servizio su un URL pubblico (o un tunnel) per usarlo come destinazione di webhook.
Webhook disattivato dimenticato
Un webhook disattivato resta nella lista ma non invia nulla. Se le notifiche sono ammutolite, controlla prima l'interruttore di attivazione prima di sospettare dell'URL.