Розділ 17 GET POST

Webhooks – Події в реальному часі

Вебхуки BigBlueButton дозволяють вашому застосунку отримувати HTTP POST-сповіщення в реальному часі щоразу, коли відбуваються події зустрічі. Замість того щоб постійно опитувати getMeetings або getMeetingInfo, ви реєструєте URL-адресу зворотного виклику, і BigBlueButton автоматично надсилає вам події. У цьому розділі розглядаються три кінцеві точки API вебхуків, формат зворотного виклику, типи подій, поведінка повторних спроб і конфігурація сервера.

Для вебхуків потрібно, щоб на сервері було встановлено пакет bbb-webhooks. Кілька деталей, описаних у цьому розділі, не охоплені офіційною документацією BigBlueButton і були визначені шляхом аналізу вихідного коду. undocumented

Передумови

Пакет bbb-webhooks має бути встановлено на сервері BigBlueButton, перш ніж стануть доступними кінцеві точки вебхуків:

sudo apt-get install bbb-webhooks

Якщо застосунок webhook не працює в момент створення зустрічі, внутрішнє зіставлення зустрічі не буде встановлено. У результаті для цієї зустрічі не буде викликано жодних callback.

hooks/create — зареєструвати вебхук

GET https://api-guide.bbbserver.com/bigbluebutton/api/hooks/create?<parameters>&checksum=replace-with-checksum

Офіційна документація не визначає HTTP-метод. Маршрутизатор Express реєструє лише маршрути GET — запити POST не приймаються. undocumented

Параметр Тип Обов’язково За замовчуванням Опис
callbackURL String Так URL-адреса, яка отримуватиме зворотні виклики POST. Виявлення дублікатів базується виключно на цій URL-адресі — ту саму URL-адресу не можна зареєструвати двічі, навіть з іншим meetingID або eventID.
meetingID String Ні Обмежує webhook конкретною зустріччю (зовнішній ідентифікатор зустрічі). Якщо параметр пропущено, webhook стає глобальним і спрацьовує для всіх зустрічей.
eventID String Ні Список типів подій, розділених комами, які слід відстежувати (наприклад, user-joined,meeting-ended). Якщо параметр пропущено, доставляються всі події. Фільтр нечутливий до регістру. Доступно з BBB 2.5.
getRaw Boolean Ні false Якщо встановлено в true, зворотні виклики містять сире повідомлення Redis замість оброблених даних події.

Успішна відповідь

<response>
  <returncode>SUCCESS</returncode>
    <hookID>replace-with-hook-id</hookID>
  <permanentHook>false</permanentHook>
  <rawData>false</rawData>
</response>

Дубльована реєстрація

Якщо той самий callbackURL реєструється знову, відповідь однаково повертає SUCCESS, але містить duplicateWarning. Існуючий webhook залишається без змін — meetingID, eventID і getRaw не оновлюються.

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

Відповіді з помилками

messageKey Опис
checksumError Контрольна сума недійсна або відсутня.
missingParamCallbackURL Параметр callbackURL не було надано. undocumented
createHookError Сталася внутрішня помилка (наприклад, Redis недоступний). Перевірте журнали сервера.

hooks/list — перелік зареєстрованих вебхуків

GET https://api-guide.bbbserver.com/bigbluebutton/api/hooks/list?<parameters>&checksum=replace-with-checksum
Параметр Тип Обов’язково Опис
meetingID String Ні Фільтрує за ID зустрічі. Результат містить як хуки для вказаної зустрічі, так і всі глобальні хуки. Якщо параметр не вказано, повертаються всі зареєстровані хуки.

Успішна відповідь

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

Елемент <meetingID> з’являється лише для хуків, прив’язаних до конкретної зустрічі. Глобальні хуки не мають елемента <meetingID>. Так само, <eventID> з’являється лише тоді, коли під час створення було встановлено фільтр подій.

Відповіді з помилками

messageKey Опис
checksumError Контрольна сума недійсна або відсутня.
listHookError Під час отримання списку хуків сталася внутрішня помилка. Перевірте журнали сервера. undocumented

hooks/destroy — видалити вебхук

GET https://api-guide.bbbserver.com/bigbluebutton/api/hooks/destroy?<parameters>&checksum=replace-with-checksum
Параметр Тип Обов’язково Опис
hookID String Так ID хука, який потрібно видалити (отриманий із hooks/create або hooks/list).

