Webhooks – Eventi in tempo reale
I Webhook di BigBlueButton permettono alla tua applicazione di ricevere notifiche HTTP POST in tempo reale ogni volta che si verificano eventi di riunione. Invece di interrogare ripetutamente getMeetings o getMeetingInfo, registri un URL di callback e BigBlueButton ti invia automaticamente gli eventi. Questo capitolo copre i tre endpoint API dei webhook, il formato della callback, i tipi di evento, il comportamento di retry e la configurazione del server.
I webhook richiedono che il pacchetto bbb-webhooks sia installato sul server. Diversi dettagli descritti in questo capitolo non sono coperti dalla documentazione ufficiale BigBlueButton e sono stati determinati tramite analisi del codice sorgente. undocumented
Prerequisiti
Il pacchetto bbb-webhooks deve essere installato sul server BigBlueButton prima che gli endpoint webhook diventino disponibili:
sudo apt-get install bbb-webhooks Se l'applicazione webhook non è in esecuzione quando viene creata una riunione, non viene stabilita alcuna mappatura interna della riunione. Di conseguenza, non verrà attivato alcun callback per quella riunione.
hooks/create — Registra un webhook
GET https://api-guide.bbbserver.com/bigbluebutton/api/hooks/create?<parameters>&checksum=replace-with-checksum La documentazione ufficiale non specifica un metodo HTTP. Il router Express registra solo rotte GET — le richieste POST non sono accettate. undocumented
| Parametro | Tipo | Obbligatorio | Predefinito | Descrizione |
|---|---|---|---|---|
callbackURL | String | Sì | — | L'URL che riceverà le callback POST. Il rilevamento dei duplicati si basa esclusivamente su questo URL — lo stesso URL non può essere registrato due volte, nemmeno con un meetingID o eventID diverso. |
meetingID | String | No | — | Limita l'hook a una riunione specifica (ID riunione esterno). Se omesso, l'hook diventa un hook globale che si attiva per tutte le riunioni. |
eventID | String | No | — | Elenco di tipi di evento separati da virgole da ascoltare (ad es. user-joined,meeting-ended). Se omesso, vengono consegnati tutti gli eventi. Il filtro non distingue tra maiuscole e minuscole. Disponibile da BBB 2.5. |
getRaw | Boolean | No | false | Se impostato su true, le callback contengono il messaggio Redis grezzo invece dei dati evento elaborati. |
Risposta riuscita
<response>
<returncode>SUCCESS</returncode>
<hookID>replace-with-hook-id</hookID>
<permanentHook>false</permanentHook>
<rawData>false</rawData>
</response> Registrazione duplicata
Se lo stesso callbackURL viene registrato di nuovo, la risposta restituisce comunque SUCCESS ma include un duplicateWarning. L'hook esistente viene mantenuto invariato — meetingID, eventID e getRaw non vengono aggiornati.
<response>
<returncode>SUCCESS</returncode>
<hookID>replace-with-hook-id</hookID>
<messageKey>duplicateWarning</messageKey>
<message>There is already a hook for this callback URL.</message>
</response> Risposte di errore
messageKey | Descrizione |
|---|---|
checksumError | Il checksum non è valido o manca. |
missingParamCallbackURL | Il parametro callbackURL non è stato fornito. undocumented |
createHookError | Si è verificato un errore interno (ad es. Redis irraggiungibile). Controlla i log del server. |
hooks/list — Elenca i webhook registrati
GET https://api-guide.bbbserver.com/bigbluebutton/api/hooks/list?<parameters>&checksum=replace-with-checksum | Parametro | Tipo | Obbligatorio | Descrizione |
|---|---|---|---|
meetingID | String | No | Filtra per ID della riunione. Il risultato include sia i hook per la riunione specificata sia tutti i hook globali. Se omesso, vengono restituiti tutti i hook registrati. |
Risposta riuscita
<response>
<returncode>SUCCESS</returncode>
<hooks>
<hook>
<hookID>replace-with-hook-id</hookID>
<callbackURL><![CDATA[https://api-guide.bbbserver.com/callbacks/webhook]]></callbackURL>
<meetingID><![CDATA[replace-with-meeting-id]]></meetingID>
<eventID>user-joined,meeting-ended</eventID>
<permanentHook>false</permanentHook>
<rawData>false</rawData>
</hook>
</hooks>
</response> L'elemento <meetingID> appare solo per i hook specifici della riunione. I hook globali non hanno alcun elemento <meetingID>. Allo stesso modo, <eventID> appare solo quando un filtro eventi è stato impostato durante la creazione.
Risposte di errore
messageKey | Descrizione |
|---|---|
checksumError | Il checksum non è valido o manca. |
listHookError | Si è verificato un errore interno durante l'elenco dei hook. Controlla i log del server. undocumented |
hooks/destroy — Rimuovi un webhook
GET https://api-guide.bbbserver.com/bigbluebutton/api/hooks/destroy?<parameters>&checksum=replace-with-checksum | Parametro | Tipo | Obbligatorio | Descrizione |
|---|---|---|---|
hookID | String | Sì | L'ID del hook da rimuovere (ottenuto da hooks/create o hooks/list). |
Risposta riuscita
<response>
<returncode>SUCCESS</returncode>
<removed>true</removed>
</response> I hook permanenti (configurati lato server tramite permanentURLs) non possono essere eliminati tramite l'API. Tentare di farlo restituisce un errore destroyMissingHook come se il hook non esistesse.
Risposte di errore
messageKey | Descrizione |
|---|---|
checksumError | Il checksum non è valido o manca. |
missingParamHookID | Il parametro hookID non è stato fornito. |
destroyMissingHook | L'ID del hook non esiste o appartiene a un hook permanente. |
destroyHookError | Si è verificato un errore interno durante la rimozione del hook. Controlla i log del server. |
hooks/ping — Controllo di integrità
GET https://api-guide.bbbserver.com/bigbluebutton/api/hooks/ping Questo endpoint diagnostico non richiede checksum. Se l'applicazione webhook è raggiungibile, restituisce la stringa in testo semplice bbb-webhooks API up! (non XML, tipo di contenuto text/plain). undocumented
Formato del callback
I callback webhook vengono inviati come richieste HTTP POST con tipo di contenuto application/x-www-form-urlencoded. Il corpo della richiesta contiene tre campi:
| Campo | Descrizione |
|---|---|
domain | Il dominio del server (dalla configurazione del webhook). undocumented |
event | Un array JSON contenente i dati dell'evento. Sempre un array, anche per un singolo evento. |
timestamp | Un timestamp Unix in millisecondi al momento dell'invio. |
Corpo della callback elaborato (getRaw=false)
domain=myserver.com&event=[{"data":{"type":"event","id":"user-joined","attributes":{...},"event":{"ts":1532718316938}}}]×tamp=1532718316953 Corpo della callback grezzo (getRaw=true)
domain=myserver.com&event=[{"envelope":{"name":"UserJoinedMeetingEvtMsg","routing":{"sender":"bbb-apps-akka"}},"core":{"header":{...},"body":{...}}}]×tamp=1532718316953 Quando il server è configurato con multiEvent maggiore di 1, più eventi possono essere raggruppati nell'array event all'interno di un singolo callback.
Convalida del checksum del callback
Nella modalità predefinita, ogni URL di callback riceve un parametro di query checksum che la tua applicazione dovrebbe verificare:
https://api-guide.bbbserver.com/callbacks/webhook?checksum=replace-with-checksum La formula di convalida è:
sha<algo>(<callback-URL-without-checksum> + <URL-encoded-body> + <shared-secret>) Prendi l'URL di callback registrato senza il parametro checksum.
Aggiungi il corpo completo della richiesta codificato come URL (domain=...&event=[...]×tamp=...).
Aggiungi in coda il shared secret BBB.
Calcola l'hash della stringa risultante con l'algoritmo configurato (predefinito: sha1, configurabile tramite hookChecksumAlgorithm).
Modalità Auth 2.0 / Bearer
In alternativa, il server può essere configurato con auth2_0: true. In questa modalità, nessun parametro checksum viene aggiunto all'URL di callback. Invece, il shared secret viene inviato come token Bearer nell'header Authorization: undocumented
Authorization: Bearer <shared-secret> Comportamento del callback
- Codici di stato HTTP accettati: HTTP
2xxe HTTP401vengono trattati come consegna riuscita. Tutti gli altri codici di stato attivano un retry. undocumented - Redirect: Le risposte HTTP
3xxvengono seguite (fino a 10 hop). Solo se non si raggiunge alcun2xx/401dopo 10 redirect la callback viene considerata fallita. - Timeout: ogni richiesta di callback ha un timeout di 5 secondi (configurabile tramite
requestTimeout). - Intervalli di ritentativo: in caso di errore, i ritentativi usano back-off esponenziale:
100ms, 500ms, 1s, 2s, 4s, 8s, 10s, 30s, 60s, 60s, 60s, 60s(12 tentativi in circa 5 minuti, configurabile tramiteretryIntervals). - Dopo l'esaurimento di tutti i ritentativi: i hook non permanenti vengono rimossi automaticamente. I hook permanenti continuano a ritentare indefinitamente a intervalli di 60 secondi (configurabile tramite
permanentIntervalReset).
Tipi di evento
Eventi della riunione
| ID evento | Descrizione |
|---|---|
meeting-created | È stata creata una riunione. |
meeting-ended | Una riunione è terminata. Questo attiva anche eventi sintetici user-left per tutti gli utenti connessi. |
meeting-recording-started | La registrazione è iniziata. |
meeting-recording-stopped | La registrazione si è fermata. |
meeting-recording-unhandled | Evento di registrazione non gestito (fallback quando lo stato della registrazione non è né true né false). |
meeting-screenshare-started | La condivisione dello schermo è iniziata (include i dati utente del presentatore). |
meeting-screenshare-stopped | La condivisione dello schermo si è fermata (include i dati utente del proprietario). |
meeting-presentation-changed | La presentazione attiva è cambiata (include presentation-id). |
Eventi utente
| ID evento | Descrizione |
|---|---|
user-joined | Un utente è entrato nella riunione (include flag guest, user data, indirizzo IP, User-Agent). |
user-left | Un utente ha lasciato la riunione (include flag ospite). Viene generato anche sinteticamente su meeting-ended. |
user-audio-voice-enabled | Audio abilitato (include flag listening-only, sharing-mic, muted). |
user-audio-voice-disabled | Audio disabilitato. |
user-audio-muted | L'utente è stato silenziato. |
user-audio-unmuted | L'utente non è più silenziato. |
user-audio-unhandled | Evento audio non gestito (fallback). |
user-cam-broadcast-start | Webcam avviata (include stream-id). |
user-cam-broadcast-end | Webcam arrestata. |
user-presenter-assigned | All'utente è stato assegnato il ruolo di presentatore. |
user-presenter-unassigned | Il ruolo di presentatore è stato rimosso all'utente. |
user-emoji-changed | L'emoji o la reazione dell'utente è cambiata (include il valore dell'emoji). |
user-raise-hand-changed | L'utente ha alzato o abbassato la mano (include booleano raise-hand). Nelle versioni BBB precedenti alla 2.7, questo viene generato sinteticamente da user-emoji-changed. |
Eventi della chat e delle note
| ID evento | Descrizione |
|---|---|
chat-group-message-sent | È stato inviato un messaggio nella chat pubblica. I messaggi di chat privata non generano eventi webhook. |
transcript-updated | Trascrizione aggiornata (include transcript, locale, flag final). |
pad-content | Il contenuto delle note condivise è cambiato (include pad-id, rev, text). |
Eventi dei sondaggi
| ID evento | Descrizione |
|---|---|
poll-started | È stato avviato un sondaggio (include la domanda e le opzioni di risposta). |
poll-responded | Un partecipante ha risposto a un sondaggio (include gli ID delle risposte). |
Eventi Record and Playback (RAP)
| ID evento | Descrizione |
|---|---|
rap-archive-started | Archiviazione avviata. |
rap-archive-ended | Archiviazione completata (include flag recorded e durata). |
rap-sanity-started | Controllo di integrità avviato. |
rap-sanity-ended | Controllo di integrità completato. |
rap-post-archive-started | Post-archiviazione avviata. |
rap-post-archive-ended | Post-archiviazione completata. |
rap-process-started | Elaborazione avviata. |
rap-process-ended | Elaborazione completata. |
rap-post-process-started | Post-elaborazione avviata. |
rap-post-process-ended | Post-elaborazione completata. |
rap-publish-started | Pubblicazione avviata. |
rap-publish-ended | Pubblicazione completata (include l'oggetto completo della registrazione con metadati, riproduzione e informazioni sul download). |
rap-post-publish-started | Post-pubblicazione avviata. |
rap-post-publish-ended | Post-pubblicazione completata. |
rap-published | Registrazione pubblicata. |
rap-unpublished | Registrazione non pubblicata. |
rap-deleted | Registrazione eliminata. |
La maggior parte degli eventi RAP include record-id, success (booleano) e step-time. Gli eventi con un campo workflow contengono inoltre il nome del flusso di lavoro di elaborazione.
Configurazione del server
Le seguenti opzioni possono essere configurate in /etc/bigbluebutton/bbb-webhooks.yml o config/default.yml. La maggior parte di queste opzioni non è coperta dalla documentazione ufficiale. undocumented
| Opzione | Predefinito | Descrizione |
|---|---|---|
hookChecksumAlgorithm | sha1 | Algoritmo di hash per i checksum delle callback (sha1, sha256, sha384, sha512). |
api.supportedChecksumAlgorithms | [sha1, sha256, sha384, sha512] | Algoritmi accettati per i checksum API in ingresso. |
api.port | 3005 | Porta del server API webhook. |
api.bind | 127.0.0.1 | Indirizzo di bind del server API. |
includeEvents | [] | Filtro eventi a livello di server: solo questi eventi vengono consegnati a tutti gli hook. Vuoto significa tutti gli eventi. |
excludeEvents | [] | Filtro eventi a livello di server: questi eventi sono soppressi per tutti gli hook. Vuoto significa nessuna esclusione. |
permanentURLs | [] | Elenco degli URL hook permanenti che vengono registrati all'avvio e non possono essere rimossi tramite l'API. |
retryIntervals | [100,500,1000,...,60000] | Intervalli di ritentativo in millisecondi per i callback non riusciti. |
permanentIntervalReset | 60000 | Intervallo di ritentativo in millisecondi per gli hook permanenti dopo l'esaurimento di tutti i normali tentativi. |
requestTimeout | 5000 | Timeout HTTP in millisecondi per le richieste di callback. |
multiEvent | 1 | Quando impostato su un valore maggiore di 1, più eventi vengono raggruppati nell'array degli eventi per callback. |
queueSize | 10000 | Dimensione massima della coda interna degli eventi. |
bbb.auth2_0 | false | Abilita l'autenticazione tramite token Bearer invece del checksum URL per le callback. |
includeEvents e excludeEvents sono filtri a livello di server che si applicano in aggiunta al filtro eventID per hook. Un evento deve superare entrambi i filtri per essere consegnato.
Note operative
- Persistenza: Gli hook sono memorizzati in Redis e sopravvivono ai riavvii del server (risincronizzati all'avvio).
- Ordinamento: I callback vengono inviati in modo sequenziale per hook, uno alla volta, preservando l'ordine degli eventi.
- Unicità URL: Il rilevamento dei duplicati si basa esclusivamente sull'URL di callback. Lo stesso URL non può essere registrato con filtri
meetingIDoeventIDdiversi — prevale la prima registrazione. - Pulizia dei dati: Le mappature interne delle riunioni vengono rimosse dopo una settimana di inattività (configurabile tramite
mappings.timeout, predefinito: 604800000 ms). - Eventi sintetici: Quando una riunione termina, gli eventi
user-leftvengono generati automaticamente per tutti gli utenti ancora connessi, perché BigBlueButton stesso non emetteUserLeftMeetingEvtMsgalla fine della riunione. - Chat private: Solo i messaggi della chat pubblica generano eventi
chat-group-message-sent. I messaggi privati vengono ignorati silenziosamente.
meetingID per ogni hook — gli hook globali senza meetingID non sono supportati; (2) i dati personali negli eventi vengono automaticamente offuscati per la privacy (ad es. gli indirizzi IP dei partecipanti non sono visibili).Domande frequenti
bbb-webhooks deve essere installato tramite apt-get install bbb-webhooks. Senza di esso, gli endpoint hooks/create, hooks/list e hooks/destroy non sono disponibili.duplicateWarning e l'hook esistente rimane invariato. Per monitorare riunioni specifiche separatamente, usa URL di callback distinti.MAIN-PUBLIC-GROUP-CHAT) attivano un evento chat-group-message-sent. I messaggi privati tra partecipanti non generano alcun evento webhook.getRaw=false (predefinito), ricevi dati evento elaborati con una struttura standardizzata contenente i campi type, id e attributes. Con getRaw=true, ricevi il messaggio Redis grezzo come pubblicato internamente da BigBlueButton, che include i campi envelope e core. Il formato grezzo è utile per il debug o quando ti servono dati non inclusi nel formato elaborato.permanentURLs e non possono essere rimossi tramite l'API. Chiamare hooks/destroy su un hook permanente restituisce un errore destroyMissingHook come se l'hook non esistesse.2xx e HTTP 401 vengono entrambi trattati come consegna riuscita. Tutti gli altri codici di stato, inclusi 3xx (dopo aver seguito fino a 10 redirect), 4xx (eccetto 401) e 5xx, attivano un retry. Questo comportamento non è documentato nella documentazione ufficiale BigBlueButton.