Skip to content

refactor(akka-apps): remove dead bbb-html5 -> akka-apps messages - #27

Closed
antobinary wants to merge 1706 commits into
v4.0.x-developfrom
fix-20095-remove-html5-akka-messages
Closed

antobinary wants to merge 1706 commits into
v4.0.x-developfrom
fix-20095-remove-html5-akka-messages

Conversation

@antobinary

@antobinary antobinary commented Aug 7, 2026 •

Copy link
Copy Markdown
Owner

What this does

Closes bigbluebutton#20095 — removes the client → akka-apps messages that no longer have a
sender, and the outbound messages they leave stranded.

The html5 client stopped publishing to redis when its calls moved to
bbb-graphql-actions, and state reads moved to GraphQL/Hasura. Anything
ReceivedJsonMsgHandlerActor still accepts but nobody sends is dead code.

44 messages removed.

Before After
Inbound messages accepted by akka-apps 208 179
Messages defined in bbb-common-message 447 406

Two commits, so the risky part is reviewable on its own:

Commit Contents Diff
0da4f75746 3 inbound (pads + waiting queue) 10 files, −124
43351d1fbb 26 inbound + 15 stranded outbound 55 files, +16 / −1163

Inbound removed (29)

Initial-state fetches (13) — the client reads this from Hasura now:
GetAllPresentationPodsReqMsg, GetChatHistoryReqMsg, GetCurrentLayoutReqMsg,
GetCurrentPollReqMsg, GetGroupChatMsgsReqMsg, GetGroupChatsReqMsg,
GetGuestPolicyReqMsg, GetGuestsWaitingApprovalReqMsg,
GetPresenterGroupReqMsg, GetScreenshareStatusReqMsg,
GetWebcamsOnlyForModeratorReqMsg, GetWhiteboardAnnotationsReqMsg,
IsMeetingMutedReqMsg

Chat (2), superseded by group chat in 2018 — SendPublicMessagePubMsg,
SendPrivateMessagePubMsg

Presenter group (2), feature removed 2018 — AddUserToPresenterGroupCmdMsg,
RemoveUserFromPresenterGroupCmdMsg

Presentation pods (4) — CreateNewPresentationPodPubMsg,
RemovePresentationPodPubMsg, SlideResizedPubMsg,
PreuploadedPresentationsSysPubMsg

Pads / waiting queue (3) — PadCreateReqMsg, PadUpdatePubMsg,
UpdatePositionInWaitingQueueReqMsg

Other (5) — BreakoutRoomsListMsg, LockUsersInMeetingCmdMsg,
EjectUserFromMeetingSysMsg, RecordAndClearPreviousMarkersCmdMsg,
ClientToServerLatencyTracerMsg

Outbound removed (15)

These lost their only emitter when the inbound side went, so they are removed in
the same change rather than left as new dead code:

GetAllPresentationPodsRespMsg, GetChatHistoryRespMsg,
GetCurrentLayoutRespMsg, GetCurrentPollRespMsg, GetGroupChatMsgsRespMsg,
GetGroupChatsRespMsg, GetGuestPolicyRespMsg,
GetWebcamsOnlyForModeratorRespMsg, GetWhiteboardAnnotationsRespMsg,
IsMeetingMutedRespMsg, NewPresentationEvtMsg, SendPrivateMessageEvtMsg,
ServerToClientLatencyTracerMsg, PadUpdateCmdMsg,
PosInWaitingQueueUpdatedRespMsg

Plus the helpers that built them: Polls.handleGetCurrentPollReqMsg,
PresentationApp2x.processPreuploadedPresentations, the
NewPresentationMsgHdlr trait, MsgBuilder.buildPosInWaitingQueueUpdatedRespMsg,
and the GuestWaitingUP VO that only PosInWaitingQueueUpdatedRespMsg used.

Verified invariant: 25 messages in bbb-common-message have no emitter after
this PR, and all 25 were already in that state on v4.1.x-develop. No message
that had an emitter before this change is left without one.

Notes for reviewers

LayoutApp2x now declares val liveMeeting: LiveMeeting itself. It inherited
that declaration from GetCurrentLayoutReqMsgHdlr, and its sibling handler
traits resolve liveMeeting through the mixin.

Pad creation is unaffected — akka-apps drives it via
PadslHdlrHelpers.broadcastPadCreateGroupCmdMsg / broadcastPadCreateCmdMsg
from MeetingActor and PadGroupCreatedEvtMsgHdlr. PadCreateReqMsg was only
the old client-initiated entry point.

bbb-pads still has a redis handler for PadUpdateCmdMsg
(lib/redis/handler.js). Nothing has emitted that message since the client
stopped sending PadUpdatePubMsg, so the handler was already unreachable; it can
be dropped on the bbb-pads side separately.