Успішна відповідь

<response>
  <returncode>SUCCESS</returncode>
  <removed>true</removed>
</response>

Постійні хуки (налаштовані на боці сервера через permanentURLs) не можна видалити через API. Спроба зробити це повертає помилку destroyMissingHook, ніби такого хука не існує.

Відповіді з помилками

messageKey Опис
checksumError Контрольна сума недійсна або відсутня.
missingParamHookID Параметр hookID не було надано.
destroyMissingHook ID хука не існує або належить постійному хуку.
destroyHookError Під час видалення хука сталася внутрішня помилка. Перевірте журнали сервера.

hooks/ping — перевірка працездатності

GET https://api-guide.bbbserver.com/bigbluebutton/api/hooks/ping

Ця діагностична кінцева точка не потребує контрольної суми. Якщо застосунок вебхука доступний, вона повертає рядок звичайного тексту bbb-webhooks API up! (не XML, тип вмісту text/plain). undocumented

Формат зворотного виклику

Зворотні виклики вебхука надсилаються як запити HTTP POST з типом вмісту application/x-www-form-urlencoded. Тіло запиту містить три поля:

Поле Опис
domain Домен сервера (із конфігурації вебхука). undocumented
event Масив JSON, що містить дані події. Завжди масив, навіть для однієї події.
timestamp Мітка часу Unix у мілісекундах на момент відправлення.

Тіло обробленого зворотного виклику (getRaw=false)

domain=myserver.com&event=[{"data":{"type":"event","id":"user-joined","attributes":{...},"event":{"ts":1532718316938}}}]&timestamp=1532718316953

Тіло сирого зворотного виклику (getRaw=true)

domain=myserver.com&event=[{"envelope":{"name":"UserJoinedMeetingEvtMsg","routing":{"sender":"bbb-apps-akka"}},"core":{"header":{...},"body":{...}}}]&timestamp=1532718316953

Коли сервер налаштовано зі значенням multiEvent більшим за 1, кілька подій можуть бути об’єднані в масиві event в межах одного зворотного виклику.

Перевірка контрольної суми зворотного виклику

У типовому режимі кожна URL-адреса зворотного виклику отримує параметр запиту checksum, який ваш застосунок повинен перевірити:

https://api-guide.bbbserver.com/callbacks/webhook?checksum=replace-with-checksum

Формула перевірки така:

sha<algo>(<callback-URL-without-checksum> + <URL-encoded-body> + <shared-secret>)

Візьміть зареєстрований URL зворотного виклику без параметра checksum.

Додайте повністю URL-кодоване тіло запиту (domain=...&event=[...]&timestamp=...).

Додайте спільний секрет BBB.

Обчисліть хеш отриманого рядка за допомогою налаштованого алгоритму (типово: sha1, можна налаштувати через hookChecksumAlgorithm).

Режим Auth 2.0 / Bearer

Альтернативно сервер можна налаштувати за допомогою auth2_0: true. У цьому режимі параметр контрольної суми не додається до URL-адреси зворотного виклику. Натомість спільний секрет надсилається як токен Bearer у заголовку Authorization: undocumented

Authorization: Bearer <shared-secret>

Поведінка зворотного виклику

  • Прийняті коди стану HTTP: HTTP 2xx і HTTP 401 вважаються успішною доставкою. Усі інші коди стану спричиняють повторну спробу. undocumented
  • Перенаправлення: відповіді HTTP 3xx обробляються (до 10 переходів). Лише якщо після 10 перенаправлень не буде досягнуто 2xx/401, зворотний виклик вважається невдалим.
  • Тайм-аут: Кожен запит зворотного виклику має тайм-аут 5 секунд (можна налаштувати через requestTimeout).
  • Інтервали повторних спроб: У разі помилки повторні спроби використовують експоненційне збільшення інтервалів: 100ms, 500ms, 1s, 2s, 4s, 8s, 10s, 30s, 60s, 60s, 60s, 60s (12 спроб протягом приблизно 5 хвилин, можна налаштувати через retryIntervals).
  • Після вичерпання всіх повторних спроб: Непостійні хуки автоматично видаляються. Постійні хуки продовжують повторні спроби безстроково з інтервалом 60 секунд (можна налаштувати через permanentIntervalReset).

Типи подій

Події зустрічі

