Clarified body vs raw_body distinction and documented HTML escaping on send methods.
+1
-1
@@ -87,7 +87,7 @@ from owlbot.api import EventContext, EventType, ChatEvent, on_event
|
|||||||
@on_event(EventType.CHAT)
|
@on_event(EventType.CHAT)
|
||||||
async def on_chat(ctx: EventContext[ChatEvent]) -> None:
|
async def on_chat(ctx: EventContext[ChatEvent]) -> None:
|
||||||
# The event itself:
|
# The event itself:
|
||||||
message = ctx.event.body
|
message = ctx.event.raw_body
|
||||||
user = ctx.event.user.display_name
|
user = ctx.event.user.display_name
|
||||||
|
|
||||||
# Services (proxied from ModuleContext):
|
# Services (proxied from ModuleContext):
|
||||||
|
|||||||
+5
-5
@@ -13,7 +13,7 @@ from owlbot.api import EventContext, EventType, ChatEvent, on_event
|
|||||||
|
|
||||||
@on_event(EventType.CHAT)
|
@on_event(EventType.CHAT)
|
||||||
async def keyword_alert(ctx: EventContext[ChatEvent]) -> None:
|
async def keyword_alert(ctx: EventContext[ChatEvent]) -> None:
|
||||||
if "help" in ctx.event.body.lower():
|
if "help" in ctx.event.raw_body.lower():
|
||||||
await ctx.owncast_client.send_system_message("A moderator will be with you shortly!")
|
await ctx.owncast_client.send_system_message("A moderator will be with you shortly!")
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -49,7 +49,7 @@ from owlbot.api import on_event, EventContext, EventType, ChatEvent, Priority
|
|||||||
|
|
||||||
@on_event(EventType.CHAT, priority=Priority.HIGHEST)
|
@on_event(EventType.CHAT, priority=Priority.HIGHEST)
|
||||||
async def spam_filter(ctx: EventContext[ChatEvent]) -> None:
|
async def spam_filter(ctx: EventContext[ChatEvent]) -> None:
|
||||||
if "buy cheap" in ctx.event.body.lower():
|
if "buy cheap" in ctx.event.raw_body.lower():
|
||||||
await ctx.owncast_client.set_message_visibility([ctx.event.message_id], visible=False)
|
await ctx.owncast_client.set_message_visibility([ctx.event.message_id], visible=False)
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -62,7 +62,7 @@ Any event handler can stop the event from reaching remaining handlers by calling
|
|||||||
```python
|
```python
|
||||||
@on_event(EventType.CHAT, priority=Priority.HIGHEST)
|
@on_event(EventType.CHAT, priority=Priority.HIGHEST)
|
||||||
async def spam_filter(ctx: EventContext[ChatEvent]) -> None:
|
async def spam_filter(ctx: EventContext[ChatEvent]) -> None:
|
||||||
if "buy cheap" in ctx.event.body.lower():
|
if "buy cheap" in ctx.event.raw_body.lower():
|
||||||
await ctx.owncast_client.set_message_visibility([ctx.event.message_id], visible=False)
|
await ctx.owncast_client.set_message_visibility([ctx.event.message_id], visible=False)
|
||||||
ctx.stop_propagation("Spam detected")
|
ctx.stop_propagation("Spam detected")
|
||||||
```
|
```
|
||||||
@@ -123,8 +123,8 @@ Each event type maps to a dataclass:
|
|||||||
|-------|------|-------------|
|
|-------|------|-------------|
|
||||||
| `user` | `User` | The user who sent the message. |
|
| `user` | `User` | The user who sent the message. |
|
||||||
| `client_id` | `int` | Numeric client ID. |
|
| `client_id` | `int` | Numeric client ID. |
|
||||||
| `body` | `str` | Message text (HTML `<p>` tags stripped). |
|
| `body` | `str` | Rendered HTML from Owncast (markdown converted, custom emotes as `<img>` tags, outer `<p>` wrapper stripped). |
|
||||||
| `raw_body` | `str` | Original unprocessed message body. |
|
| `raw_body` | `str` | Original user input before Owncast rendering. |
|
||||||
| `message_id` | `str` | Unique message identifier. |
|
| `message_id` | `str` | Unique message identifier. |
|
||||||
| `is_visible` | `bool` | Whether the message is visible. |
|
| `is_visible` | `bool` | Whether the message is visible. |
|
||||||
| `timestamp` | `datetime \| None` | When the message was sent. |
|
| `timestamp` | `datetime \| None` | When the message was sent. |
|
||||||
|
|||||||
+9
-4
@@ -8,6 +8,8 @@ This is always available. It uses Bearer token authentication (the `access_token
|
|||||||
|
|
||||||
### Sending Messages
|
### Sending Messages
|
||||||
|
|
||||||
|
All message-sending methods HTML-escape the body by default to prevent injection when echoing user-originated content. Markdown syntax is unaffected by escaping and will be rendered normally by Owncast. Pass `unsanitized=True` to send raw HTML intentionally.
|
||||||
|
|
||||||
```python
|
```python
|
||||||
# Regular chat message (visible to everyone):
|
# Regular chat message (visible to everyone):
|
||||||
await ctx.owncast_client.send_message("Hello, chat!")
|
await ctx.owncast_client.send_message("Hello, chat!")
|
||||||
@@ -23,6 +25,9 @@ await ctx.owncast_client.send_system_message_to_client(
|
|||||||
client_id=event.client_id,
|
client_id=event.client_id,
|
||||||
body="Only this client can see this."
|
body="Only this client can see this."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Send raw HTML (opt out of escaping):
|
||||||
|
await ctx.owncast_client.send_message("<b>bold html</b>", unsanitized=True)
|
||||||
```
|
```
|
||||||
|
|
||||||
### Moderation
|
### Moderation
|
||||||
@@ -63,10 +68,10 @@ clients = await ctx.owncast_client.get_connected_clients()
|
|||||||
| Method | Description |
|
| Method | Description |
|
||||||
|--------|-------------|
|
|--------|-------------|
|
||||||
| `base_url` | Property: the Owncast server base URL. |
|
| `base_url` | Property: the Owncast server base URL. |
|
||||||
| `send_message(body)` | Send a chat message visible to all. |
|
| `send_message(body, *, unsanitized=False)` | Send a chat message visible to all. Body is HTML-escaped unless `unsanitized=True`. |
|
||||||
| `send_system_message(body)` | Send a system message visible to all. |
|
| `send_system_message(body, *, unsanitized=False)` | Send a system message visible to all. Body is HTML-escaped unless `unsanitized=True`. |
|
||||||
| `send_action(body)` | Send an action message (like IRC `/me`). |
|
| `send_action(body, *, unsanitized=False)` | Send an action message (like IRC `/me`). Body is HTML-escaped unless `unsanitized=True`. |
|
||||||
| `send_system_message_to_client(client_id, body)` | Send a private system message to one client. |
|
| `send_system_message_to_client(client_id, body, *, unsanitized=False)` | Send a private system message to one client. Body is HTML-escaped unless `unsanitized=True`. |
|
||||||
| `set_message_visibility(message_ids, visible)` | Hide or show messages. |
|
| `set_message_visibility(message_ids, visible)` | Hide or show messages. |
|
||||||
| `set_stream_title(title)` | Update the stream title. |
|
| `set_stream_title(title)` | Update the stream title. |
|
||||||
| `get_status()` | Get public server status dict. |
|
| `get_status()` | Get public server status dict. |
|
||||||
|
|||||||
Reference in New Issue
Block a user