Deliberately NOT removed

GetMediaGroupsReqMsg has no sender either, but it is not legacy. Added
2024-12 as GetAudioGroupsReqMsg, renamed 2025-10 when media groups were
extended to cameras and screenshare; its sibling graphql-actions mutations
(mediaGroupCreate/Destroy/Join/Leave/UpdateParticipant) are all live. Looks
like scaffolding for in-flight work — @prlanzarin should confirm before it goes.

UserConnectedToGlobalAudioMsg / UserDisconnectedFromGlobalAudioMsg look
dead from this repo but bbb-webrtc-sfu sends both from
lib/audio/client-audio-consumer.js.

TranscriptionProviderErrorMsg — sent by bbb-transcription-controller
(app.js:199).

CheckGraphqlMiddlewareAlivePongSysMsg, UserGraphqlConnectionEstablishedSysMsg,
UserGraphqlConnectionClosedSysMsg
— sent by bbb-graphql-middleware (Go).

How "no sender" was established

A grep of this repo is not sufficient — several of the near-misses above are sent
from other repos. Each candidate was checked against:

  • every component in this monorepo, including akka-apps constructing the message
    itself, not just handling it;
  • the components installed on a running 4.x server (bbb-webrtc-sfu, bbb-pads,
    bbb-export-annotations, bbb-graphql-actions, etherpad incl.
    ep_redis_publisher, the Ruby recording scripts, freeswitch);
  • jar/war contents via unzip -p | strings;
  • the bbb-graphql-middleware and bbb-webrtc-recorder Go binaries via strings
    (substring, not anchored — Go concatenates string literals);
  • bbb-transcription-controller v0.2.10, bbb-webhooks v3.6.1 and
    bbb-webrtc-recorder v0.14.0 at their pinned placeholder tags;
  • every publisher to to-akka-apps-redis-channel, to confirm none builds a
    message name dynamically;
  • docs/, in case any is a documented integration point;
  • git log -S per message, for senders removed recently enough to be coming back.

A second independent pass re-ran all of this adversarially, instructed to refute
rather than confirm. It is what rescued GetMediaGroupsReqMsg.

Testing

  • bbb-common-message — sbt publishM2 succeeds.
  • akka-bbb-apps — sbt compile succeeds; only pre-existing deprecation warnings.
  • akka-bbb-apps — sbt test does not compile on v4.1.x-develop, with or
    without this change: 54 identical errors in TestDataGen.scala
    (RegisteredUsers.create missing loggedOut; WebcamStream missing
    hasAudio/showAsContent/subscribers). Verified by stashing the change and
    re-running. Filed separately; not addressed here.
  • The MeetingActor diff was reviewed arm by arm: multi-line case m: X =>
    bodies are removed together with their case line. An earlier scripted attempt
    dropped only the case line and silently merged the body into the previous
    arm — it compiled and was wrong. Worth spot-checking in review.

Follow-ups

  • 25 messages in bbb-common-message have no emitter and predate this PR —
    separate issue.
  • bbb-graphql-middleware sends UserGraphqlDisconnectionForcedEvtMsg, which
    akka-apps has never had a handler for — separate issue.
  • akka-bbb-apps test suite does not compile — separate issue.

@antobinary
antobinary force-pushed the fix-20095-remove-html5-akka-messages branch from 5d4ec0b to 43351d1 Compare August 8, 2026 00:28
@antobinary

Copy link
Copy Markdown
Owner Author

Issue 1 — dead outbound messages


Remove dead outbound messages from bbb-common-message

Mirror of bigbluebutton#20095. That issue covered inbound (client → apps) messages with no
sender; this covers messages that are defined but never emitted.

Of 421 messages currently defined in bbb-common-message, 25 are referenced
nowhere outside their own definition
— not in akka-apps, akka-fsesl, bbb-web,
bbb-common-web, bbb-graphql-actions, bbb-shared-notes-server, the html5 client,
bbb-pads, or record-and-playback. Several are also absent from the components
installed on a running 4.x server and from the bbb-graphql-middleware binary.

Request/response pairs whose request side is long gone

GetLockSettingsRespMsg          LockSettingsNotInitializedRespMsg
GetPresenterGroupRespMsg        GetUsersReqMsg
LookUpUserRespMsg               UserSessionTokenRegisteredRespMsg

Group chat events, superseded

GroupChatAccessChangedEvtMsg    GroupChatUserAddedEvtMsg
GroupChatDestroyedEvtMsg        GroupChatUserRemovedEvtMsg
OpenGroupChatWindowEvtMsg

Pads

