SmallBlueClient
Community automation for authenticated BigBlueButton sessions.
Export a session once. Build powerful bots in Python.
Why SBC?
SmallBlueClient (SBC) is a Python-first toolkit for BigBlueButton. The included
Chrome extension is deliberately tiny: it only passively captures the real,
authenticated BBB GraphQL session and exports a portable .sbc credential. All
automation, media, events, models, reconnects, and controllers live in Python.
| Build | With SBC |
|---|---|
| Bots | welcome users, moderate rooms, react to events, manage breakouts |
| Automation | chat, polls, captions, presentations, cameras, timers, recordings |
| Custom media | publish Python-controlled audio and video where supported by BBB |
| Typed code | controllers, enums, models, generated schema catalog, async API |
| Multiple meetings | one independent sbc.client("meeting.sbc") per session |
Install
pip install SmallBlueClient
import sbc
with sbc.client("teacher.sbc") as client:
print(client.meeting.name)
client.chat.send("Hello from SBC")
Read the complete guides and generated API reference at sbc.protobuf.lol.
Quick start
- Load the
extension/directory throughchrome://extensions→ Load unpacked. - Join your BBB meeting normally and open SBC Session Extractor.
- Export the detected
.sbcfile and keep it private. - Start writing Python:
import sbc
bot = sbc.client("classroom.sbc")
@bot.on(sbc.Event.USER_JOINED)
def welcome(user: sbc.User) -> None:
bot.chat.send(f"Welcome, {user.name}!")
bot.run()
[!IMPORTANT] An
.sbcexport is an authenticated browser credential. Do not commit it, send it to someone else, or publish it in bug reports.
Session extractor
The included extension is a passive session extractor, not the SBC program.
It observes the BBB page's actual GraphQL WebSocket, captures the observed
connection payload, adds browser cookies through Chrome's extension API, and
downloads an integrity-checked .sbc file. It does not send GraphQL
mutations, automate BBB, alter media, spoof devices, or run a localhost bridge.
The retired v5 automation extension is stored locally in
archive/chrome-extension-v5.0.1/ and is not part of this repository.
Escape hatch: source-derived actions
High-level controllers cover normal tasks. For experiments, all 109 BBB mutations are embedded in the installed Python package and are validated before they are sent. Both BBB camelCase and clean Python snake_case are supported:
client.actions.userSetMuted(userId="user-id", muted=True)
client.actions.user_set_muted(userId="user-id", muted=True)
client.mutation("meetingEnd")
Bots and events
bot = sbc.client("classroom.sbc")
@bot.on("user_joined")
def welcome(user):
bot.chat.send(f"Welcome {user.name}")
bot.run()
Events: user_joined, user_left, chat_message, hand_raised,
voice_joined, user_talking, presentation_changed, and meeting_ended.
Complete event surface
SBC also exposes source-backed user transitions: hand_lowered, voice_left,
user_stopped_talking, user_muted, user_unmuted,
user_became_presenter, user_stopped_presenting,
user_became_moderator, user_stopped_moderating, user_away, user_back,
user_disconnected, user_reconnected, camera_started, and camera_stopped.
Meeting streams provide meeting_updated, screenshare_started,
screenshare_stopped, external_video_started, external_video_stopped,
poll_updated, poll_published, poll_ended, poll_results_changed,
timer_updated, timer_started, timer_stopped, timer_elapsed, and
current-user events including current_user_joined and current_user_ejected.
Every field in the BBB 3.0.32 user, current-user, and meeting subscriptions also gets a generated change handler. For example:
@bot.on("user_role_changed")
def role_changed(user, old_role, new_role):
print(user.name, old_role, "->", new_role)
@bot.on("meeting_lock_settings_changed")
def locks_changed(meeting, old, new):
print(new)
Handlers can be removed, filtered, prioritized, run once, or be async:
@bot.once("user_joined", priority=10, when=lambda user: user.guest)
async def greet_guest(user):
bot.chat.send(f"Welcome {user.name}")
bot.off("user_joined", greet_guest)
For any BBB 3.0.32 schema table, use the embedded source-backed catalog before
run:
bot.watch_table(
sbc.BBBTable.NOTIFICATION,
"messageId notificationType messageDescription",
)
@bot.on("table_notification_changed")
def notification(rows):
print(rows)
sbc.BBBTable contains every table listed in the bundled BBB 3.0.32 GraphQL
schema. sbc.schema.subscription(...) is also available when a raw operation
string is useful.
All 109 built-in BBB action methods also have lifecycle handlers. For example,
userSetMuted emits action_started, action_completed, and action_failed,
plus action_user_set_muted_started, action_user_set_muted_completed, and
action_user_set_muted_failed. The same pattern is generated for every action
in client.actions.names.
Live event subscriptions reconnect automatically with exponential backoff. SBC
multiplexes all selected built-in and table subscriptions through one event
socket, so a bot no longer creates one authenticated BBB WebSocket per handler.
A new X-ClientSessionUUID is generated for each SBC socket so reconnects do
not replace the browser's active BBB GraphQL connection.
Only streams required by registered handlers are opened. A bot using only
user_talking opens one BBB GraphQL subscription instead of every optional
meeting stream. Streams may also be selected explicitly:
bot.enable_events("user_talking", "chat_message")
Pass listen_only=False to join a muted full-audio microphone session instead
of a listener session. It keeps the SFU connection ready so a later
client.media.audio.play(...) begins without a new WebRTC negotiation:
bot = sbc.client("classroom.sbc", listen_only=False)
Typed controllers and enums
High-level controllers cover polls, breakouts, captions, shared notes, recording, cameras, whiteboards, guests, timers, external video, plugins, media groups, meeting settings, and locks. BBB values are named enums rather than unexplained strings:
import sbc
bot = sbc.client("teacher.sbc")
poll_id = bot.polls.create(
"Ready?", ["Yes", "No"], poll_type=sbc.PollType.YES_NO,
)
bot.polls.publish(poll_id)
bot.guests.policy(sbc.GuestPolicy.ASK_MODERATOR)
bot.settings.role("student-id", sbc.Role.VIEWER)
bot.locks.set(sbc.LockSettings(disable_microphone=True, lock_on_join=True))
room = sbc.BreakoutRoom("Group A", sequence=1, users=("student-id",))
bot.breakouts.create([room], duration_minutes=15)
Typed data objects are available directly from sbc: User, Meeting,
Chat, ChatMessage, Presentation, Poll, Timer, Caption,
BreakoutRoom, Camera, LockSettings, Screenshare, ExternalVideo,
SharedNotesSession, Recording, WhiteboardAnnotation, Notification, and
plugin/media-group models.
Read controllers
Controllers provide typed reads as well as actions:
with sbc.client("teacher.sbc") as client:
polls = client.polls.list()
rooms = client.breakout_rooms.list()
cameras = client.cameras.list()
recording = client.recordings.status()
guests = client.guests.list()
annotations = client.whiteboards.current()
transcript = client.captions.transcript()
Native asyncio
The async facade uses the same session format, models, enums, controllers, and automatic reconnect behavior:
import sbc
async with sbc.async_client("test.sbc") as bot:
await bot.chat.send("Hello")
async for user in bot.events.user_joined():
await bot.chat.send(f"Welcome {user.name}")
Use python examples/async_bot.py for a complete runnable version.
Generated source catalog and API
Release builds read BBB's bbb-graphql-schema.md directly and package a frozen
catalog containing table enums, scalar fields, generated table events, and
TypedDict row models. Public Python-only source checkouts intentionally omit
the large BBB source tree and use SBC's compact compatibility catalog until a
schema is supplied for a release build.
To release for BBB 2.7 or a newer checkout, provide its source explicitly:
$env:SBC_BBB_SCHEMA = "C:\bbb-2.7\bbb-graphql-server\bbb-graphql-schema.md"
$env:SBC_BBB_VERSION = "2.7"
python -m build --wheel
At runtime, load a second source version without replacing the default catalog:
bbb27 = sbc.catalogs.load("C:/bbb-2.7/bbb-graphql-schema.md", version="2.7")
print(bbb27.fields("notification"))
Every wheel includes py.typed, generated action signatures, and an API.md
reference generated from SBC's embedded action definitions. See docs/API.md
for the controller/event cheat sheet. Enable JSON logs and non-secret media
diagnostics with:
sbc.enable_logging("DEBUG", structured=True)
Examples
All examples use the local examples/test.sbc session and can be launched from
the repository root:
python examples/hello.py— minimal meeting, user, and chat workflow.python examples/automation.py— one-shot moderation controllers.python examples/moderation_bot.py— enum-backed event bot.python examples/voice_guard_bot.py— warmed custom-audio voice guard.python examples/custom_media.py— loopexamples/test.mp3as the Python microphone.python examples/event_patterns.py— async, priority, filters, once, and off.python examples/schema_events.py— source-schema table events.python examples/typed_controls.py --apply— typed controllers and enums.python examples/async_bot.py— async context manager and event iterator.
Custom microphone and camera
The extension only exports the .sbc session. Python connects directly to BBB's
LiveKit room and publishes the selected media:
client.media.audio.play("music.mp3", loop=True)
client.media.audio.mute()
client.media.audio.unmute()
client.media.camera.play("loop.mp4", loop=True)
client.media.camera.mute()
Runnable audio example: python examples/custom_media.py; it uses the bundled
examples/test.mp3.
SBC follows BBB 3.0.32's LiveKit implementation: it reads the authenticated
user_current.livekit.livekitToken, connects to wss://<bbb-host>/livekit, and
publishes Python-decoded audio/video frames as microphone/camera tracks. No
extension media hook or local bridge is used. Run python examples/custom_media.py
to publish examples/test.mp3.
The extension also observes BBB's user_current GraphQL response and writes the
LiveKit token and url into snapshot.livekit in exported .sbc files. For an
older session such as examples/test.sbc, client.media.credentials() fetches
that same source-backed field once and keeps it in the running client. SBC never
rewrites the loaded .sbc file automatically; call client.save_session() only
when you explicitly want to persist updated session data.
Current BBB mapping
The operation mapping was taken from the bundled BBB 3.0.32 source:
bbb-graphql-actions and bigbluebutton-html5. It uses chatSendMessage,
userSetMuted, meetingSetMuted, userEjectFromMeeting, presentationSetPage,
and meetingEnd rather than guessed mutation names.
Documentation site
The complete documentation is authored as a Sphinx site with the Furo theme in
docs/. It includes the generated Python API/action reference, controller and
event guides, the BBB version compatibility table, session-health guidance, and
media troubleshooting. The published documentation is available at
sbc.protobuf.lol.
pip install -e ".[docs]"
sphinx-build -W -b html docs docs/_build/html
Open docs/_build/html/index.html after a successful build.
Session health
with sbc.client("teacher.sbc") as client:
health = client.session.validate()
print(health.to_dict())
print(client.session.expires_at)
if health.requires_reexport:
print("Export a new .sbc session from the extension.")
SBC marks a running session for re-export when BBB reports expired or rejected
credentials. It never mutates the original .sbc file unless you explicitly
call client.save_session().
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file smallblueclient-0.1.0.tar.gz.
File metadata
- Download URL: smallblueclient-0.1.0.tar.gz
- Upload date:
- Size: 69.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
64c867b9cf68a2dc93d7b944437be72f4169c2dd6333cc5efadbc47cd46e45eb
|
|
| MD5 |
105736b4fad8f254caba2b3407509469
|
|
| BLAKE2b-256 |
581630d5039a208fd1b45a29d9728db5efce17f27ebb28704d28fb5e4fac5f65
|
File details
Details for the file smallblueclient-0.1.0-py3-none-any.whl.
File metadata
- Download URL: smallblueclient-0.1.0-py3-none-any.whl
- Upload date:
- Size: 70.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
01bb0463976a37b75c69bd5299541cc7cf4a7aa7078bd2bf3a70b302df5743cc
|
|
| MD5 |
289d91799b25354cdbcbfc7bf74ab2a5
|
|
| BLAKE2b-256 |
af122ebed50096b82f45e9226af404dc7e0f21b630b916f136c7ae022313a51c
|