1 Commits

2 changed files with 26 additions and 4 deletions

View File

@@ -11,7 +11,7 @@ from typing import List
from mautrix.types import TextMessageEventContent, MessageType
from .database import SubscriptionRepository
from .utils import SECONDS_BETWEEN_NOTIFICATIONS, sanitize_for_markdown
from .utils import SECONDS_BETWEEN_NOTIFICATIONS, sanitize_for_plain_text
class NotificationService:
@@ -130,7 +130,7 @@ class NotificationService:
"""
# Use name if available, fallback to domain
stream_name = name if name else domain
safe_stream_name = sanitize_for_markdown(stream_name)
safe_stream_name = sanitize_for_plain_text(stream_name)
# Choose message based on notification type
if title_change:
@@ -140,7 +140,7 @@ class NotificationService:
# Add title if present
if title != "":
safe_title = sanitize_for_markdown(title)
safe_title = sanitize_for_plain_text(title)
body_text += "\nStream Title: " + safe_title
# Add stream URL
@@ -150,7 +150,7 @@ class NotificationService:
if tags and len(tags) > 0:
safe_tags = []
for tag in tags:
safe_tag = sanitize_for_markdown(tag)
safe_tag = sanitize_for_plain_text(tag)
if safe_tag and not safe_tag.startswith('.'):
safe_tags.append(safe_tag)

View File

@@ -157,6 +157,28 @@ def escape_markdown(text: str) -> str:
return escaped_text
def sanitize_for_plain_text(text: str) -> str:
"""
Sanitize text for plain text rendering.
Removes newlines and normalizes whitespace without escaping special characters.
Use this for plain text notifications where escaping would show literal backslashes.
:param text: The text to sanitize
:return: Sanitized text
"""
if not text:
return text
# Remove newlines and carriage returns to prevent multi-line injection
sanitized = text.replace('\n', ' ').replace('\r', ' ')
# Collapse multiple spaces into single space
sanitized = ' '.join(sanitized.split())
return sanitized
def sanitize_for_markdown(text: str) -> str:
"""
Sanitize text for safe Markdown rendering.