Documented event-aware session URL generation.

2026-05-04 21:48:06 -04:00
parent d7f18ba962
commit d8ce4b4570
4 changed files with 8 additions and 7 deletions
+1 -1
@@ -83,7 +83,7 @@ async def settings(ctx: CommandContext) -> None:
)
```
Use plain `ctx.routes.url_for(path)` for public pages. See [Protected Routes](Modules-Routes#protected-routes) for route-level session and permission checks.
Use plain `ctx.routes.url_for(path)` for public pages. Use `ctx.session_url_for(path)` for pages that require a browser session, authentication, or moderator access. See [Protected Routes](Modules-Routes#protected-routes) for route-level session and permission checks.
## Cooldowns
+4 -3
@@ -107,6 +107,7 @@ async def on_chat(ctx: EventContext[ChatEvent]) -> None:
| Method | Description |
|--------|-------------|
| `stop_propagation(reason=None)` | Stops the event from reaching remaining handlers. See [Event System](Modules-Events). |
| `session_url_for(path)` | Build a one-time connect URL for one of this module's routes, tied to `ctx.event.user`. Available only when the event has a `user` field. |
All `ModuleContext` services are available directly on `ctx` (see [Proxied Properties](#proxied-properties) below).
@@ -149,7 +150,7 @@ async def greet(ctx: CommandContext) -> None:
| Method | Description |
|--------|-------------|
| `session_url_for(path)` | Build a one-time connect URL for one of this module's routes, tied to the command user. Available in command handlers; use this when sending links to protected routes. |
| `session_url_for(path)` | Build a one-time connect URL for one of this module's routes, tied to the command user. Use this when sending links to protected routes. |
All `ModuleContext` services are available directly on `ctx` (see [Proxied Properties](#proxied-properties) below).
@@ -198,8 +199,8 @@ For public routes, `ctx.session` may be `None`. Check it before reading session
The only differences between the three context types are the handler-specific fields:
- **EventContext** adds `.event` (the triggering event) and propagation control.
- **CommandContext** adds `.command_event` (parsed command data), convenience properties for command/args/user, and `.session_url_for()`.
- **EventContext** adds `.event` (the triggering event), propagation control, and `.session_url_for()` for events with a `user` field.
- **CommandContext** adds `.command_event` (parsed command data), convenience properties for command/args/user, and `.session_url_for()` through the underlying chat event.
- **RouteContext** adds `.request` (the HTTP request) and `.session` (the connected browser session, if any).
Utility functions that need to work across handler types can accept `ModuleContext` directly, since all three contexts expose it via `.module`.
+2 -2
@@ -198,7 +198,7 @@ This uses the `public_base_url` from config. If not set, it falls back to `ownca
## Protected Routes
Routes that need to know which chat user is visiting can require an Owlbot browser session. A browser session is created when a viewer runs the built-in `!connect` command in chat and opens the private link, or when your module sends them a session URL with `ctx.session_url_for()` from a command.
Routes that need to know which chat user is visiting can require an Owlbot browser session. A browser session is created when a viewer runs the built-in `!connect` command in chat and opens the private link, or when your module sends them a session URL with `ctx.session_url_for()` from a command or user-bearing event handler.
`requires_session=True` only requires a linked browser session. Use `requires_authenticated=True` when the page should only be available to logged-in Owncast users. Use `requires_moderator=True` when it should only be available to moderators.
@@ -232,7 +232,7 @@ When a protected route runs, `ctx.session` contains the linked Owncast user snap
### Sending Session URLs
Call `ctx.session_url_for(path)` from a command handler when you need to link to a protected page. Use it instead of `ctx.routes.url_for(path)` so Owlbot can link the browser session to the user who invoked the command. It accepts the same module-relative paths as `url_for()`, but returns a one-time `/owlbot/connect/<token>` URL for that user. When the user opens that link, Owlbot creates their browser session and redirects them to the route path you provided.
Call `ctx.session_url_for(path)` from a command handler or from an event handler whose event has a `user` field when you need to link to a protected page. Use it instead of `ctx.routes.url_for(path)` so Owlbot can link the browser session to that Owncast user. It accepts the same module-relative paths as `url_for()`, but returns a one-time `/owlbot/connect/<token>` URL for that user. When the user opens that link, Owlbot creates their browser session and redirects them to the route path you provided.
For example:
+1 -1
@@ -232,7 +232,7 @@ Route URLs follow the `/owlbot/<module_name>/<path>` pattern used in production.
### Testing Protected Routes
The `route_client` fixture includes Owlbot's connect routes and keeps cookies between requests, so protected route tests can use the same flow as a browser. Dispatch a command for a test user, redeem the generated session URL with `route_client`, then request the protected route:
The `route_client` fixture includes Owlbot's connect routes and keeps cookies between requests, so protected route tests can use the same flow as a browser. Dispatch a command or user-bearing event for a test user, redeem the generated session URL with `route_client`, then request the protected route:
```python
from aiohttp.test_utils import TestClient