ID події Опис
meeting-created Зустріч була створена.
meeting-ended Зустріч завершилася. Це також спричиняє синтетичні події user-left для всіх підключених користувачів.
meeting-recording-started Запис розпочато.
meeting-recording-stopped Запис зупинено.
meeting-recording-unhandled Необроблена подія запису (резервний варіант, коли статус запису не є ні true, ні false).
meeting-screenshare-started Почато демонстрацію екрана (включає дані користувача-доповідача).
meeting-screenshare-stopped Демонстрацію екрана зупинено (включає дані користувача-власника).
meeting-presentation-changed Активну презентацію змінено (включає presentation-id).

Події користувача

ID події Опис
user-joined Користувач приєднався до зустрічі (включає ознаку гостя, дані користувача, IP-адресу, User-Agent).
user-left Користувач залишив зустріч (включає прапорець гостя). Також генерується синтетично під час meeting-ended.
user-audio-voice-enabled Аудіо увімкнено (включає прапорці listening-only, sharing-mic, muted).
user-audio-voice-disabled Аудіо вимкнено.
user-audio-muted Користувача було вимкнено звук.
user-audio-unmuted Користувачу було ввімкнено звук.
user-audio-unhandled Необроблена аудіоподія (резервний варіант).
user-cam-broadcast-start Вебкамера запущена (включає stream-id).
user-cam-broadcast-end Вебкамеру зупинено.
user-presenter-assigned Користувачу було призначено роль ведучого.
user-presenter-unassigned Користувача було позбавлено ролі ведучого.
user-emoji-changed Змінено емодзі або реакцію користувача (включає значення емодзі).
user-raise-hand-changed Користувач підняв або опустив руку (включає булеве значення raise-hand). У версіях BBB до 2.7 це генерується синтетично з user-emoji-changed.

Події чату та нотаток

ID події Опис
chat-group-message-sent Повідомлення було надіслано в публічний чат. Повідомлення приватного чату не генерують webhook-подій.
transcript-updated Транскрипцію оновлено (включає transcript, locale, прапорець final).
pad-content Вміст спільних нотаток змінено (включає pad-id, rev, text).

Події опитувань

ID події Опис
poll-started Опитування було розпочато (включає запитання та варіанти відповідей).
poll-responded Учасник відповів на опитування (включає ID відповідей).

Події запису та відтворення (RAP)

ID події Опис
rap-archive-started Архівування розпочато.
rap-archive-ended Архівування завершено (включає прапорець recorded і тривалість).
rap-sanity-started Перевірку цілісності розпочато.
rap-sanity-ended Перевірку цілісності завершено.
rap-post-archive-started Післяархівну обробку розпочато.
rap-post-archive-ended Післяархівну обробку завершено.
rap-process-started Обробку розпочато.
rap-process-ended Обробку завершено.
rap-post-process-started Післяобробку розпочато.
rap-post-process-ended Післяобробку завершено.
rap-publish-started Публікацію розпочато.
rap-publish-ended Публікацію завершено (включає повний об’єкт запису з метаданими, інформацією про відтворення та завантаження).
rap-post-publish-started Післяпублікаційну обробку розпочато.
rap-post-publish-ended Післяпублікаційну обробку завершено.
rap-published Запис опубліковано.
rap-unpublished Публікацію запису скасовано.
rap-deleted Запис видалено.

Більшість подій RAP включають record-id, success (булеве значення) і step-time. Події з полем workflow додатково містять назву робочого процесу обробки.

Конфігурація сервера

Наведені нижче параметри можна налаштувати в /etc/bigbluebutton/bbb-webhooks.yml або config/default.yml. Більшість із них не описано в офіційній документації. undocumented

