Webhooks – Événements en temps réel
Les webhooks BigBlueButton permettent à votre application de recevoir des notifications HTTP POST en temps réel chaque fois que des événements de réunion se produisent. Au lieu d’interroger en boucle getMeetings ou getMeetingInfo, vous enregistrez une URL de callback et BigBlueButton vous envoie automatiquement les événements. Ce chapitre couvre les trois points de terminaison API de webhook, le format des callbacks, les types d’événements, le comportement de nouvelle tentative et la configuration du serveur.
Les webhooks nécessitent que le package bbb-webhooks soit installé sur le serveur. Plusieurs détails décrits dans ce chapitre ne sont pas couverts par la documentation officielle BigBlueButton et ont été déterminés par analyse du code source. undocumented
Prérequis
Le package bbb-webhooks doit être installé sur le serveur BigBlueButton avant que les points de terminaison webhook deviennent disponibles :
sudo apt-get install bbb-webhooks Si l’application webhook n’est pas en cours d’exécution lorsqu’une réunion est créée, aucun mappage interne de réunion n’est établi. Par conséquent, aucun callback ne sera déclenché pour cette réunion.
hooks/create — Enregistrer un webhook
GET https://api-guide.bbbserver.com/bigbluebutton/api/hooks/create?<parameters>&checksum=replace-with-checksum La documentation officielle ne spécifie pas de méthode HTTP. Le routeur Express n’enregistre que des routes GET — les requêtes POST ne sont pas acceptées. undocumented
| Paramètre | Type | Obligatoire | Par défaut | Description |
|---|---|---|---|---|
callbackURL | String | Oui | — | L’URL qui recevra les callbacks POST. La détection des doublons est basée uniquement sur cette URL — la même URL ne peut pas être enregistrée deux fois, même avec un meetingID ou un eventID différent. |
meetingID | String | Non | — | Restreint le hook à une réunion spécifique (identifiant externe de réunion). S’il est omis, le hook devient un hook global qui se déclenche pour toutes les réunions. |
eventID | String | Non | — | Liste de types d’événements séparés par des virgules à écouter (par ex. user-joined,meeting-ended). Si elle est omise, tous les événements sont livrés. Le filtre est insensible à la casse. Disponible depuis BBB 2.5. |
getRaw | Boolean | Non | false | Lorsqu’il est défini sur true, les callbacks contiennent le message Redis brut au lieu des données d’événement traitées. |
Réponse réussie
<response>
<returncode>SUCCESS</returncode>
<hookID>replace-with-hook-id</hookID>
<permanentHook>false</permanentHook>
<rawData>false</rawData>
</response> Enregistrement en double
Si le même callbackURL est enregistré à nouveau, la réponse renvoie toujours SUCCESS mais inclut un duplicateWarning. Le hook existant est conservé sans modification — meetingID, eventID et getRaw ne sont pas mis à jour.
<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> Réponses d’erreur
messageKey | Description |
|---|---|
checksumError | La checksum est invalide ou absente. |
missingParamCallbackURL | Le paramètre callbackURL n’a pas été fourni. undocumented |
createHookError | Une erreur interne s’est produite (par ex. Redis inaccessible). Vérifiez les journaux du serveur. |
hooks/list — Lister les webhooks enregistrés
GET https://api-guide.bbbserver.com/bigbluebutton/api/hooks/list?<parameters>&checksum=replace-with-checksum | Paramètre | Type | Obligatoire | Description |
|---|---|---|---|
meetingID | String | Non | Filtre par ID de réunion. Le résultat inclut à la fois les hooks pour la réunion spécifiée et tous les hooks globaux. Si omis, tous les hooks enregistrés sont renvoyés. |
Réponse réussie
<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’élément <meetingID> n’apparaît que pour les hooks spécifiques à une réunion. Les hooks globaux n’ont pas d’élément <meetingID>. De même, <eventID> n’apparaît que lorsqu’un filtre d’événement a été défini lors de la création.
Réponses d’erreur
messageKey | Description |
|---|---|
checksumError | La checksum est invalide ou absente. |
listHookError | Une erreur interne s’est produite lors de la liste des hooks. Vérifiez les journaux du serveur. undocumented |
hooks/destroy — Supprimer un webhook
GET https://api-guide.bbbserver.com/bigbluebutton/api/hooks/destroy?<parameters>&checksum=replace-with-checksum | Paramètre | Type | Obligatoire | Description |
|---|---|---|---|
hookID | String | Oui | L’ID du hook à supprimer (obtenu via hooks/create ou hooks/list). |
Réponse réussie
<response>
<returncode>SUCCESS</returncode>
<removed>true</removed>
</response> Les hooks permanents (configurés côté serveur via permanentURLs) ne peuvent pas être supprimés via l’API. Toute tentative renvoie une erreur destroyMissingHook comme si le hook n’existait pas.
Réponses d’erreur
messageKey | Description |
|---|---|
checksumError | La checksum est invalide ou absente. |
missingParamHookID | Le paramètre hookID n’a pas été fourni. |
destroyMissingHook | L’ID du hook n’existe pas ou appartient à un hook permanent. |
destroyHookError | Une erreur interne s’est produite lors de la suppression du hook. Vérifiez les journaux du serveur. |
hooks/ping — Vérification de l’état
GET https://api-guide.bbbserver.com/bigbluebutton/api/hooks/ping Ce point de terminaison de diagnostic ne nécessite aucune somme de contrôle. Si l’application webhook est joignable, il renvoie la chaîne en texte brut bbb-webhooks API up! (pas du XML, type de contenu text/plain). undocumented
Format du callback
Les callbacks webhook sont envoyés sous forme de requêtes HTTP POST avec le type de contenu application/x-www-form-urlencoded. Le corps de la requête contient trois champs :
| Champ | Description |
|---|---|
domain | Le domaine du serveur (issu de la configuration du webhook). undocumented |
event | Un tableau JSON contenant les données de l’événement. Toujours un tableau, même pour un seul événement. |
timestamp | Un horodatage Unix en millisecondes au moment de l’envoi. |
Corps du callback traité (getRaw=false)
domain=myserver.com&event=[{"data":{"type":"event","id":"user-joined","attributes":{...},"event":{"ts":1532718316938}}}]×tamp=1532718316953 Corps du callback brut (getRaw=true)
domain=myserver.com&event=[{"envelope":{"name":"UserJoinedMeetingEvtMsg","routing":{"sender":"bbb-apps-akka"}},"core":{"header":{...},"body":{...}}}]×tamp=1532718316953 Lorsque le serveur est configuré avec une valeur multiEvent supérieure à 1, plusieurs événements peuvent être regroupés dans le tableau event au sein d’un seul callback.
Validation de la somme de contrôle du callback
Dans le mode par défaut, chaque URL de callback reçoit un paramètre de requête checksum que votre application doit vérifier :
https://api-guide.bbbserver.com/callbacks/webhook?checksum=replace-with-checksum La formule de validation est :
sha<algo>(<callback-URL-without-checksum> + <URL-encoded-body> + <shared-secret>) Prenez l’URL de callback enregistrée sans le paramètre checksum.
Ajoutez le corps complet de la requête encodé en URL (domain=...&event=[...]×tamp=...).
Ajoutez le secret partagé BBB.
Hachez la chaîne résultante avec l’algorithme configuré (par défaut : sha1, configurable via hookChecksumAlgorithm).
Mode Auth 2.0 / Bearer
Alternativement, le serveur peut être configuré avec auth2_0: true. Dans ce mode, aucun paramètre checksum n’est ajouté à l’URL de callback. À la place, le secret partagé est envoyé comme jeton Bearer dans l’en-tête Authorization : undocumented
Authorization: Bearer <shared-secret> Comportement du callback
- Codes de statut HTTP acceptés : HTTP
2xxet HTTP401sont traités comme une livraison réussie. Tous les autres codes de statut déclenchent une nouvelle tentative. undocumented - Redirections : Les réponses HTTP
3xxsont suivies (jusqu’à 10 sauts). Ce n’est que si aucun2xx/401n’est atteint après 10 redirections que le callback est considéré comme ayant échoué. - Délai d’expiration : chaque requête de callback a un délai d’expiration de 5 secondes (configurable via
requestTimeout). - Intervalles de nouvelle tentative : en cas d’échec, les nouvelles tentatives utilisent un back-off exponentiel :
100ms, 500ms, 1s, 2s, 4s, 8s, 10s, 30s, 60s, 60s, 60s, 60s(12 tentatives sur environ 5 minutes, configurable viaretryIntervals). - Après l’épuisement de toutes les tentatives : les hooks non permanents sont supprimés automatiquement. Les hooks permanents continuent les nouvelles tentatives indéfiniment à des intervalles de 60 secondes (configurable via
permanentIntervalReset).
Types d’événements
Événements de réunion
| ID d’événement | Description |
|---|---|
meeting-created | Une réunion a été créée. |
meeting-ended | Une réunion est terminée. Cela déclenche également des événements user-left synthétiques pour tous les utilisateurs connectés. |
meeting-recording-started | L’enregistrement a démarré. |
meeting-recording-stopped | L’enregistrement s’est arrêté. |
meeting-recording-unhandled | Événement d’enregistrement non géré (repli lorsque l’état de l’enregistrement n’est ni true ni false). |
meeting-screenshare-started | Le partage d’écran a démarré (inclut les données utilisateur du présentateur). |
meeting-screenshare-stopped | Le partage d’écran s’est arrêté (inclut les données utilisateur du propriétaire). |
meeting-presentation-changed | La présentation active a changé (inclut presentation-id). |
Événements utilisateur
| ID d’événement | Description |
|---|---|
user-joined | Un utilisateur a rejoint la réunion (inclut le drapeau invité, les données utilisateur, l’adresse IP, User-Agent). |
user-left | Un utilisateur a quitté la réunion (inclut l’indicateur invité). Également généré de façon synthétique sur meeting-ended. |
user-audio-voice-enabled | Audio activé (inclut les indicateurs listening-only, sharing-mic, muted). |
user-audio-voice-disabled | Audio désactivé. |
user-audio-muted | L’utilisateur a été mis en sourdine. |
user-audio-unmuted | L’utilisateur n’est plus en sourdine. |
user-audio-unhandled | Événement audio non géré (secours). |
user-cam-broadcast-start | Webcam démarrée (inclut stream-id). |
user-cam-broadcast-end | La webcam a été arrêtée. |
user-presenter-assigned | Le rôle de présentateur a été attribué à l’utilisateur. |
user-presenter-unassigned | Le rôle de présentateur a été retiré à l’utilisateur. |
user-emoji-changed | L’emoji ou la réaction de l’utilisateur a changé (inclut la valeur de l’emoji). |
user-raise-hand-changed | L’utilisateur a levé ou baissé la main (inclut le booléen raise-hand). Sur les versions BBB antérieures à 2.7, cela est généré synthétiquement à partir de user-emoji-changed. |
Événements de chat et de notes
| ID d’événement | Description |
|---|---|
chat-group-message-sent | Un message a été envoyé dans le chat public. Les messages de chat privé ne génèrent pas d’événements webhook. |
transcript-updated | Transcription mise à jour (inclut transcript, locale, indicateur final). |
pad-content | Le contenu des notes partagées a changé (inclut pad-id, rev, text). |
Événements de sondage
| ID d’événement | Description |
|---|---|
poll-started | Un sondage a été lancé (inclut la question et les options de réponse). |
poll-responded | Un participant a répondu à un sondage (inclut les ID des réponses). |
Événements Enregistrement et Lecture (RAP)
| ID d’événement | Description |
|---|---|
rap-archive-started | L’archivage a commencé. |
rap-archive-ended | Archivage terminé (inclut l’indicateur recorded et la durée). |
rap-sanity-started | La vérification d’intégrité a commencé. |
rap-sanity-ended | La vérification d’intégrité est terminée. |
rap-post-archive-started | Le post-archivage a commencé. |
rap-post-archive-ended | Le post-archivage est terminé. |
rap-process-started | Le traitement a commencé. |
rap-process-ended | Le traitement est terminé. |
rap-post-process-started | Le post-traitement a commencé. |
rap-post-process-ended | Le post-traitement est terminé. |
rap-publish-started | La publication a commencé. |
rap-publish-ended | La publication est terminée (inclut l’objet d’enregistrement complet avec les métadonnées, les informations de lecture et de téléchargement). |
rap-post-publish-started | Le post-publication a commencé. |
rap-post-publish-ended | Le post-publication est terminé. |
rap-published | L’enregistrement a été publié. |
rap-unpublished | L’enregistrement a été dépublié. |
rap-deleted | L’enregistrement a été supprimé. |
La plupart des événements RAP incluent record-id, success (booléen) et step-time. Les événements avec un champ workflow contiennent en plus le nom du flux de traitement.
Configuration du serveur
Les options suivantes peuvent être configurées dans /etc/bigbluebutton/bbb-webhooks.yml ou config/default.yml. La plupart de ces options ne sont pas couvertes par la documentation officielle. undocumented
| Option | Par défaut | Description |
|---|---|---|
hookChecksumAlgorithm | sha1 | Algorithme de hachage pour les checksums de callback (sha1, sha256, sha384, sha512). |
api.supportedChecksumAlgorithms | [sha1, sha256, sha384, sha512] | Algorithmes acceptés pour les sommes de contrôle API entrantes. |
api.port | 3005 | Port du serveur API webhook. |
api.bind | 127.0.0.1 | Adresse de liaison du serveur API. |
includeEvents | [] | Filtre d’événements global du serveur : seuls ces événements sont transmis à tous les hooks. Vide signifie tous les événements. |
excludeEvents | [] | Filtre d’événements global du serveur : ces événements sont supprimés pour tous les hooks. Vide signifie aucune exclusion. |
permanentURLs | [] | Liste des URL de hooks permanents enregistrées au démarrage et qui ne peuvent pas être supprimées via l’API. |
retryIntervals | [100,500,1000,...,60000] | Intervalles de nouvelle tentative en millisecondes pour les callbacks en échec. |
permanentIntervalReset | 60000 | Intervalle de nouvelle tentative en millisecondes pour les hooks permanents après épuisement de toutes les tentatives normales. |
requestTimeout | 5000 | Délai d’expiration HTTP en millisecondes pour les requêtes de callback. |
multiEvent | 1 | Lorsqu’une valeur supérieure à 1 est définie, plusieurs événements sont regroupés dans le tableau d’événements par callback. |
queueSize | 10000 | Taille maximale de la file d’attente interne des événements. |
bbb.auth2_0 | false | Active l’authentification par jeton Bearer au lieu du checksum d’URL pour les callbacks. |
includeEvents et excludeEvents sont des filtres à l’échelle du serveur qui s’appliquent en plus du filtre eventID propre à chaque hook. Un événement doit passer les deux filtres pour être livré.
Notes opérationnelles
- Persistance : Les hooks sont stockés dans Redis et survivent aux redémarrages du serveur (resynchronisés au démarrage).
- Ordonnancement : Les callbacks sont envoyés séquentiellement pour chaque hook, un à la fois, en préservant l’ordre des événements.
- Unicité de l’URL : La détection des doublons repose uniquement sur l’URL de callback. La même URL ne peut pas être enregistrée avec des filtres
meetingIDoueventIDdifférents — le premier enregistrement l’emporte. - Nettoyage des données : Les mappages internes des réunions sont supprimés après une semaine d’inactivité (configurable via
mappings.timeout, valeur par défaut : 604800000 ms). - Événements synthétiques : Lorsqu’une réunion se termine, des événements
user-leftsont automatiquement générés pour tous les utilisateurs encore connectés, car BigBlueButton lui-même n’émet pasUserLeftMeetingEvtMsgà la fin de la réunion. - Chats privés : Seuls les messages du chat public génèrent des événements
chat-group-message-sent. Les messages privés sont ignorés silencieusement.
meetingID est requis pour chaque hook — les hooks globaux sans meetingID ne sont pas pris en charge ; (2) les données personnelles dans les événements sont automatiquement masquées pour des raisons de confidentialité (par ex. les adresses IP des participants ne sont pas visibles).Foire aux questions
bbb-webhooks doit être installé via apt-get install bbb-webhooks. Sans lui, les points de terminaison hooks/create, hooks/list et hooks/destroy ne sont pas disponibles.duplicateWarning et le hook existant reste inchangé. Pour surveiller séparément des réunions spécifiques, utilisez des URL de callback distinctes.MAIN-PUBLIC-GROUP-CHAT) déclenchent un événement chat-group-message-sent. Les messages privés entre participants ne génèrent aucun événement de webhook.getRaw=false (par défaut), vous recevez des données d’événement traitées avec une structure standardisée contenant les champs type, id et attributes. Avec getRaw=true, vous recevez le message Redis brut tel que publié en interne par BigBlueButton, qui inclut les champs envelope et core. Le format brut est utile pour le débogage ou lorsque vous avez besoin de données non incluses dans le format traité.permanentURLs et ne peuvent pas être supprimés via l’API. L’appel de hooks/destroy sur un hook permanent renvoie une erreur destroyMissingHook comme si le hook n’existait pas.2xx et HTTP 401 sont tous deux traités comme une livraison réussie. Tous les autres codes de statut, y compris 3xx (après suivi d’un maximum de 10 redirections), 4xx (sauf 401) et 5xx, déclenchent une nouvelle tentative. Ce comportement n’est pas documenté dans la documentation officielle BigBlueButton.