From 51e98ae3d3345e32cebb3bf2f080c4b1ca7bfc4b Mon Sep 17 00:00:00 2001 From: Claude Agent Date: Thu, 16 Apr 2026 23:01:28 +0000 Subject: [PATCH] fix(notify): switch Telegram parse_mode from Markdown to HTML MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Underscores in alert text (dark_green, FIRE_BUY) broke Telegram's legacy Markdown parser, causing ok:false → retries exhausted → failed. HTML parse_mode is more robust and doesn't treat _ as italic. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/atm/notifier/telegram.py | 7 ++++--- tests/test_notifier.py | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/atm/notifier/telegram.py b/src/atm/notifier/telegram.py index b54f704..ad5db2f 100644 --- a/src/atm/notifier/telegram.py +++ b/src/atm/notifier/telegram.py @@ -1,5 +1,6 @@ from __future__ import annotations +import html as _html from pathlib import Path from typing import Any @@ -22,7 +23,7 @@ class TelegramNotifier: return _BASE.format(token=self._token, method=method) def send(self, alert: Alert) -> None: - text = f"*{alert.title}*\n{alert.body}" + text = f"{_html.escape(alert.title)}\n{_html.escape(alert.body)}" if alert.image_path and Path(alert.image_path).exists(): with open(alert.image_path, "rb") as fh: @@ -31,7 +32,7 @@ class TelegramNotifier: data={ "chat_id": self._chat_id, "caption": text, - "parse_mode": "Markdown", + "parse_mode": "HTML", }, files={"photo": fh}, timeout=10, @@ -42,7 +43,7 @@ class TelegramNotifier: json={ "chat_id": self._chat_id, "text": text, - "parse_mode": "Markdown", + "parse_mode": "HTML", }, timeout=10, ) diff --git a/tests/test_notifier.py b/tests/test_notifier.py index 3c1575e..1d24518 100644 --- a/tests/test_notifier.py +++ b/tests/test_notifier.py @@ -228,7 +228,7 @@ def test_telegram_send_ok() -> None: n = TelegramNotifier("token", "chat123", session=session) n.send(_alert("Hi")) assert len(session.calls) == 1 - assert "*Hi*" in session.calls[0]["json"]["text"] + assert "Hi" in session.calls[0]["json"]["text"] def test_telegram_429_raises() -> None: