Used Maubot and Mautrix helpers for bot messages.
This commit is contained in:
@@ -127,7 +127,10 @@ class OwncastSentry(Plugin):
|
||||
except Exception:
|
||||
self.metrics_service.record_error(ErrorSource.COMMAND)
|
||||
self.log.exception("Unhandled exception in subscribe command.")
|
||||
await evt.reply("An unexpected error occurred. Please try again later.")
|
||||
await evt.reply(
|
||||
"An unexpected error occurred. Please try again later.",
|
||||
markdown=False,
|
||||
)
|
||||
|
||||
@command.new(help="Unsubscribes from an Owncast stream.")
|
||||
@command.argument("url")
|
||||
@@ -138,7 +141,10 @@ class OwncastSentry(Plugin):
|
||||
except Exception:
|
||||
self.metrics_service.record_error(ErrorSource.COMMAND)
|
||||
self.log.exception("Unhandled exception in unsubscribe command.")
|
||||
await evt.reply("An unexpected error occurred. Please try again later.")
|
||||
await evt.reply(
|
||||
"An unexpected error occurred. Please try again later.",
|
||||
markdown=False,
|
||||
)
|
||||
|
||||
@command.new(help="Lists all stream subscriptions in this room.")
|
||||
async def subscriptions(self, evt: MessageEvent) -> None:
|
||||
@@ -148,7 +154,10 @@ class OwncastSentry(Plugin):
|
||||
except Exception:
|
||||
self.metrics_service.record_error(ErrorSource.COMMAND)
|
||||
self.log.exception("Unhandled exception in subscriptions command.")
|
||||
await evt.reply("An unexpected error occurred. Please try again later.")
|
||||
await evt.reply(
|
||||
"An unexpected error occurred. Please try again later.",
|
||||
markdown=False,
|
||||
)
|
||||
|
||||
@command.new(help="Lists currently live streams in this room.")
|
||||
async def live(self, evt: MessageEvent) -> None:
|
||||
@@ -158,7 +167,10 @@ class OwncastSentry(Plugin):
|
||||
except Exception:
|
||||
self.metrics_service.record_error(ErrorSource.COMMAND)
|
||||
self.log.exception("Unhandled exception in live command.")
|
||||
await evt.reply("An unexpected error occurred. Please try again later.")
|
||||
await evt.reply(
|
||||
"An unexpected error occurred. Please try again later.",
|
||||
markdown=False,
|
||||
)
|
||||
|
||||
async def _run_stream_updates_every_minute(self) -> None:
|
||||
"""Run stream state updates at the top of each wall-clock minute."""
|
||||
|
||||
@@ -111,18 +111,21 @@ class CommandHandler:
|
||||
"The URL you supplied does not appear to "
|
||||
"be a valid Owncast instance. You may have "
|
||||
"specified an invalid domain, or the "
|
||||
"instance is offline."
|
||||
"instance is offline.",
|
||||
markdown=False,
|
||||
)
|
||||
return
|
||||
except AlreadySubscribedError as e:
|
||||
await evt.reply(
|
||||
f"This room is already subscribed to notifications for {e.domain}."
|
||||
f"This room is already subscribed to notifications for {e.domain}.",
|
||||
markdown=False,
|
||||
)
|
||||
return
|
||||
|
||||
await evt.reply(
|
||||
f"Subscription added! This room will receive "
|
||||
f"notifications when {stream_domain} goes live."
|
||||
f"notifications when {stream_domain} goes live.",
|
||||
markdown=False,
|
||||
)
|
||||
|
||||
async def unsubscribe(self, evt: MessageEvent, url: str) -> None:
|
||||
@@ -137,13 +140,15 @@ class CommandHandler:
|
||||
)
|
||||
except NotSubscribedError as e:
|
||||
await evt.reply(
|
||||
f"This room is already not subscribed to notifications for {e.domain}."
|
||||
f"This room is already not subscribed to notifications for {e.domain}.",
|
||||
markdown=False,
|
||||
)
|
||||
return
|
||||
|
||||
await evt.reply(
|
||||
f"Subscription removed! This room will no "
|
||||
f"longer receive notifications for {stream_domain}."
|
||||
f"longer receive notifications for {stream_domain}.",
|
||||
markdown=False,
|
||||
)
|
||||
|
||||
async def subscriptions(self, evt: MessageEvent) -> None:
|
||||
|
||||
@@ -18,8 +18,6 @@ import asyncio
|
||||
import time
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from mautrix.types import MessageType, TextMessageEventContent
|
||||
|
||||
from .metrics import NotificationType
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@@ -209,8 +207,7 @@ class NotificationService:
|
||||
Propagates send errors so broadcast delivery accounting can count failures.
|
||||
"""
|
||||
try:
|
||||
content = TextMessageEventContent(msgtype=MessageType.TEXT, body=body_text)
|
||||
await self.client.send_message(room_id, content)
|
||||
await self.client.send_notice(room_id, body_text)
|
||||
except Exception as exception:
|
||||
self.log.warning(
|
||||
"[%s] Failed to send notification message to room [%s]: %s",
|
||||
|
||||
+26
-15
@@ -15,9 +15,12 @@
|
||||
"""Shared test fixtures and stubs for OwncastSentry tests."""
|
||||
|
||||
from dataclasses import dataclass, field
|
||||
from typing import TYPE_CHECKING, Any
|
||||
from typing import TYPE_CHECKING, Any, override
|
||||
|
||||
import pytest
|
||||
from maubot.matrix import MaubotMatrixClient
|
||||
from maubot.testing.bot import MatrixEvent
|
||||
from mautrix.types import EventContent, EventID, EventType, RoomID
|
||||
from mautrix.util.async_db import Database
|
||||
from prometheus_client import generate_latest
|
||||
|
||||
@@ -185,27 +188,35 @@ VALID_STATUS_RESPONSE: dict[str, object] = {
|
||||
}
|
||||
|
||||
|
||||
@dataclass
|
||||
class _SentMessage:
|
||||
"""A message recorded by _StubMatrixClient."""
|
||||
|
||||
room_id: str
|
||||
content: Any
|
||||
|
||||
|
||||
class _StubMatrixClient:
|
||||
"""Recording stub for the Matrix client used in notification tests."""
|
||||
class _StubMatrixClient(MaubotMatrixClient):
|
||||
"""Recording Matrix client using Mautrix message builders."""
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.sent_messages: list[_SentMessage] = []
|
||||
self.sent_messages: list[MatrixEvent] = []
|
||||
self.should_fail_for_rooms: set[str] = set()
|
||||
|
||||
async def send_message(self, room_id: str, content: Any) -> None:
|
||||
"""Record a sent message, or raise if room is in the fail set."""
|
||||
@override
|
||||
async def send_message_event(
|
||||
self,
|
||||
room_id: RoomID,
|
||||
event_type: EventType,
|
||||
content: EventContent,
|
||||
_disable_encryption: bool = False,
|
||||
**kwargs: Any,
|
||||
) -> EventID:
|
||||
"""Record a sent message event, or raise if room is in the fail set."""
|
||||
if room_id in self.should_fail_for_rooms:
|
||||
msg = f"Stubbed failure for room {room_id}"
|
||||
raise RuntimeError(msg)
|
||||
self.sent_messages.append(_SentMessage(room_id=room_id, content=content))
|
||||
self.sent_messages.append(
|
||||
MatrixEvent(
|
||||
room_id=room_id,
|
||||
event_type=event_type,
|
||||
content=content,
|
||||
kwargs=kwargs,
|
||||
)
|
||||
)
|
||||
return EventID("$stubbed")
|
||||
|
||||
|
||||
@dataclass
|
||||
|
||||
@@ -20,6 +20,7 @@ import time
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import pytest
|
||||
from mautrix.types import MessageType
|
||||
|
||||
from owncastsentry.metrics import MetricsService
|
||||
from owncastsentry.notification_service import (
|
||||
@@ -301,6 +302,7 @@ class TestNotifyStreamLive:
|
||||
"#tag"
|
||||
)
|
||||
for msg in client.sent_messages:
|
||||
assert msg.content.msgtype == MessageType.NOTICE
|
||||
assert msg.content.body == expected_body
|
||||
|
||||
async def test_records_cooldown_after_success(
|
||||
@@ -358,10 +360,10 @@ class TestNotifyStreamLive:
|
||||
"""Count a cancelled delivery result as a failure."""
|
||||
client = _StubMatrixClient()
|
||||
|
||||
async def send_message(_room_id: str, _content: object) -> None:
|
||||
async def send_notice(_room_id: str, _text: str) -> None:
|
||||
raise asyncio.CancelledError
|
||||
|
||||
client.send_message = send_message
|
||||
client.send_notice = send_notice
|
||||
service = _make_service(client=client, subscription_repo=subscription_repo)
|
||||
|
||||
await stream_repo.create("example.com")
|
||||
@@ -406,6 +408,7 @@ class TestNotifyStreamLive:
|
||||
|
||||
assert len(client.sent_messages) == 1
|
||||
assert client.sent_messages[0].room_id == "!good:matrix.org"
|
||||
assert client.sent_messages[0].content.msgtype == MessageType.NOTICE
|
||||
assert client.sent_messages[0].content.body == (
|
||||
"🎥 Stream is now live!\n"
|
||||
"Stream Title: Title\n"
|
||||
@@ -432,6 +435,7 @@ class TestSendCleanupWarning:
|
||||
await service.send_cleanup_warning("example.com")
|
||||
|
||||
assert len(client.sent_messages) == 1
|
||||
assert client.sent_messages[0].content.msgtype == MessageType.NOTICE
|
||||
assert client.sent_messages[0].content.body == (
|
||||
"⚠️ Warning: Subscription Cleanup Scheduled\n"
|
||||
"\n"
|
||||
@@ -461,6 +465,7 @@ class TestSendCleanupDeletion:
|
||||
await service.send_cleanup_deletion("example.com")
|
||||
|
||||
assert len(client.sent_messages) == 1
|
||||
assert client.sent_messages[0].content.msgtype == MessageType.NOTICE
|
||||
assert client.sent_messages[0].content.body == (
|
||||
"🗑️ Subscription Automatically Removed\n"
|
||||
"\n"
|
||||
|
||||
Reference in New Issue
Block a user