feat(send_message): auto-detect @username mentions and create Telegram entities

When sending messages containing @username patterns, auto-generate
MessageEntity(type='mention') entries so that the receiving bot's
require_mention filter can trigger. This enables proper bot-to-bot
interop where mention-based routing is used.
This commit is contained in:
fonhal 2026-05-18 16:18:31 +08:00 committed by Teknium
parent 434d508d0a
commit cf814c96f6

View file

@ -795,7 +795,7 @@ async def _send_telegram(token, chat_id, message, media_files=None, thread_id=No
instead, bypassing MarkdownV2 conversion.
"""
try:
from telegram import Bot
from telegram import Bot, MessageEntity
from telegram.constants import ParseMode
# Auto-detect HTML tags — if present, skip MarkdownV2 and send as HTML.
@ -816,6 +816,14 @@ async def _send_telegram(token, chat_id, message, media_files=None, thread_id=No
formatted = message
send_parse_mode = ParseMode.MARKDOWN_V2
# Detect @username patterns and create mention entities so
# require_mention on the receiving bot's Gateway can trigger.
_MENTION_RE = re.compile(r'@([a-zA-Z][a-zA-Z0-9_]{4,31})')
_entities = [
MessageEntity(type="mention", offset=m.start(), length=len(m.group()))
for m in _MENTION_RE.finditer(formatted)
]
# Honour a configured proxy (telegram.proxy_url in config.yaml, exported
# as TELEGRAM_PROXY env var by load_gateway_config). Without this, the
# standalone send path bypasses the proxy and times out in regions
@ -876,7 +884,7 @@ async def _send_telegram(token, chat_id, message, media_files=None, thread_id=No
last_msg = await _send_telegram_message_with_retry(
bot,
chat_id=int_chat_id, text=formatted,
parse_mode=send_parse_mode, **thread_kwargs
parse_mode=send_parse_mode, entities=_entities, **thread_kwargs
)
except Exception as md_error:
# Parse failed, fall back to plain text
@ -897,7 +905,7 @@ async def _send_telegram(token, chat_id, message, media_files=None, thread_id=No
last_msg = await _send_telegram_message_with_retry(
bot,
chat_id=int_chat_id, text=plain,
parse_mode=None, **thread_kwargs
parse_mode=None, entities=_entities, **thread_kwargs
)
else:
raise