Python: fix(telegram): ignore commands addressed to other bots - #8803
Eduard van Valkenburg (eavanvalkenburg) merged 4 commits into
Conversation
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
The Foundry username cache permits duplicate getMe requests during concurrent initialization.
Review effort: Balanced
Findings: 1
What changed in this PR
Adds target-aware Telegram command parsing so samples ignore commands addressed to other bots.
Changes:
- Adds optional case-insensitive bot username validation.
- Integrates username lookup and caching across three samples.
- Adds focused tests and documentation.
| File | Description |
|---|---|
python/packages/hosting-telegram/agent_framework_hosting_telegram/_parsing.py |
Adds target-aware parsing. |
python/packages/hosting-telegram/tests/hosting_telegram/test_parsing.py |
Tests target matching. |
python/packages/hosting-telegram/README.md |
Documents the new parameter. |
python/samples/04-hosting/af-hosting/local_telegram/app.py |
Filters webhook commands. |
python/samples/04-hosting/af-hosting/local_telegram/polling_app.py |
Filters polling commands. |
python/samples/04-hosting/af-hosting/local_telegram/tests/test_command_target.py |
Tests local sample routing. |
python/samples/04-hosting/af-hosting/local_telegram/README.md |
Documents routing behavior. |
python/samples/04-hosting/foundry-hosted-agents/invocations/telegram/main.py |
Adds identity lookup and filtering. |
python/samples/04-hosting/foundry-hosted-agents/invocations/telegram/tests/test_main.py |
Tests Foundry routing and caching. |
python/samples/04-hosting/foundry-hosted-agents/invocations/telegram/README.md |
Documents command isolation. |
💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.
|
@microsoft-github-policy-service agree |
|
Lucien (@dakjdakd) I don’t think we need dedicated test coverage in the sample directories for this change. Please keep the regression coverage in |
|
Thanks for the guidance. Addressed in Verification after the cleanup: package parser tests 48/48, remaining Foundry sample tests 31/31, Ruff check and format check passed. I also updated the PR description to reflect the smaller test scope. |

Motivation & Context
The Python Telegram command parser strips
@botnamewithout checking which bot received the update. If a bot receives/new@otherbotin a group, all three official Telegram samples can treat it as their own/new: the two local samples delete their shared group session, and the Foundry-hosted sample clears its Cosmos history. Unknown commands addressed to another bot can fall through to the agent. This PR makes the samples check the target before either dispatch or model invocation.Description & Review Guide
telegram_command(update, *, bot_username=None)now checks an optional username case-insensitively. Command extraction also recognizes top-levelmessage.captionandedited_message.captionafter message text and callback data, so commands in photo or document captions pass through the same target check. The local polling and webhook samples obtain their username through aiogram's cachedBot.me()call. The Foundry-hosted sample obtains it through TelegramgetMeand caches it on its runtime; a per-runtime async lock ensures concurrent first lookups share one request. Each handler returns immediately for a command addressed to another bot. Regression tests remain in the Telegram package's parser tests, with package and sample README updates accompanying the change./new@otherbotin message text or a media caption is ignored before a session or history operation and before the agent sees the content./newand/new@mybotretain their existing behavior. The new argument is optional: callers usingtelegram_command(update)continue to get the old target-agnostic normalization for suffixed commands. That residual behavior is deliberate for compatibility; changing the default would require a separate API decision.getMelookup in the Foundry runtime.mybot/new@otherbot/new; the local handlers reachstate.session_store.delete(session_id)or the Foundry handler reachesruntime.history.clear(session_id)by the source call paths./new@otherbotNone, so the samples can pass the caption and media to the agent./new@MyBot/newEvidence and verification. The old parser output was reproduced against
c804f32c9. Before implementing the new parameter, its target-aware test failed withTypeError: telegram_command() got an unexpected keyword argument 'bot_username'(1 failed). The reset side effects in the first table row are derived from the parser-to-handler source paths, which are also present on the current PR base2024d4df4; the pre-fix sample handlers were not run in a live group. The retained parser tests cover commands addressed to another bot, commands addressed to this bot, untargeted commands, media captions, and callback precedence. The sample handlers pass the bot username to that parser and return when it rejects a command.During the
ae20399c0review follow-up, a concurrent cold-cache test observed twogetMecalls before the lock (1 failure) and one afterward. That sample-only test was later removed in4318d8eat maintainer request; the runtime lock remains in place.The media-caption follow-up in
5a4e589ebcovers the path identified during review. Before the parser change, the retained caption tests failed for bothmessageandedited_message. After the change, the parser suite passes (48/48), including a test confirming callback data retains precedence over a top-level caption. In4318d8e, I removed the local sample test file and the command-target additions to the Foundry sample tests as requested by the maintainer. The remaining Foundry sample suite passes (31/31). No live Telegram group test was run.From
python/, I ran these tests with the checkout'spackages/hosting-telegram,packages/core, andpackages/hostingdirectories onPYTHONPATHfor the sample suites, andOTEL_SDK_DISABLED=true:Ruff lint and format checks, Pyright checks for the Telegram package and Foundry sample, and
git diff --checkpassed. No live Telegram group test was run.I searched open and closed issues and PRs for
telegram,telegram_command,otherbot, andbot-suffixedon 2026-09-28 and found no existing target-matching fix. #6588/#7047 introduced the helper and local samples; #7883 added the Foundry-hosted sample. None covers this command-routing defect.Related Issue
Fixes #8802
Contribution Checklist
breaking changelabel (or add "[BREAKING]" to the title prefix, before or after any language prefix) — a workflow keeps the label and title prefix in sync automatically.