-
v1.2.0
StableCI / Formatting (push) Successful in 5sCI / Linting (push) Successful in 6sCI / Tests (Python 3.12) (push) Successful in 2m49sCI / Tests (Python 3.13) (push) Successful in 2m49sCI / Tests (Python 3.14) (push) Successful in 2m49sCI / Type Checking (push) Successful in 9sCI / Spelling (push) Successful in 5sCD / Publish Package (push) Successful in 9sCD / Publish Image (push) Successful in 1m29sreleased this
2026-04-24 20:20:22 -04:00 | 16 commits to master since this releaseOwlbot 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
pollsmodule lets moderators create interactive polls which viewers can vote on through chat or a web page. Typing!pollreturns 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_wallmodule 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.testingpackage 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 newunsanitized=Truekeyword 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
Downloads
- JSON serialization throughout the bot, including outgoing HTTP client requests, is now powered by
-
v1.1.1
StableCI / Formatting (push) Successful in 5sCI / Linting (push) Successful in 5sCI / Tests (Python 3.12) (push) Successful in 19sCI / Tests (Python 3.13) (push) Successful in 19sCI / Tests (Python 3.14) (push) Successful in 17sCI / Type Checking (push) Successful in 9sCI / Spelling (push) Successful in 5sCD / Publish Package (push) Successful in 6sCD / Publish Image (push) Successful in 55sAudit / Dependencies (push) Successful in 8sreleased this
2026-03-05 09:17:38 -05:00 | 65 commits to master since this releasev1.1.0 was pulled shortly after release due to the Docker image reporting an incorrect version number. v1.1.1 includes the same changes with a packaging fix. The PyPI package was unaffected.
The first feature release of Owlbot is here! The headline addition is the clips module, letting viewers capture and share their favorite stream moments without leaving chat. This release also brings a proper templating system and per-instance state to the module API, making it easier to build modules with polished web UIs and managed runtime state. And for the first time, Owlbot ships as a Docker image.
New Features
Clips
Owncast doesn't include built-in clip support, and previous community solutions have required complex setup to get running. The new
clipsmodule fills that gap.Viewers can capture moments from a live stream directly from chat. Typing
!clipsends the user a private link to a browser-based editor where they can trim the footage, add a title, and save the clip. Each clip gets its own shareable page with a video player, and all saved clips are browsable from a gallery page. No external services or extra software required, just ffmpeg on the host.See the Clips documentation for more information.
Docker Image
Owlbot is now published as a Docker image alongside the PyPI package. The CD pipeline builds and pushes to the Gitea Container Registry on every tagged release, so
docker pullis now a first-class installation path.Module API
Templates and Static Assets
Owlbot now bundles Bootstrap and a shared base template which modules can extend. Package modules place templates in a
templates/directory and render them viactx.templates.render(). The built-inbase.htmlgives every module a clean, unified look without having to pull in its own stylesheets or layout boilerplate. Static assets bundled with Owlbot are served automatically at/owlbot/static/.See HTTP Routes documentation for more information.
Per-Instance State
ModuleContextnow includes astatedict for holding runtime objects (schedulers, caches, managers) across handler invocations. This replaces the use of module-level globals and ensures multiple bot instances in the same process maintain fully independent state.See Context documentation for more information.
Everything Else
- Adds multi-handler support to RouteRegistry for registering multiple handlers on the same path with different HTTP methods.
- Adds
!editcountermanagement command for setting and adjusting named counters. - Adds Python 3.13 and 3.12 support alongside existing 3.14 support.
- Fixes new timers never firing.
- Fixes Docker image reporting incorrect version by removing .dockerignore.
Downloads
-
v1.0.0 Stable
released this
2026-02-14 15:21:03 -05:00 | 100 commits to master since this release- Initial release.
Downloads