CaptureSharedNotesReqEvtMsg     PadCapturePubMsg
PadGroupCreatedRespMsg          PadTailEvtMsg

Presentation conversion progress events

PresentationConversionRequestReceivedEventMsg
PresentationPageConversionStartedEventMsg
PresentationUploadedConversionCancelledErrorEvtMsg

Other

CamStreamSubscribeSysMsg        PubSubPingSysReqMsg
TimerEndedPubMsg                PubSubPongSysRespMsg
TransferUserToMeetingEvtMsg     ServerToClientLatencyTracerMsg
UserGraphqlDisconnectionForcedEvtMsg   (see separate issue — middleware sends it)
UserGraphqlReconnectionForcedEvtMsg

Caveats for whoever picks this up

  • A repo grep is not sufficient. While working Remove all bbb-html5 -> akka-apps bbb-common-messages bigbluebutton/bigbluebutton#20095, three messages that
    looked dead here turned out to be sent from other repos: bbb-webrtc-sfu
    (UserConnectedToGlobalAudioMsg), bbb-transcription-controller
    (TranscriptionProviderErrorMsg) and bbb-graphql-middleware. Check the
    installed components, the Go binaries with strings, and the placeholder
    repos at their pinned tags before deleting anything.
  • The presentation-conversion events are the ones I'd scrutinise hardest — they
    look like progress reporting that a UI or the recording pipeline might have
    consumed.
  • Some of these have consumers even though nothing emits them (see the
    separate middleware issue). A consumer without an emitter is a dead feature,
    which may be a bug rather than something to delete.
    Issue 2 — a message sent into the void
    

bbb-graphql-middleware sends UserGraphqlDisconnectionForcedEvtMsg but akka-apps has no handler

bbb-graphql-middleware publishes UserGraphqlDisconnectionForcedEvtMsg to
redis — the symbol websrv.SendUserGraphqlDisconnectionForcedEvtMsg is present
in the shipped binary, confirmed with strings /usr/bin/bbb-graphql-middleware.

akka-apps never handles it. It is not in ReceivedJsonMsgHandlerActor's
dispatch, and the name appears nowhere in akka-bbb-apps at all.
git log -S UserGraphqlDisconnectionForcedEvtMsg -- akka-bbb-apps/ is empty, so
a handler has never existed on this branch.

The message is defined in bbb-common-message
(SystemMsgs.scala:208) with body
(middlewareUID: String, sessionToken: String, browserConnectionId: String).

UserGraphqlReconnectionForcedEvtMsg is defined alongside it and is likewise
unreferenced in akka-apps, though I did not find a sender for that one.

So either:

  • akka-apps is meant to react to a forced graphql disconnection and the handler
    was never wired up — in which case something is silently not happening; or
  • the message is genuinely obsolete, and the middleware should stop publishing it
    and both definitions should be removed.

Worth a maintainer deciding which, rather than assuming. Found while working
bigbluebutton#20095.
Issue 3 — the test suite doesn't build


akka-bbb-apps test suite does not compile on v4.1.x-develop

sbt test in akka-bbb-apps fails with 54 compilation errors before any test
runs. Reproduced on a clean checkout of v4.1.x-develop (13c457f).

Two model signatures drifted away from the test fixtures:

src/test/scala/org/bigbluebutton/core2/testdata/TestDataGen.scala:20

