Repository navigation
Owlbot v1.2.0 is among us!
New Features
Polls
Finished playing a game and can't decide what to play next? Why not ask the greatest collective intelligence group ever created in human history: your chat. The new polls module lets moderators create interactive polls which viewers can vote on through chat or a web page. Typing !poll returns a private link to a creation form where the moderator picks the question, options, duration, and settings such as hidden results, required authentication, and single or multi-select voting. Owlbot announces the poll in chat with numbered options, and viewers can vote by typing a number, using !vote, or visiting a voting page. Results update live and remain accessible for one hour after the poll ends.
See the Polls documentation for more information.
Emoji Wall
The new emoji_wall module provides a browser-based OBS overlay displaying Unicode emojis and custom Owncast emotes from chat as floating animated particles. Configuration covers size range, animation duration, on-screen count cap, travel direction, and rotation. The overlay URL is printed to the startup log and can be added directly as a Browser Source in OBS.
See the Emoji Wall documentation for more information.
Module API
Public Testing Package
The new owlbot.testing package gives module developers a first-class way to write unit tests without standing up an Owncast server. It ships with a pytest plugin wiring up the real command, event, and route dispatchers, in-memory SQLite storage, and a recording Owncast client capturing every outbound API call for assertion. Factory helpers cover every Owncast event type.
See the Testing Modules documentation for installation and usage.
Streaming Routes
Routes registered with @on_route(streaming=True) skip the dispatch timeout, making them well-suited for long-lived responses such as Server-Sent Events.
See the Streaming Routes documentation for more information.
Raw Inputs and Sanitized Outputs
OwncastClient.send_message() and the other send methods now HTML-escape outbound message bodies by default, since Owncast does not sanitize messages from integrations the way it does for regular users. This prevents accidental injection when a module echoes user input back to chat (for example, custom commands using $(1) placeholders). Modules intentionally sending raw HTML can opt out per call with the new unsanitized=True keyword argument. Existing modules not assembling HTML themselves require no changes.
Command parsing now uses the raw body of chat events instead of the HTML-rendered body from Owncast, so handlers see exactly what the user typed. Custom commands saved under the previous behavior may contain leftover HTML escapes which now appear as-is in chat.
See the Chat Sending documentation for the updated send methods.
Storage Layer Overhaul
The storage layer has been rewritten around per-operation auto-commit semantics, with an explicit ctx.storage.transaction() context manager for grouping operations atomically. The old connection-pool implementation has been replaced with a single lazy connection per module, and an asyncio lock now serializes concurrent operations to prevent races.
Connection pooling may be added back in the future, but for now it added complexity and race-condition surface area for very little benefit.
See the Transactions documentation for more information.
Performance
- JSON serialization throughout the bot, including outgoing HTTP client requests, is now powered by
orjson. - The event loop is now powered by
uvloop. - The HLS cache used by clips now uses set-based segment tracking and the ffmpeg concat protocol for faster clip generation.
- Custom command placeholder parsing now scans with
str.findand caches parsed templates with an LRU for faster substitution. - Webhook event dispatch now uses a pre-built string lookup table for lower per-event overhead.
In practice, none of these are likely to be noticeable. They're mostly performance hygiene, and I just like staying on top of resource usage.
Everything Else
- Adds systemd notify support with ready, stopping, and watchdog notifications.
- Adds fMP4 stream support to HLS caching in the clips module.
- Adds a chat announcement when a new clip is created.
- Updates Owncast clients to v0.2.5 with spec-coverage tests enforcing parity with the OpenAPI spec.
- Switches the config parser from PyYAML to ruamel.yaml for comment-preserving reads and writes.
- Refactors the clips, custom commands, quotes, and timers modules into layered architectures with typed domain objects and comprehensive tests.
- Makes event types and registered command/route metadata frozen and slotted for immutability and lower memory usage.
- Changes the clip viewing URL prefix from
/clipto/view. - Improves name conflict handling in custom commands.
- Fixes the clip editor video forcing full screen playback on iOS.
Upgrading
This release targets Owncast v0.2.5, though v0.2.4 instances should continue working without issue.
From your Owlbot installation directory, run:
uv pip install --upgrade owlbot \
--default-index https://git.logal.dev/api/packages/LogalDeveloper/pypi/simple/ \
--index https://pypi.org/simpleThen restart Owlbot.
Full Changelog: v1.1.1...v1.2.0