Варіант За замовчуванням Опис
hookChecksumAlgorithm sha1 Алгоритм хешування для контрольних сум зворотних викликів (sha1, sha256, sha384, sha512).
api.supportedChecksumAlgorithms [sha1, sha256, sha384, sha512] Прийнятні алгоритми для вхідних контрольних сум API.
api.port 3005 Порт сервера API webhook.
api.bind 127.0.0.1 Адреса прив’язки сервера API.
includeEvents [] Глобальний фільтр подій сервера: лише ці події надсилаються до всіх hook-ів. Порожнє значення означає всі події.
excludeEvents [] Глобальний фільтр подій сервера: ці події пригнічуються для всіх hook-ів. Порожнє значення означає відсутність виключень.
permanentURLs [] Список постійних URL hook-ів, які реєструються під час запуску і не можуть бути видалені через API.
retryIntervals [100,500,1000,...,60000] Інтервали повторних спроб у мілісекундах для callback-запитів, що завершилися невдачею.
permanentIntervalReset 60000 Інтервал повторної спроби в мілісекундах для постійних hook-ів після вичерпання всіх звичайних повторних спроб.
requestTimeout 5000 Тайм-аут HTTP у мілісекундах для callback-запитів.
multiEvent 1 Якщо встановлено значення більше 1, кілька подій об’єднуються в масиві подій для одного callback-виклику.
queueSize 10000 Максимальний розмір внутрішньої черги подій.
bbb.auth2_0 false Увімкнює автентифікацію токеном Bearer замість контрольної суми URL для зворотних викликів.

includeEvents і excludeEvents — це загальносерверні фільтри, які застосовуються додатково до фільтра eventID для кожного hook. Щоб подію було доставлено, вона має пройти обидва фільтри.

Операційні примітки

  • Збереження: Хуки зберігаються в Redis і переживають перезапуск сервера (повторно синхронізуються під час запуску).
  • Порядок: Зворотні виклики надсилаються послідовно для кожного hook, по одному за раз, із збереженням порядку подій.
  • Унікальність URL: Виявлення дублікатів базується виключно на URL-адресі зворотного виклику. Ту саму URL-адресу не можна зареєструвати з іншими фільтрами meetingID або eventID — перша реєстрація має пріоритет.
  • Очищення даних: Внутрішні зіставлення meeting видаляються після одного тижня неактивності (налаштовується через mappings.timeout, типово: 604800000 мс).
  • Синтетичні події: Коли зустріч завершується, події user-left автоматично генеруються для всіх користувачів, які все ще підключені, тому що сам BigBlueButton не генерує UserLeftMeetingEvtMsg під час завершення зустрічі.
  • Приватні чати: Лише повідомлення публічного чату генерують події chat-group-message-sent. Приватні повідомлення тихо ігноруються.
На bbbserver.de вебхуки доступні з двома обмеженнями: (1) для кожного хука потрібен meetingID — глобальні хуки без meetingID не підтримуються; (2) персональні дані в подіях автоматично обфускуються з міркувань приватності (наприклад, IP-адреси учасників не видно).

Поширені запитання

Так. Пакет bbb-webhooks має бути встановлений через apt-get install bbb-webhooks. Без нього кінцеві точки hooks/create, hooks/list і hooks/destroy недоступні.

Система вебхуків повторює доставку з експоненційним збільшенням інтервалів приблизно протягом 5 хвилин (12 спроб). Якщо всі повторні спроби зазнають невдачі, непостійні hooks автоматично видаляються. Постійні hooks продовжують повторні спроби безстроково з інтервалом 60 секунд.

Ні. Виявлення дублікатів базується виключно на URL-адресі зворотного виклику. Якщо ви знову зареєструєте ту саму URL-адресу, ви отримаєте duplicateWarning, а наявний хук залишиться без змін. Щоб окремо відстежувати конкретні зустрічі, використовуйте різні URL-адреси зворотного виклику.

Ні. Лише повідомлення, надіслані в публічний чат (MAIN-PUBLIC-GROUP-CHAT), запускають подію chat-group-message-sent. Приватні повідомлення між учасниками не генерують жодних подій вебхуків.

З getRaw=false (типовий режим) ви отримуєте оброблені дані подій зі стандартизованою структурою, що містить поля type, id і attributes. З getRaw=true ви отримуєте сире повідомлення Redis, опубліковане внутрішньо BigBlueButton, яке містить поля envelope і core. Сирий формат корисний для налагодження або коли вам потрібні дані, яких немає в обробленому форматі.

Ні. Постійні хуки налаштовуються на стороні сервера через параметр permanentURLs і не можуть бути видалені через API. Виклик hooks/destroy для постійного хука повертає помилку destroyMissingHook так, ніби такого хука не існує.

HTTP 2xx і HTTP 401 обидва вважаються успішною доставкою. Усі інші коди стану, включно з 3xx (після виконання до 10 перенаправлень), 4xx (крім 401) і 5xx, спричиняють повторну спробу. Ця поведінка не задокументована в офіційній документації BigBlueButton.
Посібник з API BigBlueButton