not enough arguments for method create: (..., livekitToken: Option[String])
  Unspecified value parameter loggedOut.
    val ru = RegisteredUsers.create(meetingId, userId = id, extId, name, "", "", role, ...

src/test/scala/org/bigbluebutton/core2/testdata/TestDataGen.scala:85

not enough arguments for method apply: (streamId, userId, contentType, hasAudio,
  showAsContent, subscribers) in object WebcamStream.
  Unspecified value parameters hasAudio, showAsContent, subscribers.
    WebcamStream(streamId, userId, subscribers)

Also touches AppsTestFixtures.scala, BigBlueButtonActorTestsSpec.scala and
TestKitUsageSpec.scala.

Impact: there is currently no automated test coverage for akka-apps —
sbt compile succeeds, so this does not show up unless you run the tests.

Note that sbt reformats the test sources via scalariform on compile, so a test
run leaves the working tree dirty even when it fails.

antobinary and others added 28 commits October 29, 2026 09:40
…al-plugins-ci-4.0

ci: Test official plugins against BigBlueButton 4.0 in CI
If every test job stops before Playwright writes its blob report, for
example on an install or npm ci failure, nightly-merge is never created
and the loop over nightly-merge/* runs once on the literal pattern.
merge-reports fails on it, the step stops under bash -e, and the summary
loses the list of failed server health checks, the only thing such a
run has to show.

Skip anything that is not a directory, as the loop over the downloaded
jobs above it already does. shopt -s nullglob would fix this loop too,
but it would leave the grep over nightly-jobs/*/nightly-output/health.txt
at the end of the step with no file operand, reading stdin, whenever no
job got as far as the health check.

Raised in the review of bigbluebutton#26309.
With KERNEL_LOG naming a missing or unreadable file, cat printed its
error, the search ran on an empty string and the check reported PASS.
Report FAIL instead, as check_conversion_runtime already does for
BBB_WEB_LOG.

The nightly workflow does not set KERNEL_LOG, so this only changes runs
by hand.

Raised in the review of bigbluebutton#26309.
The build lookup took a page of 30 push runs of Automated tests. That is
about two days on v4.0.x-develop, where most push runs are cancelled by
the next push before their build finishes. Ask for 100, the most the API
returns in one page, so the nightly gives up only after about a week in
which no build finished.

Raised in the review of bigbluebutton#26309.
The 4.0.1 docs said the first maxPresentationsPerRequest presentations
in request order are processed. prepareDocuments moves the current
presentation to the front before it applies the cap, so that one is
always kept and the others fill the remaining slots in request order.

The URLs of all documents are also validated before the cap, so a
malformed URL fails the call with invalidPresentationUrl even when its
document would have been dropped. Say both in customize.md and in the
create and insertDocument sections of api.md.

Raised in the review of bigbluebutton#26309.
…b-unknown-action-404-error-handler

fix(bbb-web): Fix 400 bbb web unknown action 404 error handler
…b-presentation-conversion-meeting-gone

fix(bbb-web): skip the presentation conversion when its meeting is already gone
77a8dc5 renamed APOLLO_CLIENT_SETTINGS_MODULE to
APOLLO_CLIENT_SETTINGS_OVERRIDE, passed as createClientSettingsOverride,
but this test still imported the old name. The import was undefined, so
the test created its meeting without the override, found no Apollo
client and skipped itself, and the typecheck this branch adds fails on
it. With the new name it runs again: it passes in 22 seconds on a 4.0
server, where it was skipped before.
The per-pull-request gate runs 681 tests in 8 shards. Its slowest shards
take 22-26 minutes, one of them past the old 25-minute step limit that
bigbluebutton#26297 raised to 40. These 88 leave it for the nightly: about 36 of the
gate's 161 minutes of test time, measured test by test on a 4.0 server,
which takes the shards from 14/20/23/11/18/19/24/26 minutes on the last
green push to about 12/16/17/10/13/13/18/20, and the legacy media job
from 146 tests to 135.

They are the tests whose time goes to waiting (timers, reaction expiry,
connection timeouts, heavy uploads and conversions, recording
processing) and the variants of a check that a test staying in @ci
already makes; one or two of each family stay in the gate, as in
initialSelectedTool.spec.ts. Quarantined tests and the only test of a
feature stay where they are.

The tests stay where they are and take @nightly themselves. Playwright
tags only add up, so most of them keep the @ci of their describe; the
gate scripts now leave out @nightly the way they leave out the
quarantine tags, which the nightly workflow already did, and the README
says so. Five describes whose tests all move, and the reconnection test
that is tagged on its own, change @ci to @nightly instead. Where a
test's first line no longer fits, prettier puts the title, the tag and
the function on lines of their own, as for the suite's other tagged
tests; nothing else is reformatted.

The nightly runs them on both media bridges in its @nightly jobs, which
grow from about 10 to about 45 of their 150 minutes. It tests
v4.0.x-develop only, so pull requests to a release branch no longer run
these 88 unless the nightly is started there by hand.
The plugin tests download the SDK tarball from the repository owner's
bigbluebutton-html-plugin-sdk. A fork without its own copy of that
repository gets a 404, so the download fails and the plugin tests never
run.

The URL now defaults to bigbluebutton/bigbluebutton-html-plugin-sdk, so
bigbluebutton/bigbluebutton gets the same URL as before. A fork that
keeps its own copy sets the PLUGIN_SDK_REPOSITORY repository variable to
it, as owner/name.
…data

When users of a new meeting join at the same moment, their join requests
write their custom data to the meeting from several threads at once.
Meeting.userCustomData is a plain HashMap, so an entry can be lost; join
then reads null back for that user, and the MeetingService task that
publishes the user's RegisterUserReqMsg to akka-apps throws a
NullPointerException in BbbWebApiGWApp.registerUser. akka-apps never
learns the user, the client's first GraphQL REST call is refused
("x-hasura-role" not found in session variables) and the user lands on
the error screen. The Playwright stress test "Join 2 users (mod and
attendee)" fails this way from time to time.

