Chapitre 17 GET POST

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}}}]&timestamp=1532718316953

Corps du callback brut (getRaw=true)

domain=myserver.com&event=[{"envelope":{"name":"UserJoinedMeetingEvtMsg","routing":{"sender":"bbb-apps-akka"}},"core":{"header":{...},"body":{...}}}]&timestamp=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=[...]&timestamp=...).

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 2xx et HTTP 401 sont traités comme une livraison réussie. Tous les autres codes de statut déclenchent une nouvelle tentative. undocumented
  • Redirections : Les réponses HTTP 3xx sont suivies (jusqu’à 10 sauts). Ce n’est que si aucun 2xx/401 n’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 via retryIntervals).
  • 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 meetingID ou eventID diffé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-left sont automatiquement générés pour tous les utilisateurs encore connectés, car BigBlueButton lui-même n’émet pas UserLeftMeetingEvtMsg à 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.
Sur bbbserver.de, les webhooks sont disponibles avec deux restrictions : (1) un 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

Oui. Le package 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.

Le système de webhook réessaie la livraison avec un back-off exponentiel pendant environ 5 minutes (12 tentatives). Si toutes les tentatives échouent, les hooks non permanents sont automatiquement supprimés. Les hooks permanents continuent de réessayer indéfiniment à des intervalles de 60 secondes.

Non. La détection des doublons repose uniquement sur l’URL de callback. Si vous enregistrez à nouveau la même URL, vous recevez un duplicateWarning et le hook existant reste inchangé. Pour surveiller séparément des réunions spécifiques, utilisez des URL de callback distinctes.

Non. Seuls les messages envoyés au chat public (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.

Avec 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é.

Non. Les hooks permanents sont configurés côté serveur via le paramètre 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.

HTTP 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.