Skip to main content

SmallBlueClient

SmallBlueClient icon

Community automation for authenticated BigBlueButton sessions.
Export a session once. Build powerful bots in Python.

PyPI version 0.1.0 Documentation MIT License GitHub stars


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.

See the full migration history in CHANGELOG.md.

Development and community

python -m pip install -e ".[docs,dev]"
python -m unittest discover -s tests -q
ruff check sbc tests

See CONTRIBUTING.md for the contributor workflow, SECURITY.md for credential-safe reporting, and the hosted community guide for sharing BBB compatibility results.

Quick start

  1. Load the extension/ directory through chrome://extensionsLoad unpacked.
  2. Join your BBB meeting normally and open SBC Session Extractor.
  3. Export the detected .sbc file and keep it private.
  4. 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 .sbc export 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 — loop examples/test.mp3 as 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

smallblueclient-0.2.4.tar.gz (96.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

smallblueclient-0.2.4-py3-none-any.whl (89.5 kB view details)

Uploaded Python 3

File details

Details for the file smallblueclient-0.2.4.tar.gz.

File metadata

  • Download URL: smallblueclient-0.2.4.tar.gz
  • Upload date:
  • Size: 96.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.0

File hashes

Hashes for smallblueclient-0.2.4.tar.gz
Algorithm Hash digest
SHA256 db1feb91f1c3f76431b27a114ed821ada409a13bbbf09206a16bf8cea3ee221b
MD5 0c176138f977fa94af463afebf972a48
BLAKE2b-256 874757ad375b568b491343d90c35f86a74719fde515fb19648e1574d3b7c35ab

See more details on using hashes here.

File details

Details for the file smallblueclient-0.2.4-py3-none-any.whl.

File metadata

File hashes

Hashes for smallblueclient-0.2.4-py3-none-any.whl
Algorithm Hash digest
SHA256 4546f4b7a04aabb4f2c0fb1e2116714669cc34481c1b5ebac299d77e0039c75a
MD5 8662f59dfcf0da08da6b309a4e411a18
BLAKE2b-256 e9defa28684455da63b60e6c69f0b9d66d12fc9c00405a0459816f7781d2b1b0

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page