The test starts eight threads per fresh meeting, held in a busy spin
until all of them run so that they reach the meeting together, and checks
that every user's data is still there, over 2000 meetings. On the current
Meeting it fails at once (8245 of 16000 users lost their data in one
run); with userCustomData as a ConcurrentHashMap it passes.
The livekit-sip note added in 8aebd60 (bigbluebutton#25912) links to
/administration/configure-firewall. That is the page's file name and id,
not its URL: configure-firewall.md sets
slug: /administration/firewall-configuration, which is what install.md and
troubleshooting.md already link to.

Docusaurus throws on broken links (onBrokenLinks), so `docusaurus build`
fails with "Broken link on source page path = /administration/customize/".
Since bigbluebutton#26058 brought the note to v4.0.x-release on 2026-10-28, the
"Build and Deploy Docs" workflow fails too, because its build.sh builds the
4.0 version of the site from that branch, so docs.bigbluebutton.org has not
been updated since then. Pull requests do not catch this because no PR
workflow runs the docs build.

v4.1.x-develop has the same link in a reworded line. The next
v4.0.x-develop merge into it takes this line from 4.0 without a conflict,
so the fix carries over there.
Users joining a meeting at the same moment write their custom data to
Meeting.userCustomData from several request threads at once. The map was
a plain HashMap: two first puts into a new meeting's map can each
allocate its table, and the entry written into the table that loses is
gone. join then read null back as the user's metadata,
BbbWebApiGWApp.registerUser threw a NullPointerException on it, and the
user's RegisterUserReqMsg never reached akka-apps. akka-apps did not know
the session, so Hasura refused the client's first GraphQL request
("x-hasura-role" not found in session variables) and the user got
"Ops, something went wrong".

userCustomData is a ConcurrentHashMap now, like users and
registeredUsers next to it. Its keys and values are never null:
externUserID falls back to the internal user ID and join always creates
the data map.

MeetingUserCustomDataTest passes with it (it failed before: 8245 of
16000 users lost their data), as do the other 74 bbb-common-web tests.
On a 4.0.1 server, two browsers joining a new meeting at the same moment
failed in 4 of 113 rounds before and in none of 150 rounds after, with no
NullPointerException in bbb-web's journal.
MeetingService.processMessage hands every message to runExec as a task.
The try/catch that logs "Handling unexpected exception" only covers that
hand-over, so an exception inside the task ended runExec's thread with a
trace on stderr (bbb-web's journal) and nothing in bbb-web.log, and the
message it was handling was dropped without a trace. That is how users
whose registration was lost to the userCustomData race went unnoticed.

The task now runs inside a try/catch that logs the exception with the
message type, and runExec keeps its thread.
…irewall-configuration-link

docs: fix the firewall page link in customize.md
`docusaurus build` reports 11 broken anchors on this branch. Docusaurus only
warns about them (onBrokenAnchors defaults to 'warn'), so they reach the site
unnoticed and the links open at the top of the target page.

- The API headings render as "`GET` `POST` create" and so on, so their ids
  are get-post-create, get-post-end, post-insertdocument and
  get-getrecordings. Links to #create, #end, #insertdocument and
  #getrecordings, in customize.md, recording.md, faq.md and api.md, now use
  those ids.
- plugins.md: heading ids are lower case (#running-the-plugin-from-source),
  the auxiliary functions are under #auxiliaries, and there is no "Plugin
  Versioning" section; "SDK version compatibility" explains how the
  server's html5PluginSdkVersion is matched.
- release-testing.md pointed at a new-features section that is not on the
  4.0 page; preUploadedPresentationOverrideDefault is documented with the
  create call.
onBrokenLinks was the only check that failed the build. Set onBrokenAnchors
and onDuplicateRoutes to 'throw', and move onBrokenMarkdownLinks into
markdown.hooks as 'throw', next to onBrokenMarkdownImages: the top-level
option is deprecated and printed a warning on every build.

This config applies when this branch's docs are built on their own, locally
or in the docs build check. The docs.bigbluebutton.org deploy builds every
version with the config on develop, where anchors stay at 'warn' because the
archived versions link into the current one.

With the anchor fixes in the previous commit the branch builds with no
warnings.
No pull request workflow builds the docs: automated-tests.yml ignores
docs/** and **/*.md, and deploy-docs.yml only runs on pushes to develop. The
broken link from bigbluebutton#25912 was found only after it reached v4.0.x-release and
the docs deploy failed.

The new workflow runs `npm run build` in docs/ on pull requests that touch
docs/ or the workflow, and on demand. With the stricter config it fails on
broken links, anchors, markdown links and images, and duplicate routes. It
builds this branch's docs alone, without the other versions, so the archived
branches cannot fail it.

Node 24 and the action versions match deploy-docs.yml on develop.
…content-stale-main-area

fix(html5): Show the new generic content when a plugin replaces it
antobinary and others added 26 commits November 5, 2026 14:18
…-breakout-rooms-with-parent

fix(bbb-web): end API-created breakout rooms when their parent ends
…rd-yellow-fill

fix(whiteboard): keep the yellow fill colors in the palette override
fix(plugins): standardize sidekick menu badge and keep it across remounts
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
getJoinUrl drops every userdata- parameter, for viewers and for everyone
in a breakout room, when the blocklist contains "all". bbb-web has
accepted that value since bigbluebutton#22943 (3.0.7), but the userdata section of
api.md only described the named entries.

The sentence is the one CodeRabbit suggested in the review of bigbluebutton#26428.
…s_6767ac79ef51824ce6330dcfb9b03097

[4.0 locales] Updates for file bigbluebutton-html5/public/locales/en.json
The raise-hand port (eefd37e) removed the raise-hand notifier, which
formatted app.statusNotifier.lowerHandDescOneUser with
{ userName: u.name }, added a lower-hand button to the user list that
formats the same message without values, and changed its English text
from "Lower {userName}'s hand" to "Lower hand".

Transifex keeps the translations of a key whose English text changes.
Of the 28 locales that had translated the old text, 16 still carry
{userName}: ca, cs_CZ, el_GR, es, es_ES, eu, fa_IR, fr, gl, hy, ko_KR,
nl, pl_PL, pt, tr_TR and uk_UA. Formatted without values, react-intl
returns a message unchanged, so the tooltip shows the raw placeholder,
for example "Опустити руку {userName}" in Ukrainian.

Pass the user's name again. The 16 locales then render the text they
were translated for, with the name filled in. English and the 12
locales re-translated to "Lower hand" since (ar, de, et, hu_HU, it_IT,
ja, nb_NO, pt_BR, ru, sv_SE, tr, zh_TW) ignore the unused value and
render as before.

Reported in bigbluebutton#26426. The other strings that report shows in English are
missing uk_UA translations, which come from Transifex.
…hand-tooltip-username

fix(user-list): pass userName to the lower-hand tooltip again
…ish-results-contents-read

ci: let the tests comment job check out the repository
…shboard-title-locale

test(learning-dashboard): match the breakout dashboard by its room name
test(api-conformance): Add a Conformance Suite for the HTTP API
GitHub now forces Node 20 actions to run on Node 24 and warns on every
run ("Node.js 20 is deprecated. The following actions target Node.js 20
but are being forced to run on Node.js 24"). Three pins on this line
were still on Node 20 majors:

- actions/download-artifact@v4 in push-debs-to-package-repo -> @v7.
  Every other download step in automated-tests.yml was already on @v7;
  this one was missed. It downloads by name, so the v5 change to
  downloads by artifact ID does not apply.
- peter-evans/create-or-update-comment@v4 (6 steps) in
  automated-tests-publish-results.yml -> @v5.
- actions/stale@v9 in stale.yml -> @v10.

The only breaking change in each new major is the Node 24 runtime,
which needs runner v2.327.1 or later. These jobs already run other
Node 24 actions (checkout@v5, github-script@v8) on the same runners.
…gs-language-selector

fix(settings): use BBBSelect for the language selector
…ing-data-loading

fix(plugins): withhold meeting data from plugins until it loads
fix: breakoutRoomsRecord=false is not enforced
…-web-render-sandbox-tmp

fix(bbb-web): write slide renders where the conversion sandbox can
…l-metadata-orphan-view-and-captiontype

bbb-graphql-server: drop orphan user_reaction_current metadata, declare captionType on captionSubmitTranscript
…e24-40

ci: move the remaining Node 20 actions to their Node 24 majors
getStrongestSupportedChecksumAlgorithm trimmed and lowercased each entry
of supportedChecksumAlgorithms, while GetChecksumValidator matches the
raw value with a case-sensitive contains. With "sha1,SHA512", getJoinUrl
signed with SHA-512 and the validator, which does not find "sha512" in
that value, refused the URL; the previous SHA-1 signature passed. Test
the setting the way the validator does, so getJoinUrl only signs with an
algorithm the issuing server accepts. Lowercasing the setting in its
setter instead would also change which checksums every other API call
accepts.

When the setting names no known algorithm, the selection still falls
back to sha256, which the validator refuses. Such a server already
refuses every checksummed call; log a warning there so the operator can
see why.

The API docs no longer claim that the URL verifies under any configured
list. GetJoinUrlSpec gains a mixed-case row, and the encode-once test
now also covers a literal plus sign, ampersand and percent sign and
non-ASCII characters. The space-only case passed even with an encoder
that only turned spaces into plus signs.
…lobby-dead-code-40

refactor(core): Cleanup guest lobby dead code
…sh-local-screenshot-baselines

test: make the local-only screenshot comparisons deterministic and refresh their baselines
…nurl-encode-once-configurable-checksum

fix(bbb-web): encode getJoinUrl values once and sign with a supported checksum algorithm
Part of bigbluebutton#20095. The Etherpad removal in 6227aa5 kept these two, with
their handler, route and analytics case, behind a TODO: "drop once
bbb-transcription-controller is confirmed not to publish PadUpdatePubMsg".
It does not, and it never has:

  - `git log --all -S PadUpdatePubMsg` on bbb-transcription-controller is
    empty, and no tag from v0.2.5 to v0.4.0 (the version pinned in
    bbb-transcription-controller.placeholder.sh) contains the name. The
    controller has no pad code at all.
  - The `transcript: true` flag came with bigbluebutton#19091 (Gladia transcriptions,
    2.7). Its sender was the html5 Meteor server, in
    imports/api/pads/server/methods/updateTranscriptPad.js. The pad
    methods went with the Meteor server in 5643305 (2024-04-25).
  - Nothing in this repo, in the components installed on a 4.0 server, or
    in the bbb-graphql-middleware and bbb-webrtc-recorder binaries
    (checked with strings) sends PadUpdatePubMsg.

PadUpdateCmdMsg was only ever emitted by PadUpdatePubMsgHdlr, and its
consumer, bbb-pads, is no longer packaged on this line. So both go,
together with the handler trait, its PadsApp2x mixin, the MeetingActor
arm, the ReceivedJsonMsgHandlerActor route and the AnalyticsActor cases.

Pads.hasAccess and Pads.getGroup stay. PadPinnedReqMsgHdlr and
EndBreakoutRoomInternalMsgHdlr still use them.

The other two messages this commit removed when it was first written,
PadCreateReqMsg and UpdatePositionInWaitingQueueReqMsg, are already gone
from v4.0.x-develop (6227aa5 and 0f855cb).
Continues the previous commit. ReceivedJsonMsgHandlerActor still accepts
these 24 inbound messages, but nothing sends any of them:

  Initial-state fetches. The client reads this state from GraphQL/Hasura
  now and no longer asks akka-apps: GetAllPresentationPodsReqMsg,
  GetChatHistoryReqMsg, GetCurrentLayoutReqMsg, GetCurrentPollReqMsg,
  GetGroupChatMsgsReqMsg, GetGroupChatsReqMsg, GetPresenterGroupReqMsg,
  GetScreenshareStatusReqMsg, GetWebcamsOnlyForModeratorReqMsg,
  GetWhiteboardAnnotationsReqMsg, IsMeetingMutedReqMsg

  Chat, superseded by group chat in 2018: SendPublicMessagePubMsg,
  SendPrivateMessagePubMsg

  Presenter group, feature removed in 2018: AddUserToPresenterGroupCmdMsg,
  RemoveUserFromPresenterGroupCmdMsg

  Presentation pods: CreateNewPresentationPodPubMsg,
  RemovePresentationPodPubMsg, SlideResizedPubMsg,
  PreuploadedPresentationsSysPubMsg

  Other: BreakoutRoomsListMsg, LockUsersInMeetingCmdMsg,
  EjectUserFromMeetingSysMsg, RecordAndClearPreviousMarkersCmdMsg,
  ClientToServerLatencyTracerMsg

Each message loses its case classes in bbb-common-message and the doc
comment above them, its handler trait and that trait's mixin, the
MeetingActor dispatch arm, the AnalyticsActor logging case and the inbound
route. Section comments left heading nothing ("// Presentation Pods" in
the router, "// System" in AnalyticsActor) go too. Two handlers live in
files named after something else, and both are removed too:
PreuploadedPresentationsPubMsgHdlr, and EjectUserFromMeetingSysMsgHdlr
inside EjectUserFromMeetingCmdMsgHdlr.scala.

The commit also removes the 12 outbound messages that these leave
without an emitter, so the change doesn't swap one kind of dead code
for another:

  GetAllPresentationPodsRespMsg, GetChatHistoryRespMsg,
  GetCurrentLayoutRespMsg, GetCurrentPollRespMsg,
  GetGroupChatMsgsRespMsg, GetGroupChatsRespMsg,
  GetWebcamsOnlyForModeratorRespMsg, GetWhiteboardAnnotationsRespMsg,
  IsMeetingMutedRespMsg, NewPresentationEvtMsg, SendPrivateMessageEvtMsg,
  ServerToClientLatencyTracerMsg

The helpers that built them go too: Polls.handleGetCurrentPollReqMsg,
PresentationApp2x.processPreuploadedPresentations and the
NewPresentationMsgHdlr trait.

LayoutApp2x now declares `val liveMeeting: LiveMeeting` itself. It used
to inherit that declaration from GetCurrentLayoutReqMsgHdlr, and its
sibling handler traits get `liveMeeting` through the mixin.

How "no sender" was established, re-checked on this base:
  - every component in this repo, including akka-apps building the
    message itself, not just handling it;
  - the components installed on a 4.0 server, and the
    bbb-graphql-middleware and bbb-webrtc-recorder binaries (with
    strings, unanchored, because Go concatenates string literals);
  - bbb-transcription-controller v0.4.0, bbb-webhooks v3.7.0,
    bbb-webrtc-recorder v0.18.0, bbb-webrtc-sfu v2.25.0-beta.3 and
    bbb-playback v5.4.8, at the tags their placeholders pin;
  - every publisher to the to-akka-apps channels, to confirm that none
    builds a message name dynamically.
The only substring hit was LiveKit's protobuf GetChatHistoryResponse,
which is not a BBB message.

Not removed on purpose:
  - GetMediaGroupsReqMsg. It has no sender either, but it isn't legacy:
    it was added in 2024-12 as GetAudioGroupsReqMsg and renamed in
    2025-10, and its sibling graphql-actions mutations are live.
  - UserConnectedToGlobalAudioMsg and UserDisconnectedFromGlobalAudioMsg,
    which bbb-webrtc-sfu sends.
  - TranscriptionProviderErrorMsg, sent by bbb-transcription-controller.

GetGuestPolicyReqMsg and GetGuestsWaitingApprovalReqMsg were in this
commit when it was first written, along with the GetGuestPolicyRespMsg
and PosInWaitingQueueUpdatedRespMsg replies and the GuestWaitingUP VO.
0f855cb removed them from v4.0.x-develop first.
Removing the dead inbound handlers left code whose only user they were.
This commit removes it, so the series ends with no new dead code.

Messages that lost their only emitter:

  SendPublicMessageEvtMsg, built only by SendPublicMessagePubMsgHdlr.
  Goes with ChatMessageVO, its only payload type, and with the routing
  arm in FromAkkaAppsMsgSenderActor, whose reference is what kept it out
  of the previous commit's "no emitter left" check.

  RemovePresentationPodEvtMsg, built only by RemovePresentationPodPubMsgHdlr.
  Goes with its RedisRecorderActor arm and RemovePresentationPodRecordEvent.

  RecordStatusResetSysMsg, built only by MsgBuilder.buildRecordStatusResetSysMsg,
  which only RecordAndClearPreviousMarkersCmdMsgHdlr called. Goes with the
  builder, its RedisRecorderActor arm and RecordStatusResetEvent.

  Nothing in record-and-playback, bbb-playback or bbb-export-annotations
  reads the two recorded events.

Helpers whose only callers were removed:

  ChatModel. addNewChatMessage and getChatHistory were only used by the
  legacy chat handlers. Without them the message buffer is never appended
  and clearPublicChatHistory empties an empty list, so the class, the
  LiveMeeting and RunningMeeting field and the fixture lines go.
  ClearPublicChatHistoryPubMsgHdlr keeps its DB and group-chat work.

  PresentationApp2x and the MeetingActor val that held it: no dispatch arm
  reaches it and both of its remaining methods were unused.

  PresentationPodsApp.createPresentationPod and PresentationPodFactory.create
  (CreateNewPresentationPodPubMsgHdlr), with the genId helper only create
  used; translatePresentationPodToVO and PresentationPodVO
  (GetAllPresentationPodsReqMsgHdlr); GroupChatInfo (GetGroupChatsRespMsg);
  PresPageDAO.updateSlidePosition (SlideResizedPubMsgHdlr);
  AnalyticsActor.traceMessage (the latency tracers).

Found with two checks that go beyond grepping for the message names:
identifiers in akka-apps and bbb-common-message whose only remaining
reference is their own declaration, and messages that some code consumes
but no code constructs. Both lists are the same before and after the
series, apart from what the series removes.

Messages defined in bbb-common-message: 382 -> 379.
@antobinary
antobinary force-pushed the fix-20095-remove-html5-akka-messages branch from 43351d1 to a5cbfdb Compare November 9, 2026 12:48
@github-actions

github-actions Bot commented Nov 9, 2026

Copy link
Copy Markdown

🚨 Automated tests failed

@antobinary

Copy link
Copy Markdown
Owner Author

Replacing with bigbluebutton#26467

@antobinary antobinary closed this Nov 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants