fix(telegram): handle caption messages in group chat mention detection (#5761)

* fix(telegram): handle caption messages in group chat @mention detection

Telegram media messages (photos, videos, etc.) store their text in
`message.caption` and mention entities in `message.caption_entities`,
not `message.text` / `message.entities`. The previous code only checked
`message.text`, so commands and @mentions sent with media were silently
skipped with "No text..." in the debug log.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(telegram): use correct entity field pairing and UTF-16 offsets for mention detection

- Explicitly pair message.entities with text messages and caption_entities
  with media messages, avoiding false fallthrough on empty entity lists
- Decode mention text via UTF-16-LE encoding to respect Telegram's UTF-16
  based offset/length values, fixing incorrect slicing when emojis are present

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
DDSRem
2026-05-12 20:57:31 +08:00
committed by GitHub
co-authored by Claude Sonnet 4.6
parent 116465b6d8
commit b172a6d08f
+21 -17
View File
@@ -276,9 +276,12 @@ class Telegram:
logger.debug(f"处理私聊消息:用户 {message.from_user.id}") logger.debug(f"处理私聊消息:用户 {message.from_user.id}")
return True return True
# 消息内容:文本消息用 text,媒体消息的说明文字用 caption
message_text = message.text or message.caption or ""
# 群聊中的命令消息总是处理(以/开头) # 群聊中的命令消息总是处理(以/开头)
if message.text and message.text.startswith("/"): if message_text.startswith("/"):
logger.debug(f"处理群聊命令消息:{message.text[:20]}...") logger.debug(f"处理群聊命令消息:{message_text[:20]}...")
return True return True
# 群聊中检查是否@了机器人 # 群聊中检查是否@了机器人
@@ -288,27 +291,28 @@ class Telegram:
logger.debug("未获取到bot用户名,处理所有群聊消息") logger.debug("未获取到bot用户名,处理所有群聊消息")
return True return True
# 检查消息文本中是否包含@bot_username # 检查消息文本或说明文字中是否包含@bot_username
if message.text and f"@{self._bot_username}" in message.text: if f"@{self._bot_username}" in message_text:
logger.debug(f"检测到@{self._bot_username},处理群聊消息") logger.debug(f"检测到@{self._bot_username},处理群聊消息")
return True return True
# 检查消息实体中是否有提及bot # 检查消息实体(文本消息用 entities,媒体消息用 caption_entities
if message.entities: entities = (message.entities if message.text is not None else message.caption_entities) or []
for entity in message.entities: for entity in entities:
if entity.type == "mention": if entity.type == "mention":
mention_text = message.text[ # Telegram offset/length 基于 UTF-16 代码单元,需用字节编码处理含 emoji 的消息
entity.offset: entity.offset + entity.length mention_text = message_text.encode('utf-16-le')[
] entity.offset * 2: (entity.offset + entity.length) * 2
if mention_text == f"@{self._bot_username}": ].decode('utf-16-le')
logger.debug( if mention_text == f"@{self._bot_username}":
f"通过实体检测到@{self._bot_username},处理群聊消息" logger.debug(
) f"通过实体检测到@{self._bot_username},处理群聊消息"
return True )
return True
# 群聊中没有@机器人,不处理 # 群聊中没有@机器人,不处理
logger.debug( logger.debug(
f"群聊消息未@机器人,跳过处理:{message.text[:30] if message.text else 'No text'}..." f"群聊消息未@机器人,跳过处理:{message_text[:30] if message_text else 'No text'}..."
) )
return False return False