Webhooks – Zdarzenia w czasie rzeczywistym
BigBlueButton Webhooks pozwalają Twojej aplikacji otrzymywać powiadomienia HTTP POST w czasie rzeczywistym, gdy występują zdarzenia spotkania. Zamiast wielokrotnie odpytywać getMeetings lub getMeetingInfo, rejestrujesz URL callbacku, a BigBlueButton automatycznie wysyła do Ciebie zdarzenia. Ten rozdział omawia trzy endpointy API webhooków, format callbacku, typy zdarzeń, zachowanie ponawiania oraz konfigurację serwera.
Webhooki wymagają zainstalowania pakietu bbb-webhooks na serwerze. Kilka szczegółów opisanych w tym rozdziale nie jest ujętych w oficjalnej dokumentacji BigBlueButton i zostało ustalonych na podstawie analizy kodu źródłowego. undocumented
Wymagania wstępne
Pakiet bbb-webhooks musi zostać zainstalowany na serwerze BigBlueButton, zanim endpointy webhooków staną się dostępne:
sudo apt-get install bbb-webhooks Jeśli aplikacja webhooków nie działa w momencie tworzenia spotkania, nie zostanie ustanowione wewnętrzne mapowanie spotkania. W rezultacie dla tego spotkania nie zostaną wywołane żadne callbacki.
hooks/create — Zarejestruj webhook
GET https://api-guide.bbbserver.com/bigbluebutton/api/hooks/create?<parameters>&checksum=replace-with-checksum Oficjalna dokumentacja nie określa metody HTTP. Router Express rejestruje wyłącznie trasy GET — żądania POST nie są akceptowane. undocumented
| Parametr | Typ | Wymagane | Domyślnie | Opis |
|---|---|---|---|---|
callbackURL | String | Tak | — | URL, który będzie odbierał callbacki POST. Wykrywanie duplikatów opiera się wyłącznie na tym URL-u — tego samego URL-u nie można zarejestrować dwa razy, nawet z innym meetingID lub eventID. |
meetingID | String | Nie | — | Ogranicza hook do konkretnego spotkania (zewnętrzny identyfikator spotkania). Jeśli zostanie pominięty, hook staje się hookiem globalnym, który uruchamia się dla wszystkich spotkań. |
eventID | String | Nie | — | Lista typów zdarzeń rozdzielona przecinkami, których należy nasłuchiwać (np. user-joined,meeting-ended). Jeśli zostanie pominięta, dostarczane są wszystkie zdarzenia. Filtr nie rozróżnia wielkości liter. Dostępne od BBB 2.5. |
getRaw | Boolean | Nie | false | Po ustawieniu na true callbacki zawierają surowy komunikat Redis zamiast przetworzonych danych zdarzenia. |
Pomyślna odpowiedź
<response>
<returncode>SUCCESS</returncode>
<hookID>replace-with-hook-id</hookID>
<permanentHook>false</permanentHook>
<rawData>false</rawData>
</response> Duplikat rejestracji
Jeśli ten sam callbackURL zostanie zarejestrowany ponownie, odpowiedź nadal zwraca SUCCESS, ale zawiera duplicateWarning. Istniejący hook pozostaje bez zmian — meetingID, eventID i getRaw nie są aktualizowane.
<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> Odpowiedzi błędów
messageKey | Opis |
|---|---|
checksumError | Suma kontrolna jest nieprawidłowa lub jej brakuje. |
missingParamCallbackURL | Nie podano parametru callbackURL. undocumented |
createHookError | Wystąpił błąd wewnętrzny (np. Redis jest nieosiągalny). Sprawdź logi serwera. |
hooks/list — Lista zarejestrowanych webhooków
GET https://api-guide.bbbserver.com/bigbluebutton/api/hooks/list?<parameters>&checksum=replace-with-checksum | Parametr | Typ | Wymagane | Opis |
|---|---|---|---|
meetingID | String | Nie | Filtruje według ID spotkania. Wynik obejmuje zarówno hooki dla określonego spotkania, jak i wszystkie hooki globalne. Jeśli pominięto, zwracane są wszystkie zarejestrowane hooki. |
Pomyślna odpowiedź
<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> Element <meetingID> pojawia się tylko dla hooków specyficznych dla spotkania. Hooki globalne nie mają elementu <meetingID>. Podobnie, <eventID> pojawia się tylko wtedy, gdy podczas tworzenia ustawiono filtr zdarzeń.
Odpowiedzi błędów
messageKey | Opis |
|---|---|
checksumError | Suma kontrolna jest nieprawidłowa lub jej brakuje. |
listHookError | Wystąpił błąd wewnętrzny podczas wyświetlania listy hooków. Sprawdź logi serwera. undocumented |
hooks/destroy — Usuń webhook
GET https://api-guide.bbbserver.com/bigbluebutton/api/hooks/destroy?<parameters>&checksum=replace-with-checksum | Parametr | Typ | Wymagane | Opis |
|---|---|---|---|
hookID | String | Tak | ID hooka do usunięcia (uzyskane z hooks/create lub hooks/list). |
Pomyślna odpowiedź
<response>
<returncode>SUCCESS</returncode>
<removed>true</removed>
</response> Hooki trwałe (konfigurowane po stronie serwera przez permanentURLs) nie mogą zostać usunięte przez API. Próba wykonania tej operacji zwraca błąd destroyMissingHook, jak gdyby hook nie istniał.
Odpowiedzi błędów
messageKey | Opis |
|---|---|
checksumError | Suma kontrolna jest nieprawidłowa lub jej brakuje. |
missingParamHookID | Nie podano parametru hookID. |
destroyMissingHook | ID hooka nie istnieje lub należy do trwałego hooka. |
destroyHookError | Wystąpił błąd wewnętrzny podczas usuwania hooka. Sprawdź logi serwera. |
hooks/ping — Kontrola zdrowia
GET https://api-guide.bbbserver.com/bigbluebutton/api/hooks/ping Ten diagnostyczny endpoint nie wymaga sumy kontrolnej. Jeśli aplikacja webhooka jest osiągalna, zwraca zwykły tekst bbb-webhooks API up! (nie XML, typ treści text/plain). undocumented
Format callbacka
Callbacki webhooków są wysyłane jako żądania HTTP POST z typem treści application/x-www-form-urlencoded. Treść żądania zawiera trzy pola:
| Pole | Opis |
|---|---|
domain | Domena serwera (z konfiguracji webhooka). undocumented |
event | Tablica JSON zawierająca dane zdarzenia. Zawsze jest to tablica, nawet dla pojedynczego zdarzenia. |
timestamp | Znacznik czasu Unix w milisekundach w momencie wysłania. |
Treść przetworzonego callbacku (getRaw=false)
domain=myserver.com&event=[{"data":{"type":"event","id":"user-joined","attributes":{...},"event":{"ts":1532718316938}}}]×tamp=1532718316953 Treść surowego callbacku (getRaw=true)
domain=myserver.com&event=[{"envelope":{"name":"UserJoinedMeetingEvtMsg","routing":{"sender":"bbb-apps-akka"}},"core":{"header":{...},"body":{...}}}]×tamp=1532718316953 Gdy serwer jest skonfigurowany z wartością multiEvent większą niż 1, wiele zdarzeń może zostać połączonych w tablicy event w ramach jednego callbacka.
Walidacja sumy kontrolnej callbacka
W trybie domyślnym każdy URL callbacku otrzymuje parametr zapytania checksum, który Twoja aplikacja powinna zweryfikować:
https://api-guide.bbbserver.com/callbacks/webhook?checksum=replace-with-checksum Formuła walidacji jest następująca:
sha<algo>(<callback-URL-without-checksum> + <URL-encoded-body> + <shared-secret>) Weź zarejestrowany URL callbacka bez parametru checksum.
Dołącz pełną treść żądania zakodowaną jako URL (domain=...&event=[...]×tamp=...).
Dołącz współdzielony sekret BBB.
Zahaszuj wynikowy ciąg przy użyciu skonfigurowanego algorytmu (domyślnie: sha1, konfigurowalny przez hookChecksumAlgorithm).
Tryb Auth 2.0 / Bearer
Alternatywnie serwer można skonfigurować z auth2_0: true. W tym trybie do URL-u callbacku nie jest dołączany parametr sumy kontrolnej. Zamiast tego współdzielony sekret jest wysyłany jako token Bearer w nagłówku Authorization: undocumented
Authorization: Bearer <shared-secret> Zachowanie callbacka
- Akceptowane kody statusu HTTP: HTTP
2xxi HTTP401są traktowane jako pomyślne dostarczenie. Wszystkie pozostałe kody statusu powodują ponowienie. undocumented - Przekierowania: Odpowiedzi HTTP
3xxsą śledzone (do 10 przeskoków). Callback jest uznawany za nieudany dopiero wtedy, gdy po 10 przekierowaniach nie zostanie osiągnięty2xx/401. - Limit czasu: Każde żądanie callbacka ma limit czasu 5 sekund (konfigurowalny przez
requestTimeout). - Interwały ponownych prób: W przypadku niepowodzenia ponowne próby używają wykładniczego opóźnienia:
100ms, 500ms, 1s, 2s, 4s, 8s, 10s, 30s, 60s, 60s, 60s, 60s(12 prób w ciągu około 5 minut, konfigurowalne przezretryIntervals). - Po wyczerpaniu wszystkich ponownych prób: Hooki nietrwałe są automatycznie usuwane. Hooki trwałe kontynuują ponawianie bez końca w odstępach 60-sekundowych (konfigurowalne przez
permanentIntervalReset).
Typy zdarzeń
Zdarzenia spotkania
| ID zdarzenia | Opis |
|---|---|
meeting-created | Spotkanie zostało utworzone. |
meeting-ended | Spotkanie zostało zakończone. To wyzwala także syntetyczne zdarzenia user-left dla wszystkich połączonych użytkowników. |
meeting-recording-started | Nagrywanie zostało rozpoczęte. |
meeting-recording-stopped | Nagrywanie zostało zatrzymane. |
meeting-recording-unhandled | Nieobsłużone zdarzenie nagrania (awaryjne, gdy stan nagrania nie jest ani true, ani false). |
meeting-screenshare-started | Rozpoczęto udostępnianie ekranu (zawiera dane użytkownika prezentera). |
meeting-screenshare-stopped | Zatrzymano udostępnianie ekranu (zawiera dane użytkownika właściciela). |
meeting-presentation-changed | Aktywna prezentacja została zmieniona (zawiera presentation-id). |
Zdarzenia użytkownika
| ID zdarzenia | Opis |
|---|---|
user-joined | Użytkownik dołączył do spotkania (zawiera flagę gościa, dane użytkownika, adres IP, User-Agent). |
user-left | Użytkownik opuścił spotkanie (zawiera flagę gościa). Generowane także syntetycznie przy meeting-ended. |
user-audio-voice-enabled | Włączono audio (zawiera flagi listening-only, sharing-mic, muted). |
user-audio-voice-disabled | Dźwięk wyłączony. |
user-audio-muted | Użytkownik został wyciszony. |
user-audio-unmuted | Użytkownik został odciszony. |
user-audio-unhandled | Nieobsłużone zdarzenie audio (awaryjnie). |
user-cam-broadcast-start | Uruchomiono kamerę internetową (zawiera stream-id). |
user-cam-broadcast-end | Kamera internetowa została zatrzymana. |
user-presenter-assigned | Użytkownikowi przypisano rolę prezentera. |
user-presenter-unassigned | Użytkownikowi odebrano rolę prezentera. |
user-emoji-changed | Zmieniono emoji lub reakcję użytkownika (zawiera wartość emoji). |
user-raise-hand-changed | Użytkownik podniósł lub opuścił rękę (zawiera wartość logiczną raise-hand). W wersjach BBB wcześniejszych niż 2.7 jest to generowane syntetycznie z user-emoji-changed. |
Zdarzenia czatu i notatek
| ID zdarzenia | Opis |
|---|---|
chat-group-message-sent | Wysłano wiadomość na czacie publicznym. Prywatne wiadomości czatu nie generują zdarzeń webhook. |
transcript-updated | Zaktualizowano transkrypcję (zawiera transcript, locale, flagę final). |
pad-content | Treść współdzielonych notatek została zmieniona (zawiera pad-id, rev, text). |
Zdarzenia ankiety
| ID zdarzenia | Opis |
|---|---|
poll-started | Rozpoczęto ankietę (zawiera pytanie i opcje odpowiedzi). |
poll-responded | Uczestnik odpowiedział na ankietę (zawiera identyfikatory odpowiedzi). |
Zdarzenia nagrywania i odtwarzania (RAP)
| ID zdarzenia | Opis |
|---|---|
rap-archive-started | Rozpoczęto archiwizację. |
rap-archive-ended | Archiwizacja zakończona (zawiera flagę recorded i czas trwania). |
rap-sanity-started | Rozpoczęto sprawdzanie integralności. |
rap-sanity-ended | Sprawdzanie integralności zakończone. |
rap-post-archive-started | Rozpoczęto czynności po archiwizacji. |
rap-post-archive-ended | Czynności po archiwizacji zakończone. |
rap-process-started | Rozpoczęto przetwarzanie. |
rap-process-ended | Przetwarzanie zakończone. |
rap-post-process-started | Rozpoczęto czynności po przetwarzaniu. |
rap-post-process-ended | Czynności po przetwarzaniu zakończone. |
rap-publish-started | Rozpoczęto publikowanie. |
rap-publish-ended | Publikowanie zakończone (zawiera pełny obiekt nagrania z metadanymi oraz informacjami o odtwarzaniu i pobieraniu). |
rap-post-publish-started | Rozpoczęto czynności po publikowaniu. |
rap-post-publish-ended | Czynności po publikowaniu zakończone. |
rap-published | Nagranie opublikowano. |
rap-unpublished | Cofnięto publikację nagrania. |
rap-deleted | Nagranie usunięto. |
Większość zdarzeń RAP zawiera record-id, success (wartość logiczna) oraz step-time. Zdarzenia z polem workflow dodatkowo zawierają nazwę przepływu pracy przetwarzania.
Konfiguracja serwera
Poniższe opcje można skonfigurować w /etc/bigbluebutton/bbb-webhooks.yml lub config/default.yml. Większość z tych opcji nie jest opisana w oficjalnej dokumentacji. undocumented
| Opcja | Domyślnie | Opis |
|---|---|---|
hookChecksumAlgorithm | sha1 | Algorytm haszujący dla sum kontrolnych callbacków (sha1, sha256, sha384, sha512). |
api.supportedChecksumAlgorithms | [sha1, sha256, sha384, sha512] | Akceptowane algorytmy dla przychodzących sum kontrolnych API. |
api.port | 3005 | Port serwera API webhooków. |
api.bind | 127.0.0.1 | Adres powiązania serwera API. |
includeEvents | [] | Filtr zdarzeń dla całego serwera: tylko te zdarzenia są dostarczane do wszystkich hooków. Puste oznacza wszystkie zdarzenia. |
excludeEvents | [] | Filtr zdarzeń dla całego serwera: te zdarzenia są wykluczane dla wszystkich hooków. Puste oznacza brak wykluczeń. |
permanentURLs | [] | Lista stałych adresów URL hooków rejestrowanych przy uruchomieniu, których nie można usunąć przez API. |
retryIntervals | [100,500,1000,...,60000] | Interwały ponawiania w milisekundach dla nieudanych wywołań zwrotnych. |
permanentIntervalReset | 60000 | Interwał ponawiania w milisekundach dla stałych hooków po wyczerpaniu wszystkich zwykłych prób. |
requestTimeout | 5000 | Limit czasu HTTP w milisekundach dla żądań wywołań zwrotnych. |
multiEvent | 1 | Po ustawieniu wartości większej niż 1 wiele zdarzeń jest łączonych w tablicy zdarzeń dla pojedynczego wywołania zwrotnego. |
queueSize | 10000 | Maksymalny rozmiar wewnętrznej kolejki zdarzeń. |
bbb.auth2_0 | false | Włącza uwierzytelnianie tokenem Bearer zamiast sumy kontrolnej w URL-u dla callbacków. |
includeEvents i excludeEvents to filtry obowiązujące na poziomie całego serwera, które są stosowane dodatkowo do filtra eventID przypisanego do konkretnego hooka. Zdarzenie musi przejść przez oba filtry, aby zostało dostarczone.
Uwagi operacyjne
- Trwałość: Hooki są przechowywane w Redis i przetrwają restarty serwera (są ponownie synchronizowane przy starcie).
- Kolejność: Callbacki są wysyłane sekwencyjnie dla każdego hooka, po jednym na raz, z zachowaniem kolejności zdarzeń.
- Unikalność URL: Wykrywanie duplikatów opiera się wyłącznie na URL-u callbacku. Tego samego URL-u nie można zarejestrować z różnymi filtrami
meetingIDlubeventID— pierwsza rejestracja wygrywa. - Czyszczenie danych: Wewnętrzne mapowania spotkań są usuwane po tygodniu braku aktywności (konfigurowalne przez
mappings.timeout, domyślnie: 604800000 ms). - Zdarzenia syntetyczne: Gdy spotkanie się kończy, zdarzenia
user-leftsą automatycznie generowane dla wszystkich nadal połączonych użytkowników, ponieważ samo BigBlueButton nie emitujeUserLeftMeetingEvtMsgprzy zakończeniu spotkania. - Prywatne czaty: Tylko wiadomości z czatu publicznego generują zdarzenia
chat-group-message-sent. Prywatne wiadomości są po cichu ignorowane.
meetingID — globalne hooki bez meetingID nie są obsługiwane; (2) dane osobowe w zdarzeniach są automatycznie maskowane ze względów prywatności (np. adresy IP uczestników nie są widoczne).Najczęściej zadawane pytania
bbb-webhooks musi zostać zainstalowany przez apt-get install bbb-webhooks. Bez niego endpointy hooks/create, hooks/list i hooks/destroy nie są dostępne.duplicateWarning, a istniejący hook pozostanie bez zmian. Aby osobno monitorować konkretne spotkania, używaj różnych URL-i callbacku.MAIN-PUBLIC-GROUP-CHAT) wywołują zdarzenie chat-group-message-sent. Prywatne wiadomości między uczestnikami nie generują żadnych zdarzeń webhooków.getRaw=false (domyślnym) otrzymujesz przetworzone dane zdarzenia o ustandaryzowanej strukturze zawierającej pola type, id i attributes. W trybie getRaw=true otrzymujesz surowy komunikat Redis publikowany wewnętrznie przez BigBlueButton, który zawiera pola envelope i core. Format surowy jest przydatny do debugowania lub gdy potrzebujesz danych nieuwzględnionych w formacie przetworzonym.permanentURLs i nie mogą być usuwane przez API. Wywołanie hooks/destroy na stałym hooku zwraca błąd destroyMissingHook, jakby hook nie istniał.2xx i HTTP 401 są oba traktowane jako pomyślne dostarczenie. Wszystkie pozostałe kody statusu, w tym 3xx (po wykonaniu maksymalnie 10 przekierowań), 4xx (z wyjątkiem 401) oraz 5xx, powodują ponowienie. Takie zachowanie nie jest udokumentowane w oficjalnej dokumentacji BigBlueButton.