Webhooks – Realtimegebeurtenissen
BigBlueButton Webhooks zorgen ervoor dat je applicatie realtime HTTP-POST-meldingen ontvangt wanneer vergadergebeurtenissen plaatsvinden. In plaats van herhaaldelijk getMeetings of getMeetingInfo te pollen, registreer je een callback-URL en pusht BigBlueButton automatisch gebeurtenissen naar je toe. Dit hoofdstuk behandelt de drie webhook-API-endpoints, het callbackformaat, gebeurtenistypen, retrygedrag en serverconfiguratie.
Webhooks vereisen dat het pakket bbb-webhooks op de server is geïnstalleerd. Verschillende details die in dit hoofdstuk worden beschreven, komen niet voor in de officiële BigBlueButton-documentatie en zijn vastgesteld via broncodeanalyse. undocumented
Vereisten
Het pakket bbb-webhooks moet op de BigBlueButton-server zijn geïnstalleerd voordat webhook-endpoints beschikbaar worden:
sudo apt-get install bbb-webhooks Als de webhook-applicatie niet draait wanneer een vergadering wordt aangemaakt, wordt er geen interne meeting-mapping opgezet. Daardoor worden er voor die vergadering geen callbacks geactiveerd.
hooks/create — Een webhook registreren
GET https://api-guide.bbbserver.com/bigbluebutton/api/hooks/create?<parameters>&checksum=replace-with-checksum De officiële documentatie specificeert geen HTTP-methode. De Express-router registreert alleen GET-routes — POST-requests worden niet geaccepteerd. undocumented
| Parameter | Type | Vereist | Standaard | Beschrijving |
|---|---|---|---|---|
callbackURL | String | Ja | — | De URL die POST-callbacks ontvangt. Detectie van duplicaten is uitsluitend gebaseerd op deze URL — dezelfde URL kan niet twee keer worden geregistreerd, zelfs niet met een andere meetingID of eventID. |
meetingID | String | Nee | — | Beperkt de hook tot een specifieke vergadering (externe meeting-ID). Als dit wordt weggelaten, wordt de hook een globale hook die voor alle vergaderingen wordt geactiveerd. |
eventID | String | Nee | — | Door komma's gescheiden lijst met gebeurtenistypen om op te luisteren (bijv. user-joined,meeting-ended). Als dit wordt weggelaten, worden alle gebeurtenissen afgeleverd. Het filter is niet hoofdlettergevoelig. Beschikbaar sinds BBB 2.5. |
getRaw | Boolean | Nee | false | Wanneer ingesteld op true, bevatten callbacks het ruwe Redis-bericht in plaats van de verwerkte gebeurtenisgegevens. |
Succesvolle respons
<response>
<returncode>SUCCESS</returncode>
<hookID>replace-with-hook-id</hookID>
<permanentHook>false</permanentHook>
<rawData>false</rawData>
</response> Dubbele registratie
Als dezelfde callbackURL opnieuw wordt geregistreerd, retourneert de respons nog steeds SUCCESS maar bevat deze een duplicateWarning. De bestaande hook blijft ongewijzigd — meetingID, eventID en getRaw worden niet bijgewerkt.
<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> Foutresponses
messageKey | Beschrijving |
|---|---|
checksumError | De checksum is ongeldig of ontbreekt. |
missingParamCallbackURL | De parameter callbackURL is niet opgegeven. undocumented |
createHookError | Er is een interne fout opgetreden (bijv. Redis onbereikbaar). Controleer de serverlogs. |
hooks/list — Geregistreerde webhooks weergeven
GET https://api-guide.bbbserver.com/bigbluebutton/api/hooks/list?<parameters>&checksum=replace-with-checksum | Parameter | Type | Vereist | Beschrijving |
|---|---|---|---|
meetingID | String | Nee | Filtert op vergadering-ID. Het resultaat bevat zowel hooks voor de opgegeven vergadering als alle globale hooks. Als dit wordt weggelaten, worden alle geregistreerde hooks geretourneerd. |
Succesvolle respons
<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> Het element <meetingID> verschijnt alleen voor vergaderingsspecifieke hooks. Globale hooks hebben geen element <meetingID>. Evenzo verschijnt <eventID> alleen wanneer er tijdens het aanmaken een gebeurtenisfilter is ingesteld.
Foutresponses
messageKey | Beschrijving |
|---|---|
checksumError | De checksum is ongeldig of ontbreekt. |
listHookError | Er is een interne fout opgetreden bij het weergeven van hooks. Controleer de serverlogs. undocumented |
hooks/destroy — Een webhook verwijderen
GET https://api-guide.bbbserver.com/bigbluebutton/api/hooks/destroy?<parameters>&checksum=replace-with-checksum | Parameter | Type | Vereist | Beschrijving |
|---|---|---|---|
hookID | String | Ja | De ID van de hook die moet worden verwijderd (verkregen uit hooks/create of hooks/list). |
Succesvolle respons
<response>
<returncode>SUCCESS</returncode>
<removed>true</removed>
</response> Permanente hooks (server-side geconfigureerd via permanentURLs) kunnen niet via de API worden verwijderd. Een poging daartoe geeft een destroyMissingHook-fout terug alsof de hook niet bestaat.
Foutresponses
messageKey | Beschrijving |
|---|---|
checksumError | De checksum is ongeldig of ontbreekt. |
missingParamHookID | De parameter hookID is niet opgegeven. |
destroyMissingHook | De hook-ID bestaat niet of behoort tot een permanente hook. |
destroyHookError | Er is een interne fout opgetreden bij het verwijderen van de hook. Controleer de serverlogs. |
hooks/ping — Gezondheidscontrole
GET https://api-guide.bbbserver.com/bigbluebutton/api/hooks/ping Dit diagnostische endpoint vereist geen checksum. Als de webhookapplicatie bereikbaar is, retourneert het de platte-tekststring bbb-webhooks API up! (geen XML, contenttype text/plain). undocumented
Callback-indeling
Webhook-callbacks worden verzonden als HTTP POST-verzoeken met contenttype application/x-www-form-urlencoded. De requestbody bevat drie velden:
| Veld | Beschrijving |
|---|---|
domain | Het serverdomein (uit de webhookconfiguratie). undocumented |
event | Een JSON-array met de gebeurtenisgegevens. Altijd een array, zelfs voor één enkele gebeurtenis. |
timestamp | Een Unix-tijdstempel in milliseconden op het moment van verzending. |
Verwerkte callbackbody (getRaw=false)
domain=myserver.com&event=[{"data":{"type":"event","id":"user-joined","attributes":{...},"event":{"ts":1532718316938}}}]×tamp=1532718316953 Ruwe callbackbody (getRaw=true)
domain=myserver.com&event=[{"envelope":{"name":"UserJoinedMeetingEvtMsg","routing":{"sender":"bbb-apps-akka"}},"core":{"header":{...},"body":{...}}}]×tamp=1532718316953 Wanneer de server is geconfigureerd met multiEvent groter dan 1, kunnen meerdere gebeurtenissen worden gebundeld in de event-array binnen één enkele callback.
Validatie van callback-checksum
In de standaardmodus ontvangt elke callback-URL een queryparameter checksum die je applicatie moet verifiëren:
https://api-guide.bbbserver.com/callbacks/webhook?checksum=replace-with-checksum De validatieformule is:
sha<algo>(<callback-URL-without-checksum> + <URL-encoded-body> + <shared-secret>) Neem de geregistreerde callback-URL zonder de checksum-parameter.
Voeg de volledig URL-gecodeerde requestbody toe (domain=...&event=[...]×tamp=...).
Voeg het BBB shared secret toe.
Hash de resulterende string met het geconfigureerde algoritme (standaard: sha1, configureerbaar via hookChecksumAlgorithm).
Auth 2.0 / Bearer-modus
Als alternatief kan de server worden geconfigureerd met auth2_0: true. In deze modus wordt er geen checksum-parameter aan de callback-URL toegevoegd. In plaats daarvan wordt het shared secret verzonden als een Bearer-token in de header Authorization: undocumented
Authorization: Bearer <shared-secret> Callback-gedrag
- Geaccepteerde HTTP-statuscodes: HTTP
2xxen HTTP401worden als succesvolle aflevering beschouwd. Alle andere statuscodes activeren een retry. undocumented - Redirects: HTTP-
3xx-responses worden gevolgd (tot 10 hops). Alleen als er na 10 redirects geen2xx/401wordt bereikt, geldt de callback als mislukt. - Timeout: Elk callback-verzoek heeft een timeout van 5 seconden (configureerbaar via
requestTimeout). - Interval tussen nieuwe pogingen: Bij een fout gebruiken retries exponentiële back-off:
100ms, 500ms, 1s, 2s, 4s, 8s, 10s, 30s, 60s, 60s, 60s, 60s(12 pogingen over ongeveer 5 minuten, configureerbaar viaretryIntervals). - Nadat alle nieuwe pogingen zijn uitgeput: Niet-permanente hooks worden automatisch verwijderd. Permanente hooks blijven onbeperkt opnieuw proberen met intervallen van 60 seconden (configureerbaar via
permanentIntervalReset).
Gebeurtenistypen
Vergaderingsgebeurtenissen
| Gebeurtenis-ID | Beschrijving |
|---|---|
meeting-created | Er is een vergadering aangemaakt. |
meeting-ended | Een vergadering is beëindigd. Dit activeert ook synthetische user-left-gebeurtenissen voor alle verbonden gebruikers. |
meeting-recording-started | Opname is gestart. |
meeting-recording-stopped | Opname is gestopt. |
meeting-recording-unhandled | Niet-afgehandelde opnamegebeurtenis (fallback wanneer opnamestatus noch true noch false is). |
meeting-screenshare-started | Scherm delen gestart (inclusief presentator-gebruikersgegevens). |
meeting-screenshare-stopped | Scherm delen gestopt (inclusief eigenaar-gebruikersgegevens). |
meeting-presentation-changed | De actieve presentatie is gewijzigd (inclusief presentation-id). |
Gebruikersgebeurtenissen
| Gebeurtenis-ID | Beschrijving |
|---|---|
user-joined | Een gebruiker nam deel aan de vergadering (inclusief gastvlag, gebruikersdata, IP-adres, User-Agent). |
user-left | Een gebruiker heeft de vergadering verlaten (inclusief gastvlag). Ook synthetisch gegenereerd bij meeting-ended. |
user-audio-voice-enabled | Audio ingeschakeld (inclusief listening-only-, sharing-mic-, muted-vlaggen). |
user-audio-voice-disabled | Audio uitgeschakeld. |
user-audio-muted | Gebruiker werd gedempt. |
user-audio-unmuted | Gebruiker werd niet meer gedempt. |
user-audio-unhandled | Niet-afgehandelde audiogebeurtenis (fallback). |
user-cam-broadcast-start | Webcam gestart (inclusief stream-id). |
user-cam-broadcast-end | Webcam gestopt. |
user-presenter-assigned | Gebruiker kreeg de presentatorrol toegewezen. |
user-presenter-unassigned | Gebruiker werd uit de presentatorrol verwijderd. |
user-emoji-changed | Gebruikersemoji of -reactie gewijzigd (bevat emojiwaarde). |
user-raise-hand-changed | Gebruiker stak de hand op of liet die zakken (inclusief boolean raise-hand). In BBB-versies vóór 2.7 wordt dit synthetisch gegenereerd op basis van user-emoji-changed. |
Chat- en notitiegebeurtenissen
| Gebeurtenis-ID | Beschrijving |
|---|---|
chat-group-message-sent | Er werd een bericht verzonden in de publieke chat. Privéchats genereren geen webhookgebeurtenissen. |
transcript-updated | Transcriptie bijgewerkt (inclusief transcript, locale, final-vlag). |
pad-content | Inhoud van gedeelde notities gewijzigd (inclusief pad-id, rev, text). |
Pollgebeurtenissen
| Gebeurtenis-ID | Beschrijving |
|---|---|
poll-started | Er werd een poll gestart (bevat vraag en antwoordopties). |
poll-responded | Een deelnemer reageerde op een poll (bevat antwoord-ID's). |
Opname- en afspeelgebeurtenissen (RAP)
| Gebeurtenis-ID | Beschrijving |
|---|---|
rap-archive-started | Archivering gestart. |
rap-archive-ended | Archivering voltooid (inclusief recorded-vlag en duur). |
rap-sanity-started | Integriteitscontrole gestart. |
rap-sanity-ended | Integriteitscontrole voltooid. |
rap-post-archive-started | Nabewerking van archivering gestart. |
rap-post-archive-ended | Nabewerking van archivering voltooid. |
rap-process-started | Verwerking gestart. |
rap-process-ended | Verwerking voltooid. |
rap-post-process-started | Nabewerking gestart. |
rap-post-process-ended | Nabewerking voltooid. |
rap-publish-started | Publicatie gestart. |
rap-publish-ended | Publicatie voltooid (bevat volledig opnameobject met metadata, afspeel- en downloadinformatie). |
rap-post-publish-started | Nabewerking van publicatie gestart. |
rap-post-publish-ended | Nabewerking van publicatie voltooid. |
rap-published | Opname gepubliceerd. |
rap-unpublished | Publicatie van opname ongedaan gemaakt. |
rap-deleted | Opname verwijderd. |
De meeste RAP-gebeurtenissen bevatten record-id, success (boolean) en step-time. Gebeurtenissen met een veld workflow bevatten daarnaast de naam van de verwerkingsworkflow.
Serverconfiguratie
De volgende opties kunnen worden geconfigureerd in /etc/bigbluebutton/bbb-webhooks.yml of config/default.yml. De meeste van deze opties worden niet behandeld in de officiële documentatie. undocumented
| Optie | Standaard | Beschrijving |
|---|---|---|
hookChecksumAlgorithm | sha1 | Hash-algoritme voor callback-checksums (sha1, sha256, sha384, sha512). |
api.supportedChecksumAlgorithms | [sha1, sha256, sha384, sha512] | Geaccepteerde algoritmen voor inkomende API-controlesommen. |
api.port | 3005 | Poort van de webhook-API-server. |
api.bind | 127.0.0.1 | Bind-adres van de API-server. |
includeEvents | [] | Serverbrede gebeurtenisfilter: alleen deze gebeurtenissen worden aan alle hooks geleverd. Leeg betekent alle gebeurtenissen. |
excludeEvents | [] | Serverbrede gebeurtenisfilter: deze gebeurtenissen worden voor alle hooks onderdrukt. Leeg betekent geen uitsluitingen. |
permanentURLs | [] | Lijst met permanente hook-URL's die bij het opstarten worden geregistreerd en niet via de API kunnen worden verwijderd. |
retryIntervals | [100,500,1000,...,60000] | Herhaalintervallen in milliseconden voor mislukte callbacks. |
permanentIntervalReset | 60000 | Herhaalinterval in milliseconden voor permanente hooks nadat alle normale herhaalpogingen zijn uitgeput. |
requestTimeout | 5000 | HTTP-time-out in milliseconden voor callbackverzoeken. |
multiEvent | 1 | Wanneer ingesteld op een waarde groter dan 1, worden meerdere gebeurtenissen per callback gebundeld in de gebeurtenisarray. |
queueSize | 10000 | Maximale grootte van de interne gebeurteniswachtrij. |
bbb.auth2_0 | false | Schakelt Bearer-tokenauthenticatie in in plaats van URL-checksum voor callbacks. |
includeEvents en excludeEvents zijn serverbrede filters die aanvullend gelden op het per-hook eventID-filter. Een gebeurtenis moet door beide filters komen om te worden afgeleverd.
Operationele opmerkingen
- Persistentie: Hooks worden opgeslagen in Redis en overleven serverherstarts (opnieuw gesynchroniseerd bij het opstarten).
- Volgorde: Callbacks worden per hook sequentieel verzonden, één tegelijk, waarbij de gebeurtenisvolgorde behouden blijft.
- Uniciteit van URL's: Detectie van duplicaten is uitsluitend gebaseerd op de callback-URL. Dezelfde URL kan niet worden geregistreerd met verschillende
meetingID- ofeventID-filters — de eerste registratie wint. - Opschonen van gegevens: Interne meetingtoewijzingen worden verwijderd na één week inactiviteit (configureerbaar via
mappings.timeout, standaard: 604800000 ms). - Synthetische gebeurtenissen: Wanneer een vergadering eindigt, worden voor alle nog verbonden gebruikers automatisch
user-left-gebeurtenissen gegenereerd, omdat BigBlueButton zelf geenUserLeftMeetingEvtMsguitzendt bij het einde van een vergadering. - Privéchats: Alleen openbare chatberichten genereren
chat-group-message-sent-gebeurtenissen. Privéberichten worden stilzwijgend genegeerd.
meetingID is vereist voor elke hook — globale hooks zonder een meetingID worden niet ondersteund; (2) persoonlijke gegevens in gebeurtenissen worden automatisch gemaskeerd voor privacy (bijv. IP-adressen van deelnemers zijn niet zichtbaar).Veelgestelde vragen
bbb-webhooks moet via apt-get install bbb-webhooks worden geïnstalleerd. Zonder dit zijn de endpoints hooks/create, hooks/list en hooks/destroy niet beschikbaar.duplicateWarning en blijft de bestaande hook ongewijzigd. Gebruik verschillende callback-URL's om specifieke vergaderingen afzonderlijk te monitoren.MAIN-PUBLIC-GROUP-CHAT) worden gestuurd, activeren een chat-group-message-sent-gebeurtenis. Privéberichten tussen deelnemers genereren geen webhook-gebeurtenissen.getRaw=false (de standaard) ontvang je verwerkte gebeurtenisgegevens met een gestandaardiseerde structuur die de velden type, id en attributes bevat. Met getRaw=true ontvang je het ruwe Redis-bericht zoals dat intern door BigBlueButton wordt gepubliceerd, inclusief de velden envelope en core. Het ruwe formaat is nuttig voor debugging of wanneer je gegevens nodig hebt die niet in het verwerkte formaat zijn opgenomen.permanentURLs en kunnen niet via de API worden verwijderd. Het aanroepen van hooks/destroy op een permanente hook retourneert een destroyMissingHook-fout alsof de hook niet bestaat.2xx en HTTP 401 worden beide als succesvolle aflevering beschouwd. Alle andere statuscodes, inclusief 3xx (na het volgen van maximaal 10 redirects), 4xx (behalve 401) en 5xx, activeren een retry. Dit gedrag is niet gedocumenteerd in de officiële BigBlueButton-documentatie.