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.

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.1.2.tar.gz (70.2 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.1.2-py3-none-any.whl (70.5 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for smallblueclient-0.1.2.tar.gz
Algorithm Hash digest
SHA256 756b4742ee869f79d2343537b31d90e8c846f66f4a163e4bb7b0fdae4b34b97e
MD5 33f3d3cdf02c1ed6b2f3df4d81675abc
BLAKE2b-256 e72feeac5dd63fbd05c5a8323c8636dc9831fccbe28385b0b33e9f0cfd79d5db

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for smallblueclient-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 80ac59ad44eff17d807c1c553b86ca07f4d2f7ac67d7faa01567b464368f867f
MD5 7ab918219654887d66688054a9871065
BLAKE2b-256 7f99f7c201cfa9327b7e2cc8a73e7e0f8b97e4e5a96bc447ba88782d27c8da2a

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