fix: ignore Telegram messages for other bots

This commit is contained in:
William Chen 2026-05-14 11:09:38 -07:00 committed by Teknium
parent e90869e887
commit fbfe294882
2 changed files with 46 additions and 7 deletions

View file

@ -4286,20 +4286,38 @@ class TelegramAdapter(BasePlatformAdapter):
for source_text, entities in _iter_sources():
for entity in entities:
entity_type = str(getattr(entity, "type", "")).split(".")[-1].lower()
if entity_type != "mention":
if entity_type not in {"mention", "bot_command"}:
continue
offset = int(getattr(entity, "offset", -1))
length = int(getattr(entity, "length", 0))
if offset < 0 or length <= 0:
continue
handle = source_text[offset:offset + length].strip().lstrip("@").lower()
if re.fullmatch(r"[a-z0-9_]{2,29}bot", handle, re.IGNORECASE):
mentioned_bot_usernames.add(handle)
for raw_text in (getattr(message, "text", None), getattr(message, "caption", None)):
if not raw_text:
entity_text = source_text[offset:offset + length].strip()
if entity_type == "mention":
handle = entity_text.lstrip("@").lower()
if re.fullmatch(r"[a-z0-9_]{2,29}bot", handle, re.IGNORECASE):
mentioned_bot_usernames.add(handle)
continue
# Telegram emits /cmd@botname as one bot_command entity, not as
# a separate mention entity. Treat that suffix as an explicit
# bot address for exclusive multi-bot routing even when the
# group has require_mention/free-response disabled.
at_index = entity_text.find("@")
if at_index < 0:
continue
command_target = entity_text[at_index + 1:].strip().lower()
if re.fullmatch(r"[a-z0-9_]{2,29}bot", command_target, re.IGNORECASE):
mentioned_bot_usernames.add(command_target)
# Entity-less fallback for older/client-specific updates. If Telegram
# supplied entities for a source, trust them and do not regex-rescue
# malformed/URL/code spans that the server did not mark as mentions.
for raw_text, entities in _iter_sources():
if not raw_text or entities:
continue
for match in re.finditer(r"(?i)(?<![A-Za-z0-9_])@([A-Za-z0-9_]{2,29}bot)\b", raw_text):
for match in re.finditer(r"(?i)(?<![A-Za-z0-9_`/])@([A-Za-z0-9_]{2,29}bot)\b", raw_text):
mentioned_bot_usernames.add(match.group(1).lower())
return mentioned_bot_usernames

View file

@ -200,6 +200,27 @@ def test_entityless_multi_bot_mentions_still_route_exclusively():
assert ops_bot._should_process_message(_group_message(text)) is True
def test_intern_bots_ignore_messages_addressed_to_other_intern_bot():
text = "@Interntestnumber1bot you're not supposed to do the blog"
test2_bot = _make_adapter(require_mention=False, bot_username="Interntestnumber2bot")
test1_bot = _make_adapter(require_mention=False, bot_username="Interntestnumber1bot")
assert test2_bot._should_process_message(_group_message(text, reply_to_bot=True)) is False
assert test1_bot._should_process_message(_group_message(text)) is True
def test_bot_command_addressed_to_other_bot_is_exclusive_even_when_mentions_not_required():
text = "/stop@Interntestnumber1bot"
entity = _bot_command_entity(text, text)
test2_bot = _make_adapter(require_mention=False, bot_username="Interntestnumber2bot")
test1_bot = _make_adapter(require_mention=False, bot_username="Interntestnumber1bot")
assert test2_bot._should_process_message(_group_message(text, entities=[entity]), is_command=True) is False
assert test1_bot._should_process_message(_group_message(text, entities=[entity]), is_command=True) is True
def test_raw_bot_mention_fallback_does_not_match_email_or_substring():
adapter = _make_adapter(require_mention=True, bot_username="hermes_bot")