Rozdział 17 GET POST

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

Treść surowego callbacku (getRaw=true)

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

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 2xx i HTTP 401 są traktowane jako pomyślne dostarczenie. Wszystkie pozostałe kody statusu powodują ponowienie. undocumented
  • Przekierowania: Odpowiedzi HTTP 3xx są śledzone (do 10 przeskoków). Callback jest uznawany za nieudany dopiero wtedy, gdy po 10 przekierowaniach nie zostanie osiągnięty 2xx/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 przez retryIntervals).
  • 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 meetingID lub eventID — 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-left są automatycznie generowane dla wszystkich nadal połączonych użytkowników, ponieważ samo BigBlueButton nie emituje UserLeftMeetingEvtMsg przy zakończeniu spotkania.
  • Prywatne czaty: Tylko wiadomości z czatu publicznego generują zdarzenia chat-group-message-sent. Prywatne wiadomości są po cichu ignorowane.
Na bbbserver.de webhooki są dostępne z dwoma ograniczeniami: (1) dla każdego hooka wymagane jest 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

Tak. Pakiet 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.

System webhooków ponawia próby dostarczenia z wykładniczo rosnącymi odstępami przez około 5 minut (12 prób). Jeśli wszystkie próby się nie powiodą, hooki nietrwałe są automatycznie usuwane. Hooki trwałe kontynuują ponawianie bezterminowo w odstępach 60-sekundowych.

Nie. Wykrywanie duplikatów opiera się wyłącznie na URL-u callbacku. Jeśli ponownie zarejestrujesz ten sam URL, otrzymasz duplicateWarning, a istniejący hook pozostanie bez zmian. Aby osobno monitorować konkretne spotkania, używaj różnych URL-i callbacku.

Nie. Tylko wiadomości wysłane na czat publiczny (MAIN-PUBLIC-GROUP-CHAT) wywołują zdarzenie chat-group-message-sent. Prywatne wiadomości między uczestnikami nie generują żadnych zdarzeń webhooków.

W trybie 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.

Nie. Stałe hooki są konfigurowane po stronie serwera za pomocą ustawienia permanentURLs i nie mogą być usuwane przez API. Wywołanie hooks/destroy na stałym hooku zwraca błąd destroyMissingHook, jakby hook nie istniał.

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